I am using Asp.NET WebApi and one thing that confuses me is the binding when a request is done.
I have this ViewModel:
[DataContract(Name="Store")]
public class StoreDm
{
[DataMember(IsRequired = true)]
[MinLength(3)]
public string Name { get; set; }
[DataMember(IsRequired = true)]
public double Latitude { get; set; }
[DataMember(IsRequired = true)]
public double Longitude { get; set; }
}
public HttpResponseMessage GetStoreNames(StoreDm vm)
{
if (ModelState.IsValid)
{
}
}
RestClient c = new RestClient("http://localhost:3333/api/store");
RestRequest r = new RestRequest("/GetStoreNames", Method.GET);
r.AddParameter("Name", autoComplete);
r.AddParameter("Latitude", "4");
r.AddParameter("Longitude", "-7");
var d = c.BuildUri(r);
c.ExecuteAsync(r, response2 =>
{
var content = response2.Content;
});
My StoreDm is Null.
I don't get this on so many levels. First I setup IsRequired on all my properties yet for whatever reason the ModelState thinks "null" ViewModel is valid.
Second I don't get why it is null
. I have to add [FromUri]
to get it to bind. What happens if this would have been a Post
and have the same restClient code but also someone is using fiddler body request.
If I am forced to put [FromUri]
then I don't think the fiddler body request will work.
How could I have it so both requests go through and bind properly?
The Web API paramter binding (extract from here:Routing and Action Selection) does this:
Parameter Bindings. A parameter binding is how Web API creates a value for a parameter. Here is the default rule for parameter binding:
So, any complex type (like the class StoreDm
is) is by default expected to be part of the body
As stated in the standard defintion Hypertext Transfer Protocol 4.3 Message Body
The rules for when a message-body is allowed in a message differ for requests and responses.
The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers. A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests.
So, while Web API provides some common functionality, it tries to be general. There could be requests with or without message-body. So, having this, the action selection and param binding is common, without inferring of the "current" request specific, and maybe obvious settings (we would think, that GET would always have all parameters (properties of StoreDm
object) in the URI... but the engine does not)
The POST would bind the StoreDm
out of the box, because its properties will be found in the body, standard binding for complex objects.
The GET breaks the rules, the properties (of Complex type) are in the URI, so we only have to inform the framework: [FromUri]. In other cases, Method will be found, null (bounded from message-body) will be passed
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