MVC Html.BeginForm 与 Ajax.BeginForm 使用总结

最近采用一边工作一边学习的方式使用MVC5+EF6做一个Demo项目, 期间遇到不少问题, 一直处于研究状态, 没能来得及记录.

今天项目进度告一段落, 得以有空记录学习中遇到的一些问题.

由于MVC的PartialView非常的灵活, 类似与WebForm的UserControl, 配合母版页可以大大节约重复开发UI的时间

既然UI可以是Partial的, 那么只要把Form放到PartialView中, 在Form中写好Action地址, 是不是每个Partial就拥有了自己独立的完整的处理逻辑了呢?

于是有了以下代码

@model DataStruct.Models.Bussiness.CallMe
@Scripts.Render("~/bundles/jq/validate")
@Scripts.Render("~/bundles/ajaxform")
<script type="text/javascript">
    function CallMeSuccess(data) {
        if (data.code == 0) {
            alert("Success");
        }
    }
    function CallMeFailure() {
        alert("Failure");
    }
</script>

<div class="message">
    <p style="margin-bottom:20px;">Subscribe to Our Newsletter: Do you want to hear from us? Just fill out the form to subscribe for free.</p>
    @using (Ajax.BeginForm("CallMe", "Partial", new AjaxOptions
    {
        OnSuccess = "CallMeSuccess",
        OnFailure = "CallMeFailure",
        UpdateTargetId = "CallMeUpdateTarget",
        InsertionMode = InsertionMode.Replace 
    }))
    {
        @Html.AntiForgeryToken()
        <ul>
            <li>
                Name*<br>
                @Html.EditorFor(model => model.Name)<br>
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </li>
            <li>
                E-mail*<br>
                @Html.EditorFor(model => model.Email)<br>
                @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
            </li>
            <li>
                Phone*<br>
                @Html.EditorFor(model => model.Phone)<br>
                @Html.ValidationMessageFor(model => model.Phone, "", new { @class = "text-danger" })
            </li>
        </ul>
        <input class="sub" type="submit" value="CALL ME" />
    }
    <div id="CallMeUpdateTarget" class="text-danger"></div>
</div>
@model DataStruct.Models.User.Member

@{
    ViewBag.Title = "regsiter——you can through this web regsiter an username.";
    Layout = "~/Areas/C/Views/Shared/_LayoutLogin.cshtml";
}

<link type="text/css" rel="stylesheet" href="@Url.Content("~/Areas/C/Content/css/regsiter.css")" />
    @Scripts.Render("~/bundles/jq/validate")
    @Scripts.Render("~/bundles/ajaxform")
<script type="text/javascript">
    function RegsiterSuccess(data) {
        if (data.code == 0) {
            window.top.location = "/c/CBase/Index";
        }
    }
    function RegsiterFailure() {
        alert("Failure");
    }
</script>

<!--登录注册主要内容-->
<div class="content">
    <hr size="3" color="#333" />
    <h2>Create Your DirecTrucks.com Account</h2>
    <p class="remind">Fields marked with an asterisk * are required</p>
    <div class="regsiterForm">
        @using (Ajax.BeginForm("Regsiter", "Jurisdiction", new AjaxOptions
        {
            OnSuccess = "RegsiterSuccess",
            OnFailure = "RegsiterFailure",
            UpdateTargetId = "RegsiterUpdateTarget",
            InsertionMode = InsertionMode.Replace 
        }))
        {
            @Html.AntiForgeryToken()
            <p class="remind">Enter Your Business Information</p>
            <table width="600" border="0">
                <tr>
                    <td><label for="Company">Your Company Name</label></td>
                    <td>@Html.TextBoxFor(model => model.Company, new { placeholder = "Please put your company name" })</td>
                    <td>&nbsp;</td>
                </tr>
                <tr>
                    <td><label for="Use">The Truck Use</label></td>
                    <td>@Html.TextBoxFor(model => model.Used, new { placeholder = "your truck is used method" })</td>
                    <td>&nbsp;</td>
                </tr>
                <tr>
                    <td><label for="number">Your Company Phone Number</label></td>
                    <td>@Html.TextBoxFor(model => model.CompanyPhone, new { placeholder = "6-12 letters or Numbers, can't begin with Numbers" })</td>
                    <td>&nbsp;</td>
                </tr>
            </table>

            <div id="RegsiterUpdateTarget" class="text-danger"></div>
            <input type="submit" id="submit" name="submit" value="submit" />
        }
</div>
</div>
<!--登录注册主要内容-->

<!--客户留言板块-->
<!--PartialView-->
@{Html.RenderPartial("~/Areas/C/Views/Partial/CallMe.cshtml");}

大家注意到以下这货, 它是MVC AjaxForm必须的JS组件

    @Scripts.Render("~/bundles/ajaxform")
//BundleConfig bundles.Add(new ScriptBundle("~/bundles/ajaxform").Include("~/Scripts/jquery.unobtrusive-ajax.min.js"));

两个PartialView由于业务独立. 都引用了这货, 然后就是这货, 由于页面渲染的时候, 会加载两次, 导至点击任意一个Submit, 后台均会收到两次提交, 这显然不是我要的

于是乎把它提取到母版页中去, 包含关系变为了 母版页(含AjaxForm JS组件) > Reg > CallMe, 这样CallMe也能使用母版页的AjaxForm JS组件, 正确的异步Submit

那有人要问了, 为什么要使用AjaxForm整这一出呢? 用同步的Form不就好了啊?

答案详见: http://blog.csdn.net/hanxuemin12345/article/details/38872807

同步提交是会且必须要转跳页面的, 跳回当前页也叫转跳, 所以虽然更简单, 但是不够灵活

15年圣诞节补充:

如果PartialView是强类型视图, 同时View也是强类型视图, 且两个类型不一样. 则必须用Render.Action或者Action方式加载PartialView

否则页面渲染的时候会报 "传入类型不是PartialView定义的类型" 错误

因为类型是Action传入的, 如果PartialView不用Action加载, 则View页面渲染的时候会把View的Model通过View的Action传递给PartialView导致传递类型错误

原文地址:https://www.cnblogs.com/motorcycle-stone/p/5066837.html