Water Cooler v2
Water Cooler v2

Reputation: 33880

A simple POST request to Web API not hitting the API at all

From my MVC application, I am trying to make a POST request to these sample end-points (actions) in an API controller named MembershipController:

[HttpPost]
public string GetFoo([FromBody]string foo)
{
    return string.Concat("This is foo: ", foo);
}

[HttpPost]
public string GetBar([FromBody]int bar)
{
    return string.Concat("This is bar: ", bar.ToString());
}

[HttpPost]
public IUser CreateNew([FromBody]NewUserAccountInfo newUserAccountInfo)
{
    return new User();
}

Here's the client code:

var num = new WebAPIClient().PostAsXmlAsync<int, string>("api/membership/GetBar", 4).Result;

And here's the code for my WebAPIClient class:

public class WebAPIClient
{
    private string _baseUri = null;

    public WebAPIClient()
    {
        // TO DO: Make this configurable
        _baseUri = "http://localhost:54488/";
    }

    public async Task<R> PostAsXmlAsync<T, R>(string uri, T value)
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri(_baseUri);

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

            var requestUri = new Uri(client.BaseAddress, uri);

            var response = await client.PostAsXmlAsync<T>(requestUri, value);

            response.EnsureSuccessStatusCode();

            var taskOfR = await response.Content.ReadAsAsync<R>();

            return taskOfR;
        }
    }
}

I have the following default route defined for the Web API:

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

UPDATE My code breaks into the debugger until the time the PostAsXmlAsync method on the System.Net.HttpClient code is called. However, no request shows up in Fiddler.

However, if I try to compose a POST request in Fiddler or try to fire a GET request via the browser to one of the API end-points, the POST request composed via Fiddler tells me that I am not sending any data and that I must. The browser sent GET request rightly tells me that the action does not support a GET request.

It just seems like the System.Net.HttpClient class is not sending the POST request properly.

Upvotes: 1

Views: 9026

Answers (4)

Muhammad Soliman
Muhammad Soliman

Reputation: 23856

Remove FromBody at all and don't make any restrictions in passing parameters (it can be passed at this time either in uri, query string or form submissions (which is kinda a similar to query strings)

[HttpPost]
public string GetFoo(string foo){...}

It will be implicitly parsed and passed.

Upvotes: 0

HashSix
HashSix

Reputation: 105

Try changing the FromBody to FromUri.

If the parameter is a "simple" type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string.

For complex types, Web API tries to read the value from the message body, using a media-type formatter.

Upvotes: 0

MIWMIB
MIWMIB

Reputation: 1497

I experienced a similar problem (may not be same one though). In my case, I hadn't given name attribute to the input element. I only figured that out when fiddler showed no post data being sent to the server (just like your case)

<input id="test" name="xyz" type="text" />

Adding the name attribute in the input tag fixed my problem.

However, there is one more thing to note. WebAPI does not put form data into parameters directly. Either you have to create an object with those properties and put that object in the parameter of the post controller. Or you could put no parameters at all like this:

    [Route("name/add")]

    public async Task Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            return;
        }

        var provider = PostHelper.GetMultipartProvider();
        var result = await Request.Content.ReadAsMultipartAsync(provider);
        var clientId = result.FormData["xyz"];
        ...

Upvotes: 0

JotaBe
JotaBe

Reputation: 39055

One of the most usual problems is that you don't use the appropriate attribute.

Take into account that there are attributes for ASP.NET MVC and ASP.NET Web API with the same name, but which live in different namespaces:

This is a very very usual error, and it affects to allkind of things that exist for both MVC and Web API. So you must be very careful when using something which can exists in bith worlds (for example filters, attributes, or dependency injection registration).

Upvotes: 0

Related Questions