Search code examples
c#asp.net-corecorsweb-config

Server returns 405 error when ASP.NET CORE 3.1 Action with HttpPost called from Html Form


I have a website developed with ASP.NET CORE 3.1, An action decorated with [HttpPost] and [ValidateAntiForgeryToken] being called from HtmlForm. Everything is OK on my localhost, but when I published it to the server, only this method get 405 error. (Another method in contact form with HttpPost is OK)

my Request headers in fidller :

405 error on server

I don't know why the security headers Allow: GET is in my request headers, my action method decorated with [HttpPost] and in my HTML form the method set to POST. After a lot of search in stackoverflow and other sources on the web, I have done these solutions but none of them worked for me.

this is my action method

[HttpPost]
[ValidateAntiForgeryToken]
[EnableCors("MyPolicy")]
public async Task<IActionResult> Order(OrderSingleProductViewModel model) {
            
   if(!ModelState.IsValid) {
                var product = await _productService.GetResultByIdAsync(model.ProductId);
                return RedirectToAction("Detail", "Post", new {
                    postType = PostType.PRODUCT,
                    slug = product.Slug
                });
            }

            var data = model.Adapt<OrderSingleProductDto>();
            //var basket = await _orderProductService.OrderProductAsync(data);
            var invoice = await _orderProductService.CreateInvoiceAsync(data);
            var result = invoice.Adapt<CustomerInvoiceViewModel>();
            result.CurrencyTitle = WebsiteInfo.CurrencyInfo.DefaultCurrencyTitle;
            var contactInfo = await _websiteOptionService.GetContactInfoAsync();
            result.InvoiceInfo.Address = contactInfo.Address1;
            result.InvoiceInfo.Email = contactInfo.Email;
            result.InvoiceInfo.Phones = contactInfo.Phones;

            var optionLogo = await _websiteOptionService
                .GetOptionAsync("website.logo");
            var optionCompany = await _websiteOptionService
                .GetOptionAsync("company.name");

            if (optionLogo != null)
                result.InvoiceInfo.Logo = optionLogo.Value;

            if (optionCompany != null)
                result.InvoiceInfo.Company = optionCompany.Value;

            return View(result);
        }

    

Enable CORS

public void ConfigureServices(IServiceCollection services) {
            services.AddCors(o => o.AddPolicy("MyPolicy", builder => {
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            }));
}

And in Configure method of Startup class :

app.UseCors("MyPolicy");

Even my action method decorated with [EnableCors("MyPolicy")]

My Web.config file :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
    <modules runAllManagedModulesForAllRequests="false">
        <remove name="WebDAVModule" />
      </modules>
      <handlers>
        <remove name="aspNetCore" />
        <remove name="WebDAV" />
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath=".\Felan.Web.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
    </system.webServer>
  </location>
</configuration>

and my website is hosted in a sharing host provider so I did not access to IIS or any other server's config.


Solution

  • Finally, I find out that the problem is with one of the fields in the database that has NULL value and I was expecting NUllable must have a value exception in the application's developer exception page, but I kept getting HTTP 405 error.

    In my question, I wrote all the solutions that I have tried. It looks like HTTP 405 error means that you must check everything with your code, especially database errors and values. Hope that it helps someone in the feature.