0

I'm trying to send form data along with (optional) file from Javascript to ASP.NET MVC WebAPI controller. Data for sending is prepared in the following way:

var save = function () {

    if (!validate())
        return;

    var details = new RecipeDetails();
    details.id = recipeDetails.id;
    details.name = name();
    details.description = description() !== "" ? description() : null;
    details.preparationTime = preparationTime();
    details.totalTime = totalTime();
    details.portions = portions() !== "" ? portions() : null;

    var formData = new FormData();
    formData.append("id", details.id);
    formData.append("name", details.name);
    formData.append("description", details.description);
    formData.append("preparationTime", details.preparationTime);
    formData.append("totalTime", details.totalTime);
    formData.append("portions", details.portions);

    recipeService.updateRecipeDetails(formData, saveSucceeded, saveFailed);

    spinnerVisible(true);
};

I don't send picture yet. Service sends data in the following way:

var postFormData = function (url, formData, success, failure) {

    $.ajax({
        type: "POST",
        url: url,
        contentType: false,
        data: formData,
        cache: false,
        processData: false,
        success: success,
        error: failure
    });
};

It looks like Javascript sends data correctly, request payload looks like following:

------WebKitFormBoundaryo4APLG1O4LUg7fSf
Content-Disposition: form-data; name="id"

1
------WebKitFormBoundaryo4APLG1O4LUg7fSf
Content-Disposition: form-data; name="name"

Naleśniki1
------WebKitFormBoundaryo4APLG1O4LUg7fSf
Content-Disposition: form-data; name="description"

Opis
------WebKitFormBoundaryo4APLG1O4LUg7fSf
Content-Disposition: form-data; name="preparationTime"

00:15:00
------WebKitFormBoundaryo4APLG1O4LUg7fSf
Content-Disposition: form-data; name="totalTime"

00:20:00
------WebKitFormBoundaryo4APLG1O4LUg7fSf
Content-Disposition: form-data; name="portions"

4
------WebKitFormBoundaryo4APLG1O4LUg7fSf--

The controller's action looks like following:

    [HttpPost]
    [Authorize]
    public HttpResponseMessage UpdateRecipeDetails(RecipeDetailsDto details)
    {
        int userId = User.Identity.GetId();

        recipeService.UpdateRecipeDetails(userId, details);

        return Request.CreateResponse(details);
    }

Now the problem is, that Javascript receives 500 error and control never enters the UpdateRecipeDetails method.

Now to clarify:

  • I was first sending the form simply through POST body and everything worked, so it doesn't seem to be a problem with deserializing JSON;
  • I looked into IIS Express logs for clues, but there are none;
  • Nothing is inside Output/Debug pane in VS

Why cannot I send form data through FormData?


Response headers:

Request URL:http://localhost:6868/api/RecipeBackend/UpdateRecipeDetails
Request Method:POST
Status Code:500 Internal Server Error
Remote Address:[::1]:6868
Referrer Policy:no-referrer-when-downgrade

Cache-Control:no-cache
Content-Length:0
Date:Mon, 30 Oct 2017 10:47:36 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/10.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=(...)=
Spook
  • 25,318
  • 18
  • 90
  • 167
  • 2
    You need to `.append()` each name/value pair (you cannot append a stringified object) –  Oct 30 '17 at 09:14
  • @StephenMuecke I get it, but should I format it in some specific way? Note, that I do not have a regular form, I'm using knockout.js, so the answer from "duplicated" question does not help me much. It seems like I have to craft the FormData myself. I posted each single field in separate field, added file to model, but I'm still receiving 500 error. – Spook Oct 30 '17 at 09:38
  • I assume you mean you used `formData.append('id', recipeDetails.id); formData.append('name', name());` etc? And use your developer tools (the Network tab) to inspect the response which will give the details of the error. And using knockout should have nothing to do with it. If youhave generated you view correctly and your form controls have `name="id"`, `name="name"` etc to match your model properties then you can just use `var formdata = new FormData($('form').get(0));` –  Oct 30 '17 at 09:42
  • @StephenMuecke I modified my question according to comment. I also believe, that it no longer duplicates the question you referenced. – Spook Oct 30 '17 at 10:08
  • I've re-opened it (although you should not be completely changing your question!). What does the response message tell you? –  Oct 30 '17 at 10:11
  • @StephenMuecke I included the complete response I could get from Chrome's developer tools to the question. – Spook Oct 30 '17 at 10:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157796/discussion-between-stephen-muecke-and-spook). –  Oct 30 '17 at 10:56
  • I'm just commenting on this now so I can find the question again. I have an idea what the answer might be as I'm trying to fix this myself so I'll be back in a bit. – sanepete Aug 06 '18 at 09:57

0 Answers0