Ajax.BeginForm doesn't fire AJAX script, falls back on postback

走远了吗. 提交于 2019-12-18 12:14:22

问题


I will update this problem with the solution, I wanted to include my problem and solution as I wasn't able to find it on Stackoverflow. If you want to jump in with the solution, feel free.

I have a newly created 'Empty' MVC5 project created using Visual Studio 2013. I needed a from and wanted AJAX behavior if possible. Using Ajax.BeginForm was always straight-forward in MVC3 so I thought it would be in MVC5 also.

However none of the javascript functions I've specified in OnBegin, OnFailure or OnSuccess inside the AjaxOptions are invoked when I click the submit button. Instead an Ajaxless post is sent to the server, this has shown to be true by examining Request.IsAjaxRequest which returns false.

I have concluded that for some reason, then, ajax isn't being used at all. I've checked a number of things such as web.config, my layout scripts, etc.

My layout includes the following scripts:

<script src="~/Scripts/jquery-1.5.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

My web.config includes:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
</configuration>

My view:

@model ContactEnquiryViewModel

@{
AjaxOptions ContactOptions = new AjaxOptions()
{
    OnBegin = "OnConactFormBegin()",    
    OnSuccess = "OnContactFormSuccess()",
    OnFailure = "OnContactFormFailure()"
    };
}

<div id="EnquiryFormContainer">

@using (Ajax.BeginForm("Contact", "Home", new { formName = "EnquiryForm" }, ContactOptions))
    {
    @Html.HiddenFor(m => m.Subject)

    <div class="field">
        @Html.LabelFor(m => m.FirstName)
        @Html.TextBoxFor(m => m.FirstName)
        <div class="validation">
            @Html.ValidationMessageFor(m => m.FirstName)
        </div>
    </div>

    <div class="field">
        @Html.LabelFor(m => m.LastName)
        @Html.TextBoxFor(m => m.LastName)
        <div class="validation">
            @Html.ValidationMessageFor(m => m.LastName)
        </div>
    </div>

    <div class="field">
        @Html.LabelFor(m => m.Email)
        @Html.TextBoxFor(m => m.Email)
        <div class="validation">
            @Html.ValidationMessageFor(m => m.Email)
        </div>
    </div>

    <div class="field">
        @Html.LabelFor(m => m.PhoneNumber)
        @Html.TextBoxFor(m => m.PhoneNumber)
        <div class="validation">
            @Html.ValidationMessageFor(m => m.PhoneNumber)
        </div>
    </div>

    <div class="field">
        @Html.LabelFor(m => m.Comments)
        @Html.TextAreaFor(m => m.Comments)
        <div class="validation">
            @Html.ValidationMessageFor(m => m.Comments)
        </div>
    </div>

    <div id="submitButtonContainer">
        <input type="submit" value="Submit" name="submit" />
    </div>
    }
</div>

My controller action (unfinished):

[HttpPost]
public ActionResult Contact(ContactViewModel viewModel, String formName = "")
    {
    if (Request.IsAjaxRequest())
        {
        return new EmptyResult();               
        }

    return new EmptyResult();
    }

I have checked some other posts on this problem, and couldn't find a solution. Though some hinted at the possible solution, I was confused by the Microsoft CDN (http://www.asp.net/ajaxlibrary/cdn.ashx).

On the Microsoft CDN they have the following section:

The following ASP.NET MVC JavaScript files are hosted on this CDN:

ASP.NET MVC 5.0

http://ajax.aspnetcdn.com/ajax/mvc/5.0/jquery.validate.unobtrusive.js
http://ajax.aspnetcdn.com/ajax/mvc/5.0/jquery.validate.unobtrusive.min.js

ASP.NET MVC 4.0

http://ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.js
http://ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js

ASP.NET MVC 3.0

http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/MicrosoftMvcAjax.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/MicrosoftMvcAjax.debug.js 

ASP.NET MVC 2.0

http://ajax.aspnetcdn.com/ajax/mvc/2.0/MicrosoftMvcAjax.js
http://ajax.aspnetcdn.com/ajax/mvc/2.0/MicrosoftMvcAjax.debug.js 

ASP.NET MVC 1.0

http://ajax.aspnetcdn.com/ajax/mvc/1.0/MicrosoftMvcAjax.js
http://ajax.aspnetcdn.com/ajax/mvc/1.0/MicrosoftMvcAjax.debug.js 

They would seem to suggest the only script you'll need for MVC5 is jquery.validate.unobtrusive.


回答1:


To get a local copy as part of your MVC project" From VS2013, right click on your MVC 5 project, select "Manage NuGet Packages". Select "Online" and search for "jquery.unobtrusive-ajax", Then Install "Microsoft.jQuery.Unobtrusive.Ajax".




回答2:


I had the same issue on a dummy MVC5 project.

Add this to your BundleConfig

        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));

Add this to your layout.cshtml

@Scripts.Render("~/bundles/jqueryval")

I didn't add any new files to my projects so if you have an MVC 4 or 5 web project, I doubt if you would need to add any extra js files.

It solved my issue. I hope it solves yours.




回答3:


Everything has started working since I included the following script in my layout:

<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js"></script>

On the Microsoft CDN it looks as though this script is MVC3-specific.

Feel free to contribute better ways if possible, or answer the question: "Why isn't this script included in the MVC project template (VS2013)?"




回答4:


Did you check if your web.config file contains

<appSettings>
    <!-- this one is for client side validation -->
    <add key="ClientValidationEnabled" value="true" />

    <!-- this is for unobtrusive ajax -->
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>



回答5:


I had the same issue and the solution was actually to make sure that the script references are in the right order (specifically that @Scripts.Render("~/bundles/jquery") appears before @Scripts.Render("~/bundles/jqueryval"))

For some reason it wasn't like it by default when creating the new project and adding the nuget packages




回答6:


Adding reference to the javascript file jquery.unobtrusive-ajax.js worked for me.




回答7:


For me it was a little bit peculiar and counter-intuitive.

The page was displayed from the controller with a custom route attribute:

[Route("contact")]
[HttpGet]
public ActionResult Contact()
{
    return this.View();
}

but the POST action handling the AjaxRequest had no [Route("contact")] attribute and that's why it didn't work.



来源:https://stackoverflow.com/questions/21831451/ajax-beginform-doesnt-fire-ajax-script-falls-back-on-postback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!