2

So in my Angular front-end app I have a form and in the typescript file I create a new formdata object and append the items to it like so:

public postFormData() {
    const form = $('#customListForm')[0];
    const formData = new FormData();

    formData.append('tenant', form[0].value);
    formData.append('username', form[1].value);
    formData.append('password', form[2].value);

    formData.append('CL_title', form[3].value);
    formData.append('CL_description', form[4].value);
    formData.append('CL_contentType', form[5].value);
    formData.append('CL_template', form[6].value);

    this.http.post(this.apiURL, formData).catch(this.errorHandler).subscribe(res => this.formPosted(res));
    // this.http.get(this.apiURL).catch(this.errorHandler).subscribe(res => this.formPosted(res));
  }  

In the end, my formData is filled in correctly. Now when I try to POST this to my ASP.NET 4.6.1 Web API, it gives me the following error:

POST http://localhost:52613/api/customlist 415 (Unsupported Media Type) 

Here you can see my API code:

// POST api/customlist
    [HttpPost]
    public System.Web.Http.IHttpActionResult Post(CustomList data)
    {
        var test = HttpContext.Current.Request;
        var testje = data;

        return Ok("POST all good");
    }  

I assume the "CustomList data" is wrong? What I'd love is that the formData binds to my model, my model has the same fields as you can see here:

public class CustomList
{
    public string Tenant { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public string CL_title { get; set; }
    public string CL_description { get; set; }
    public string CL_contentType { get; set; }
    public string CL_template { get; set; }
}  

In my headers I can see the following:

Response Headers: Content-Type: application/json
Request Headers: Content-Type: multipart/form-data  

Could this be the issue?

Here's the weird part: I had previously created a .NET Core 2 Web API as well, and my post action looks like this (ignore the file stuff):

// POST api/input
    [HttpPost]
    public async Task<IActionResult> Post(SPInputObject data)
    {            
        var uploads = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
        string filePath = Path.Combine(uploads, data.File.FileName);

        if (System.IO.File.Exists(filePath))
        {
            System.IO.File.Delete(filePath);
        }

        if (data.File.Length > 0)
        {
            using (var fileStream = new FileStream(filePath, FileMode.Create))
            {
                await data.File.CopyToAsync(fileStream);
            }
        }

        ProvisioningService service = new ProvisioningService();
        service.CreateSiteCollection(data.Tenant, data.Title, filePath);

        return Ok("POST all good");
    }  

When I post my SAME Angular form/formdata to this api controller + action, it will enter the POST .... So why is it ok sending it to my .NET Core 2 Web API but not my ASP.NET 4.6.1 Web API?

Anyone know what could be the problem?

EDIT: trying to add content-type to my front-end Angular request doesn't work, here's what I tried:

private httpOptions = {
  headers: new Headers({
    'Content-Type': 'application/json'
  })
};  

Modifying my http post (i've added this.httpOptions):

this.http.post(this.apiURL, formData, 
this.httpOptions).catch(this.errorHandler).subscribe(res => 
this.formPosted(res));  

It then gives the following error on my this.httpOptions:

 "message": "Argument of type '{ headers: Headers; }' is not assignable to parameter of type 'RequestOptionsArgs'.\n  Types of property 'headers' are incompatible.\n    Type 'Headers' is not assignable to type 'Headers'. Two different types with this name exist, but they are unrelated.\n      Property 'keys' is missing in type 'Headers'."
Tempuslight
  • 1,004
  • 2
  • 17
  • 34

2 Answers2

1

You're posting FormData. Most browsers automatically set the Content-Type to "multipart/form-data" when you supply an instance of FormData. If you modify the code to use Content-Type "application/json" then you should also modify your request object to not use FormData, but JSON:

public postFormData() {
    const form = $('#customListForm')[0];

    const requestData = {
       tenant: form[0].value,
       username: form[1].value,
       password: form[2].value,
       CL_title: form[3].value,
       CL_description: form[4].value,
       CL_contentType, form[5].value,
       CL_template: form[6].value
    };

    this.http.post(this.apiURL, requestData);
}  
David Walschots
  • 12,279
  • 5
  • 36
  • 59
0

Try to setup the content type application/json and encoding to utf-8 on the angular side, or on the asp.net side, better on both. Usually it's caused by those two things. Asp.net core's model binding works slightly differently. Here's a good article about that

Model binding JSON POSTs in ASP.NET Core

Peter Húbek
  • 646
  • 6
  • 10