locked
Fetch CORS Post resulting in Bad request RRS feed

  • Question

  • User-1699898665 posted

    I'm not sure if this is a client issue or the server.  I've set up a very basic test web api with a cors policy that should allow any client to access it (?).  Controller method:

            [HttpPost]
            public async Task<ActionResult<Organisation>> PostOrganisation(Organisation value)
            {
    
                await _dataService.SaveOrganisation(value, "MrUser");
    
                return CreatedAtAction(nameof(GetOrganisation), new { id = value.ID }, value);
    
            }

    Policy:

            public void ConfigureServices(IServiceCollection services)
            {
                //Specify the client site URLs that can use this service
                services.AddCors(options =>
                {
                    options.AddPolicy(name: corsPolicy,
                                      builder =>
                                      {
    builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
                                      });
                });
    
                services.AddControllers();
            }

    The Organisation model class is very simple:

        public class Organisation
        {
    
            public int ID { get; set; }
            public string Name { get; set; }
            public int? OrganisationTypeID { get; set; }
            public int? StatusID { get; set; }
            public string Website { get; set; }
            public string Notes { get; set; }
            //public string CreatedBy { get; set; }
            //public DateTime? CreatedDate { get; set; }
            //public string LastEditBy { get; set; }
            //public DateTime? LastEditDate { get; set; }
        }

    If I use Postman to send a Post request this works fine.  However, from Javascript I get a status of 204 from an OPTIONS request, followed by a 400 status for the POST.  The fetch being:

                fetch(postURI, {
                    mode: 'cors',
                    method: 'POST',
                    headers: {
                                'Accept': 'application/json',
                                'Content-Type': 'application/json'
                             },
                    body: JSON.stringify(item)
                   })
                    .then(response => response.json())
                    .then(() => {
                        console.log(response);
                        getOrganisation();
                    })
                    .catch(error => console.error('Unable to add/update item.', error));
            }

    I have checked that item is fine and corresponds exactly to the model.

    Any ideas?

    Paul

    Thursday, July 30, 2020 3:08 PM

All replies

  • User-1699898665 posted

    Did I say the json payload "item" was correct....err, no, as it turned out.  The two IDs have now been converted to integers and its all working.

    P

    Thursday, July 30, 2020 4:19 PM
  • User1686398519 posted

    Hi PJM8765,

    1. Did I say the json payload "item" was correct....err, no, as it turned out. 
      • I am not quite sure what this means. Is the value of "item" correct?
      • You need to check whether the value of "item" is correct, which may also cause your error.
    2. You need to have Access-Control-Allow-Credentials: true as response header to solve the problem of getting a status of 204 from an OPTIONS request.This has been explained in fetch.

    Best Regards,

    YihuiSun

    Friday, July 31, 2020 9:55 AM
  • User-1699898665 posted

    • I am not quite sure what this means. Is the value of "item" correct?
    • You need to check whether the value of "item" is correct, which may also cause your error.

    Item is now correct, yes.  I hadn't looked at the response for the POST, which told me that I had string values trying to be put into int? data items. 

    You need to have Access-Control-Allow-Credentials: true as response header to solve the problem of getting a status of 204 from an OPTIONS request.This has been explained in fetch.

    Thanks, like so:

            public void ConfigureServices(IServiceCollection services)
            {
                //Specify the client site URLs that can use this service
                services.AddCors(options =>
                {
                    options.AddPolicy(name: corsPolicy,
                                      builder =>
                                      {
    builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials();
                                      });
                });
    
                services.AddControllers();
            }

    Its still early days for me with both Web API and the JS/JQuery clients. Obviously I'm going to have to finally get my head round HTTP Request and Responses in a level of detail I haven't had to before. 

     

    Friday, July 31, 2020 11:38 AM