18

I can't seem to get this to work... I have some jQuery like this on the client:

$.ajax({
    type: "POST",
    url: "api/report/reportexists/",
    data: JSON.stringify({ "report":reportpath }),
    success: function(exists) {
        if (exists) {
            fileExists = true;
        } else {
            fileExists = false;
        }
    }
});

And in my Web.API controller I have a method like this:

[HttpPost]
public bool ReportExists( [FromBody]string report )
{
    bool exists = File.Exists(report);
    return exists;
}

I'm just checking to see if a file lives on the server, and to return a bool as to whether it does or not. The report string I am sending is a UNC path, so reportpath looks like '\\some\path\'.

I can fire the script okay, and hit a breakpoint in my ReportExists method, but the report variable is always null.

What am I doing wrong?

I also see a way to post with .post and postJSON. Maybe I should be using one of those? If so, what would my format be?

Update: An additional clue maybe- if I remove [FromBody] then my breakpoint doesnt get hit at all- 'No http resource was found that matches the request'. Examples I am looking at show that [FromBody] isn't needed...?

2
  • 1
    $.ajax would be more appropriate for this situation since you may also need to include contentType: "application/json" as an option to $.ajax Commented Feb 8, 2013 at 19:12
  • Make sure to check your ModelState for errors in case something went wrong when binding parameters. Commented Feb 8, 2013 at 20:40

5 Answers 5

29

So I found the problem, and the solution. So, first thing first. The contentType cannot be 'application/json', it has to be blank (default to application/x-www-form-urlencoded I believe). Although it seems you have to SEND json, but without a name in the name value pair. Using JSON.stringify also messes this up. So the full working jQuery code is like this:

$.ajax({
    type: "POST",
    url: "api/slideid/reportexists",
    data: { "": reportpath },
    success: function(exists) {
        if (exists) {
            fileExists = true;
        } else {
            fileExists = false;
        }
    }
});

On the Web.API side, you MUST have the [FromBody] attibute on the parameter, but other than this it's pretty standard. The real problem (for me) was the post.

In Fiddler, the request body looked like this "=%5C%5Croot%5Cdata%5Creport.html"

This post really had the answer, and linked to this article which was also very helpful.

Sign up to request clarification or add additional context in comments.

4 Comments

+1000 if i could. The only post that completely fixed my problem.
Yes, this works when you have a simple data type and not using a DTO or model. I finally gave up on everything that in theory should have worked and just did it exactly like this answer and it works.
what if you have 2 parameters?!
@K-Dawg, you'd pass a JSON object, such as { id: 12345, name: "Jane Smith" }
13

jQuery.ajax() by default sets the contentType to be application/x-www-form-urlencoded. You could send the request in application/json instead. Also, you should send your data as a string and it will get model bind to the report parameter for your post method:

$.ajax({
    type: "POST",
    url: "api/report/reportexists/",
    contentType:  "application/json",
    data: JSON.stringify(reportpath),
    success: function(exists) {
        if (exists) {
            fileExists = true;
        } else {
            fileExists = false;
        }
    }
});

1 Comment

Yes, content type is often the issue.
6

This worked for me, all other approaches didn't:

function addProduct() {
        var product = { 'Id': 12, 'Name': 'Maya', 'Category': 'newcat', 'Price': 1234 };             
        $.ajax({
            type: "POST",
            url: "../api/products",
            async: true,
            cache: false,
            type: 'POST',
            data: product,
            dataType: "json",
             success: function (result) {

            },
            error: function (jqXHR, exception) {
                alert(exception);
            }
        });
    }

Serverside:

 [HttpPost]
    public Product[] AddNewProduct([FromBody]Product prod)
    {
        new List<Product>(products).Add(prod);
        return products;
    }

2 Comments

I overhand the plain JSON object, no stringify needed !
Thanks,really thanks, after many searches finally this worked for me!
0

If you're using MVC's FromBody attribute, the MVC binder treats this as an optional parameter. This means you need to be explicit about the Parameter names even if you've only got a single FromBody parameter.

You should be able to work with something as simple as this:

Controller:

[HttpPost]
public bool ReportExists( [FromBody]string report )
{
    bool exists = File.Exists(report);
    return exists;
}

Javascript:

$.ajax({
    type: "POST",
    url: "api/report/reportexists/",
    data: { "report":reportpath },
    success: function(exists) {
    ...

You must ensure that your data object in jQuery matches the parameter names of your Controllers exactly.

Comments

-1

$.post served the purpose for me. Remove the [FromBody] from webapi and give the url in the url parameter of the $.post in jquery client. It worked!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.