Open PromontoryProtean opened 8 years ago
Ah, you've been relying on the old way of passing arguments ala RC1 ViewComponents. In RC1, ViewComponents would accepts a params object[]
array as the input, and it would use these objects and map them (in the order they are provided to the parameters of the associated MethodInfo
of the target ViewComponent method).:
@await Component.InvokeAsync("ContactForm", settingsDictionary) => public async Task<IViewComponentResult InvokeAsync(ContactFormSettingsDictionary settingsDictionary) { }
To handle model binding, we couldn't accept arguments this way, because we need to be able to map the parameters by name. Instead, in RC2 ViewComponents and this Widget framework, we accept arguments using the following syntax:
@await Widget.InvokeAsync("ContactForm", new { settingsDictionary = settingsDictionary })
// or @await Widget.InvokeAsync("ContactForm", new { settingsDictionary }) with inferred name
This means you can provide arguments to named widget parameters, and the rest will be filled in by the model binder. Currently, because you are passing that dictionary straight in, it is not being mapped at all, meaning the model binder will fill in the rest. If the model binder couldn't get a value from the value providers - it'll give you null
.
Ok, I think I follow. The confusing part is that the method is publicly available and appears to be usable, so there was no way to tell from the method signature that it was going to try to model bind directly to the params object[]
. But it looks like this will be much clearer and more flexible in RC2.
I'll take a look at the RC2 branch. There is a lot of churn going on right now in the Microsoft repositories so I don't envy you trying to build against all the renaming that is going on. I'm definitely looking forward to RC2 though, some great changes happening. I'll keep an eye on this repository and get you some more feedback as the dust settles.
I am attempting to pass a few properties to a widget from a view. In my example I am passing a settings dictionary to a contact form. I am calling the following overload from my view:
@await Widget.InvokeAsync("ContactForm", settingsDictionary)
I believe that is equivalent to the following overload in DefaultWidgetHelper:
public async Task<HtmlString> InvokeAsync(Type widgetType, object values = null)
In the contact form widget, I have the following:
Problem is that the
settingsDictionary
parameter is always delivered toInvokeGet
as null, so I am unable to initialize theContactFormViewModel
. Also, I think the model binder is touching thesettingsDictionary
because I have some getters inContactFormViewModel
that I had to comment out due to some exceptions that got tossed up. I tried to go through the source and figure out where the problem lies, but I got a little lost. Anyway, I have done something very similar using view components, so I figured I'd check to see if this is intended to be a supported scenario before I dig any deeper.