MyDaftQuestions
MyDaftQuestions

Reputation: 4701

Cannot post when parameters exist via AJAX Web API

I'm trying to post to a function via Ajax. When the web api function has no parameters, it works.

When I add parameters it fails.

I suspect the issue is due to routing but I don't see how this can be the case.

My function is

    [HttpPost]
    [Route("api/cms/{accountId:int}/{paneId}/{url}/{content}")]
    public IHttpActionResult Post(int accountId, string paneId, string url, string content)
    {
        ....
    }

If I update the above to

    [HttpPost]
    public IHttpActionResult Post()
    {
        ....
    }

Then it works (it hits this function from the AJAX post).

The javascript is

function ajaxStart(type, url, data, successDelegate, failDelegate, errorDelegate) {
    $.ajax({
        type: type.toUpperCase(),
        url: url,
        contentType: "application/json;",
        data: data,
        dataType: "json",
        success: function (response) {
            successDelegate(response);
        },
        failure: function (e) {
            failDelegate(e.statusText);
        },
        error: function (e) {
            errorDelegate(e.statusText);   //always hit this, statusText is Not Found
        }
    })
}

Where the relevant variables are

type = "POST", 
url = "http://localhost:53733/api/cms", 
data = "{"accountId":1,"paneId":"02","url":"/Playground/Index","content":"Left"}"

The data object was created used JSON.Stringify

The same issue occurs with

    public IHttpActionResult Post([FromBody] int accountId, [FromBody]string paneId, [FromBody]string url, [FromBody]string content)

Why does it not accept?

Upvotes: 0

Views: 49

Answers (1)

David Liang
David Liang

Reputation: 21526

When you define Route("api/cms/{accountId:int}/{paneId}/{url}/{content}"), Mvc really expects the route to have accountId, paneId, url and content.

So if you want to post those variables within the route / url, you need to construct the url that way, and you don't need to post any data.

Otherwise if you want to post data in application/json format within the request body back to server, your url / route should be just Route("api/cms").

Incorrect url will result 404.

Option 1: post data in request body

[HttpPost]
[Route("api/cms")]
public IActionResult Post(int accountId, string paneId, string url, string content)
{
    ...
}

$.ajax({
    type: 'POST',
    url: 'http://localhost:53733/api/cms',
    data: data,
    ...
});

Option 2: embed data in url (Not recommend!)

[HttpPost]
[Route("api/cms/{accountId: int}/{paneId}/{url}/{content}")]
public IActionResult Post(int accountId, string paneId, string url, string content)
{
    ...
}

$.ajax({
    type: 'POST',

    // Remember to encode the url parameter! yawk!
    url: 'http://localhost:53733/api/cms/1/2/%2FPlayground%2FIndex/left',

    // No need to post with data as they're already in the url
    // data: data,
    ...
});

My take

// Sample code run on ASP.NET Core MVC 2.0

// Controller
[Route("api/[controller]")]
public class CMSController : Controller
{
    ...

    [HttpPost]
    public IActionResult(CreateCmsViewModel model)
    {
        // Do something

        // Return a 201 response with new location header
        return Created(...);
    }
}

// The view model
public class CreateCmsViewModel
{
    public int AccountId { get; set; }
    public string PaneId { get; set; }
    public string Url { get; set; }
    public string Content { get; set; }
}

// jQuery AJAX
    $.ajax({
    type: 'POST',
    url: 'http://localhost:53733/api/cms',
    data: {
        accountId: 1,
        paneId: "02",
        url: "/Playground/Index",
        content: "Left"
    },
    dataType: 'json',
    // No longer need this
    // contentType: 'application/json',

    ...
}).done(function(response){

});

Upvotes: 2

Related Questions