I am creating a callback endpoint for a third party API to hit. The caller will POST multipart form data to it.
Something like this:
public SomeApiController : ApiController {
public AModel Post(AModel input) {
return input; //for demonstration
}
}
Some of the fields it will post have dashes in the name, which cannot be an actual .NET property name. So, I used [DataContract] and [DataMember(name="blah")] to define serialization rules.
Model:
//input model class
[DataContract]
public class AModel {
[DataMember]
public string NormalProperty {get; set;} //value set appropriately
[DataMember(Name="abnormal-property")]
public string AbnormalProperty {get; set;} //always null (not serializing)
}
With standard XML and JSON posts, this works fine. Normal and AbnormalProperty are set and I can carry about my business.
However, with any variant of form data (form-data, multiplart/form-data, x-urlencoded-form-data, AbnormalProperty doesn't properly deserialize into the model, and will always be null.
Is there a directive I'm missing or something?
I have tried your example, and my conclusion is that the DefaultModelBinder
in ASP.NET MVC does not support that naming of POST variables.
An obvious solution is not to use the dash in your names.
If that is not an option, then you can implement your own model binder for that specific model to handle the abnormal names you are sending to your MVC controller. Here is an example of a custom model binder:
public class AModelDataBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(AModel))
{
var request = controllerContext.HttpContext.Request;
string normal = request.Form.Get("normalproperty");
string abnormal = request.Form.Get("abnormal-property");
return new AModel
{
NormalProperty = normal,
AbnormalProperty = abnormal
};
}
return base.BindModel(controllerContext, bindingContext);
}
}
Then you would have to register this custom binder in Global.asax:
ModelBinders.Binders.Add(typeof(AModel), new AModelDataBinder());
And finally you can use the custom binder in your controller:
[HttpPost]
public ActionResult Index([ModelBinder(typeof(AModelDataBinder))]AModel input)
{
// Handle POST
return View();
}
I think the main issue is with DataContract
it expects raw data like XML. What you are trying to POST is HTML.
Types Supported by the Data Contract Serializer
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