dannyyy dannyyy - 5 months ago 90
C# Question

RestSharp / ASP.NET WebAPI - Using POST with url parameters

I've the following ASP.NET WebAPI binding:

name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new {id = RouteParameter.Optional}

And my Controller looks like this:

public class ReferenceDataController : BaseController
[RequireUserToken(ApprovedDeviceToken = true, ValidUserToken = true)]
public IEnumerable<SynchronizeItem<IReferenceDataItem>> Sync([FromBody]IEnumerable<SynchronizeItem<IReferenceDataItem>> clientSyncItems, [FromUri]int referenceDataType)
// my code

On the client site I use the following code to send a request:

var client = new RestClient (baseUrl);
var request = new RestRequest (resource, method);
request.XmlSerializer = new JsonSerializer ();
request.RequestFormat = DataFormat.Json;
request.AddHeader ("X-Abc-DeviceToken", deviceToken);

if (!string.IsNullOrWhiteSpace (userToken))
request.AddHeader ("X-Abc-UserToken", userToken);

if (payload != null)
request.AddBody (payload);

if (parameters != null)
foreach (var parameter in parameters)
request.AddUrlSegment(parameter.Key, parameter.Value);

var response = client.Execute<T> (request);

My expectation is, sending a POST request to
with a body which contains an IEnumerable. If I remove the UrlSegment parameters on client site and the second argument on the webservice site, than it works.

How can I combine a body with payload and additional URL parameters?


You can define your action method as follow,

[RequireUserToken(ApprovedDeviceToken = true, ValidUserToken = true)]
public IEnumerable<SynchronizeItem<IReferenceDataItem>> Sync(IEnumerable<SynchronizeItem<IReferenceDataItem>> clientSyncItems, int referenceDataType)
    // my code

No BodyAttribute or FromUriAttribute. In that way, Web API will try to use a MediaTypeFormatter to deserialize the body into the clientSyncItems collection and any additional value type from the query string (referenceDataType from the query string). The route as you defined it will take "sync" as Id (which would be ignored as it is not a parameter in your action).

You must also specify a content-type header so Web API can choose the right formatter (json or xml for example).