I'm bound by agreements between my party and the client to use json parameters containing dashes. Since it's not possible to use that in property names in C#, I need to map to the desired property.
What I do now:
The below code is simplified for convenience.
Model
public class MyRequest
{
[JsonProperty("request-number")]
public string RequestNumber { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
Controller
[HttpGet]
[Route("api/load-stuff")]
public Stuff LoadStuff([FromUri]MyRequest request)
{
return BackEnd.LoadStuff(request);
}
Call to the API from client
The above controller is targeted using this uri:
http://localhost:12345/api/load-stuff?request-number=X123&name=requestName
My question
If I put a breakpoint at the BackEnd.LoadStuff
line I can see the call arrives, but the request isn't mapped correctly.
Name contains what I expect: requestName
, but RequestNumber is null
, so the mapping didn't work.
What's going wrong?
ASP.NET's default model binder doesn't take the JsonPropertyAttribute
into account when attempting to bind request parameters to a model (it can't, since it doesn't know about JsonPropertyAttribute
and the rest of NewtonSoft.Json). Given your scenario (property names that aren't legal identifiers in C#), the only way to achieve what you want is via a custom model binder that does read JsonPropertyAttribute
.
If you did have property names that were legal identifiers (for example request_number
) then you could create a request model with those named properties, then map it to a separate model with the correctly-named properties, e.g.:
public class MyController : ApiController
{
[HttpGet]
[Route("api/load-stuff")]
public Stuff LoadStuff([FromUri]MyRequest request)
{
return BackEnd.LoadStuff(request.ToMyPrettyRequest());
}
}
public class MyRequest
{
public string request_number { get; set; }
public string name { get; set; }
MyPrettyRequest ToMyPrettyRequest()
{
return new MyPrettyRequest
{
RequestNumber = request_number,
Name = name,
};
}
}
public class MyPrettyRequest
{
public string RequestNumber { get; set; }
public string Name { get; set; }
}