I wrote an override of the Model Binder.
public override object BindModel(Controller context, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
object returnVal = null;
if (value == null)
returnVal = base.BindModel(controllerContext, bindingContext);
else
{
/* custom logic here that never seems to get called.
returnVal = something();
*/
}
return returnVal;
}
I also have a javascript service (in Angular) that makes an AJAX request to one of my controllers.
The AJAX request attempts to post a collection of ints. I tried stepping through the model binder, and it seems like value
is always null. And by some magic, the base.BindModel()
is still able to bind my collection to the correct C# object.
The problem with this is that I can't use my custom binder as the else
block is never invoked. Is there another way I can get the value besides using the ValueProvider
?
I also believe that before this custom binder was working correctly (from memory which could be wrong). I recently updated from 4.5 to 5.2.something. Is there anything that was updated that could've changed this behavior?
I also have a javascript service (in Angular) that makes an AJAX request to one of my controllers.
...
The problem with this is that I can't use my custom binder as the else block is never invoked.
Its null because it can't find the data based on your model name that it is trying to bind to. Whether the value can be found by this name depends on the model name and the data sent in the client request which have to align/match. But before anyone can tell you why its not matching data (including your model with the array) can be sent from the client in one of three ways:
?myArray=1&myArray=2&myArray=3
. This means that in your model binder you will have to consider this.data
(body) in a POST then it might be an actual array object. Example in json: {"myArray":[1,2,3,4]}
So to better answer your question you will need to provide
So to recap: bindingContext.ModelName
is the expected name and must match the data that your model binder is trying to find. If you are sending {"myArray":[1,2,3,4]}
but your model property is named ProductIds
then it will always be null.
I recently updated from 4.5 to 5.2.something
No, not that I am aware of.
Final thought. You could also let the default model binder execute and then do something with the returned value if the types match. If the binding happens now without a problem but you want to do some post-processing this would be a better choice. Example:
public override object BindModel(Controller context, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
object returnVal = base.BindModel(controllerContext, bindingContext);
/* check returnVal and then additional custom logic here */.
return returnVal;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With