Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataMember's Name property is ignored with [FromUri] property in WebApi service

We are creating RestService with Asp.Net WebApi. But for some reason Name property is ignored in DataMember attribute when trying to deserialize complex property with [FromURI] attribute.

For example we might have: Method:

public IHttpActionResult Get([FromUri]User user)

Model:

[DataContract]
public class User
{
    [DataMember(Name = "username")]
    public string Username{ get; set; }
    [DataMember(Name = "isActive", IsRequired = false)]
    public bool? Active { get; set; }
}

When deserializing user we get username as expected, but null for Active. On the other hand when serializing data we get both isActive and username as expected. If we send request with active in query string it works as expected.

It's obviously problem with IModelBinder. It doesn't use DataMember's Name property for some reason. I checked what formaters are included and 4 default ones are registered:

System.Net.Http.Formatting.JsonMediaTypeFormatter
System.Net.Http.Formatting.XmlMediaTypeFormatter
System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
System.Net.Http.Formatting.JQueryMvcFormUrlEncodedFormatter

I don't have a way to check which one is used on request. I would assume that its FormUrlEncodedMediaTypeFormatter but I can't be sure. Also, I am not sure if it even supports Name property.

I already checked for a solution and closest topic I could find was WebAPI DataMember Name not used when de/serializing via application/x-www-form-urlencoded but it doesn't use [FromUri] but application/x-www-form-urlencoded property and it wasn't really solved.

Any ideas, pointers or suggestions would be much appreciated.

like image 209
Igor Avatar asked Nov 09 '15 15:11

Igor


People also ask

What is the use of the FromUri attribute in Web API?

The [FromUri] attribute is prefixed to the parameter to specify that the value should be read from the URI of the request, and the [FromBody] attribute is used to specify that the value should be read from the body of the request.

Why are the FromBody and FromUri attributes needed in asp net web API?

When the ASP.NET Web API calls a method on a controller, it must set values for the parameters, a process called parameter binding. In order to bind a model (an action parameter), that would normally default to a formatter, from the URI we need to decorate it with [FromUri] attribute.


1 Answers

Use [FromQuery] instead other attributes.

And model for your request http://localhost:8080/api/users?username=John&isActive=true

[Route("api/users")]
public class UsersController : Controller
{
    [HttpGet]
    public IHttpActionResult Get(User user)
    {
        //...
    }
}

Will looks like

public class User
{
    [FromQuery(Name = "username")]
    public string Username{ get; set; }
    [FromQuery(Name = "isActive")]
    public bool? Active { get; set; }
}

Anyway best practice is to keep names in model as it parameters names in query. In this case you dont have to provide "Name" parameter, only keep [FromQuery] on queryClass, and lower casing .Net provide automaticly.

like image 129
Leonid Pavlov Avatar answered Sep 30 '22 16:09

Leonid Pavlov