8

Can I have a webapi method

[Route("someroute")]
public void SomeMethod(string variable1, int variable2, Guid variable3)
{
     //... Code here
}

simple json

var jsonvariable = new {
    variable1:"somestring",
    variable2:3,
    variable3: {9E57402D-8EF8-45DE-B981-B8EC201D3D8E}
}

Then make the post

HttpClient client = new HttpClient { BaseAddress = new Uri(ConfigurationManager.AppSettings["SomeURL"]) };
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.PostAsJsonAsync("someroute", jsonvariable ).Result

Coming from javascript I can do something like this and it resolves the individual properties but I can't seem to do it with a C# call

var postData = {
     appUniqueId: appUniqueId
};

$http
   .post('someurl', postData)
   .success(function(response) {
      defer.resolve(response.data);
   });

webapi method
SomeWebMethod(Guid appUniqueId) <-- same name as in postdata
DRobertE
  • 3,478
  • 3
  • 26
  • 43
  • For one thing, if your jsonvariable code is supposed to be C# then your syntax is wrong. Show us the exact code that you're trying to use and the results that you're getting. – Michael Richardson Jun 14 '14 at 02:10
  • Sorry. I forgot the "new" keyword on the – DRobertE Jun 14 '14 at 02:15
  • I'm theory, this should be possible. What's likely causing it to fail for you is some missing header or malformed request. I would recommend firing up Fiddler, making the request both ways, and comparing the raw requests. That should help get you started. – Anthony Compton Jun 14 '14 at 02:20
  • Here is a much more in depth question related to this question. I was trying to post an abbreviated version to try to get answers. It seems without using a "model" for model binding this may be a framework limitation http://stackoverflow.com/questions/24212152/postasjsonasync-not-calling-webapi-service-from-windows-service-using-anonymous – DRobertE Jun 14 '14 at 02:25
  • Your answer is in the previous question. You should read the article Stephan links in his answer. http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api particularly this line: "At most one parameter is allowed to read from the message body ... The reason for this rule is that the request body might be stored in a non-buffered stream that can only be read once." – solidau Feb 06 '15 at 23:22

1 Answers1

5

You can't quite go about it like you are doing there.

As mentioned in the comments and in this article, you may only use one FromBody parameter for your method. Thus, one or none of those parameters are going to be bound from your JSON body. If any of them, it may be the guid that it tries to bind simply because of the web api parameter binding rules involved.

How do you get around this? Make a class that is how your data is described.

public class SomeBodyParameters
{
     public string variable1 { get; set; } 
     public int variable2 { get; set; } 
     public Guid variable3 { get; set; } 
} 

Then your api method would look like this:

[Route("someroute")]
public void SomeMethod([FromBody]SomeBodyParameters parameters)
{
     //... Code here
}

The stipulation is that it won't automagically bind based on type, but rather the name that you set in your example anonymous type. variable1, variable2, and variable3 must have their names match in both spots.

When you think about it, that anonymous type that looks like JSON really is passing in a sort of object, so really that's what you should be accepting back anyway.

Food for thought: How would you be able to differentiate between a simple "string" and an object that has a singular string like var jsonvariable = new { variable1:"somestring"};? You basically couldn't and the two probably shouldn't be equivilant.

Community
  • 1
  • 1
Zachary Dow
  • 1,897
  • 21
  • 36