3

I am working on an ASP.NET Core 2.1 application. I need to call a named page handler through ajax.

The method works correctly while in debug/release, but fails once it is published to IIS.

What I have tried

  • I am now using @page "{handler?}" instead of specifying the handler as a query parameter
  • I have made sure that the request url is correct, and that the form contains the "__RequestVerificationToken"
  • I have changed the IIS Application Pool CLR Version to "No Managed Code"
  • I have modified my web.config to look like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <location path="." inheritInChildApplications="false">
        <system.webServer>
            <modules runAllManagedModulesForAllRequests="true" />
            <handlers>
                <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
            </handlers>
            <aspNetCore processPath="dotnet" arguments=".\MyApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
        </system.webServer>
    </location>
</configuration>

Code:

This is the handler method, there are similar ones in other pages and none of them is found by the ajax request (but again, this only happens once it is deployed to IIS):

[HttpPost]
public IActionResult OnPostExampleHandler([FromForm]ExampleHandlerModel model)
{
    // ...

    return new JsonResult(new { data, message });
}

This is the javascript code which is called on submit:

function submitForm()
{
    return $.ajax(
        {
            type: "POST",
            url: "/relativeURL/ExampleHandler",
            data: $('#ExampleHandlerForm').serialize(),
            dataType: "json",

            complete: function (res)
            {
                // do something on completion
            }
        });
}

And lastly this is the Html/Razor code, I am using the 'form' TagHelper which ensures the AntiForgeryToken is present when the form is serialized:

<form method="post" asp-page-handler="ExampleHandler" id="ExampleHandlerForm">

    <div class="modal-content">
        <div class="modal-header">
            <h5 class="modal-title">@Model.Details.Description</h5>
            <button type="button" class="close" data-dismiss="modal">
                <span aria-hidden="true">&times;</span>
            </button>
        </div>
        <div class="modal-body form-row">

            @* Input Fields *@

        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">@Lang.Operations.Close</button>
            <button type="button" onclick="submitForm();" class="btn btn-primary">@Lang.Operations.Save</button>
        </div>
    </div>

</form>

Error Message

POST http://root:port/relativeURL/ExampleHandler 404 (Not Found)
send    @   jquery.min.js:2
ajax    @   jquery.min.js:2
submitForm  @   VM106:13
onclick @   5:1
  • 404 is a credential issue. Server probably wants HTTPS (secure SSL) and you are not going performing SSL. See : https://www.codeproject.com/Articles/1000189/A-Working-TCP-Client-and-Server-With-SSL – jdweng Oct 09 '19 at 16:44
  • @jdweng But why would it only happen with Ajax Post requests? I have also disabled SSL for the project and removed app.UseHttpsRedirection(); in the Startup configuration, since I do not yet need https at this stage – user12189734 Oct 09 '19 at 16:48
  • Is your app hosted on a virtual application under IIS, if yes the path should contain that virtual application name. – user1672994 Oct 09 '19 at 16:58
  • Use a sniffer like wireshark or fiddler and compare the headers in first request with working and non-working. – jdweng Oct 09 '19 at 17:00
  • @jdweng The headers seem to be the same, except for `Accept-Encoding: gzip, deflate`, which is `Accept-Encoding: gzip, deflate, br` on the working version, but from what I see this is browser-related and not something I can change via Ajax? – user12189734 Oct 11 '19 at 13:13
  • Look for the word "Header" on following : https://learn.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-3.0 and https://stackoverflow.com/questions/10093053/add-header-in-ajax-request-with-jquery – jdweng Oct 11 '19 at 13:22
  • @jdweng I know how to change header values, but 'Accept-Encoding' in particular is an unsafe header which cannot be changed https://stackoverflow.com/a/3778750/12189734 – user12189734 Oct 11 '19 at 13:32
  • That posting is referring Browsers. Are you using a Browser or HTTP method in Net? HTTP in Net does not automatically add anything. See : https://social.msdn.microsoft.com/Forums/en-US/f4a079ef-ec12-41ae-879a-84d881392ed9/does-httpclient-add-header-aceptencoding-is-gzip-deflate-automatically?forum=winappswithcsharp – jdweng Oct 11 '19 at 13:44
  • 2 years and no answer... did you ever get this right? – Ortund Mar 23 '21 at 08:38
  • I format my url as: `url: "./relativeURL?handler=ExampleHandler"`, not sure if that's your issue – Dave Cousineau Apr 26 '21 at 21:20

1 Answers1

1

Worked for me.

  1. add [IgnoreAntiforgeryToken(Order = 1001)] to PageModel. Even if AntiforgeryTokens are disabled in your project.
  2. Remove "/" from the start of the url, in that case browser will make a request with respect to the current page so you don't need to hardcode entire path.

Example:

url: 'NameOfPageModel?handler=NameOfHandler'

don't forget to remove prefix OnPost and suffix Async(if exist) from handler name.

Vlad
  • 193
  • 2
  • 14