Asp.Net MVC通过ajax传递模型

时间:2013-08-21 21:01:54

标签: asp.net-mvc

我有一个模型,我想用它来生成/绑定一个弹出窗体,该​​窗体仍然隐藏在页面上,直到需要使用。

<table id="dlgNewEdit" class="vtableform hide">
    <tr>
        <td>@Html.CustomLabelFor(m => new NewEditModel().Name)</td>
        <td>
            @Html.HiddenFor(m => new NewEditModel().OemEquipmentMakeId)
            @Html.CustomTextBoxFor(m => new NewEditModel().Name, new { @class = "focus w300" })
            @Html.ValidationMessageFor(m => new NewEditModel().Name)
        </td>
    </tr>
    <tr>
        <td>@Html.CustomLabelFor(m => new NewEditModel().Description)</td>
        <td>
            @Html.CustomTextAreaFor(m => new NewEditModel().Description, new { @class = "w300" })
            @Html.ValidationMessageFor(m => new NewEditModel().Description)
        </td>
    </tr>
</table>

导致:

<table id="dlgNewEdit" class="vtableform hide">
    <tr>
        <td><label class="required" for="Name">* Name</label></td>
        <td>
            <input data-val="true" data-val-number="The field OemEquipmentMakeId must be a number." data-val-required="The OemEquipmentMakeId field is required." id="OemEquipmentMakeId" name="OemEquipmentMakeId" type="hidden" value="0" />
            <input autocomplete="off" class="required tip focus w300" data-val="true" data-val-length="Cannot exceed 50 characters" data-val-length-max="50" data-val-required="Required" id="Name" maxlength="50" name="Name" title="Enter the make name" type="text" value="" />
            <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
        </td>
    </tr>
    <tr>
        <td><label for="Description">Description</label></td>
        <td>
            <textarea class="w300 tip" cols="20" data-val="true" data-val-length="Cannot exceed 500 characters" data-val-length-max="500" id="Description" name="Description" rows="2" title="Enter a brief description">
</textarea>
            <span class="field-validation-valid" data-valmsg-for="Description" data-valmsg-replace="true"></span>
        </td>
    </tr>
</table>

正如您所看到的,我无法想出任何方法来生成正确的表单ID /名称而不在我的所有表达式中使用“new NewEditModel()”。这样做很好,但似乎有点冗长。我希望我的字段名称与我的模型属性完全匹配,因为我希望模型在以下操作中绑定,该操作通过jQuery ajax调用:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public JsonNetResult New(NewEditModel model)
    {
    }

我尝试创建了一个变量:

var myModel = new NewEditModel();

使用:

@Html.HiddenFor(m => myModel.OemEquipmentMakeId)

但是这会生成id / name“myModel.OemEquipmentMakeId”,它不会在我的动作中绑定。有没有办法在不同的庄园里做我想做的事?

*编辑* 以下是视图的更详细表示。同样,我要从ajax形式来回传递的模型不是绑定到页面的模型。这是一个搜索结果页面。当用户单击行上的编辑时,我从服务器通过ajax获取记录并显示在弹出窗口中。单击弹出窗口上的确定通过ajax调用操作。这就是我希望模型在动作中正确绑定的地方。 bootdialog是一个自定义的jQuery插件,我改编自bootbox(Bootstrap模式插件),可以将DOM内容加载到弹出窗口中。

@model IndexModel

@section startupscripts
{
    $('.command-add').on('click', function() { addMake(); })

    $('#SearchGrid')
        .on('click', '.command-edit', function() { editMake($(this).data('id')); })
        .on('click', '.command-delete', function() { deleteMake($(this).data('id')); });

    filter(@Model.Criteria.Page.GetValueOrDefault(1), '@Model.Criteria.SortExpression');
}

@section scripts {
    <script type="text/javascript">
        var _currentPage, _currentSort;
        function filter(page, sort) {
            ...
        }

        function resetSearch() {
            ...
        }

        function addMake() {

            notify();

            bootdialog.prompt($('#dlgNewEdit'),
                {
                    title: 'New OEM Equipment Make',
                    formAction: '@Url.Action("New")',
                    formMethod: 'POST',
                    showClose: false,
                    buttons: [
                        {
                            label: 'OK',
                            value: true,
                            isPrimary: true,
                            callback: function (data) {
                                notify('success', 'New OEM equipment make \'' + data.name + '\' successfully created');
                                filter(_currentPage, _currentSort);
                            }
                        },
                        { label: 'Cancel', value: false }
                    ]
                });
        }

        function editMake(id) {

            notify();

            var bError = false;

            // Load the information from the DB
            $.ajax({
                url: '@Url.Action("Edit")',
                data: { id: id },
                async: false,
                cache: false,
                type: 'GET',
                error: function (xhr, status, error) {
                    notify('error', 'There was an error querying the database', error);
                    bError = true;
                },
                success: function (data) {
                    if (data.errors) {
                        for (var i = 0; i < data.errors.length; i++)
                            notify('error', 'There was an error querying the database', data.errors[i].message);
                        bError = true;
                    } else {
                        $('#dlgNewEdit #@Html.IdFor(m => new NewEditModel().OemEquipmentMakeId)').val(id);
                        $('#dlgNewEdit #@Html.IdFor(m => new NewEditModel().Name)').val(data.data.name);
                        $('#dlgNewEdit #@Html.IdFor(m => new NewEditModel().Description)').val(data.data.description);
                    }
                }
            });

            if (bError) return;

            bootdialog.prompt($('#dlgNewEdit'),
                {
                    title: 'Edit OEM Equipment Make',
                    formAction: '@Url.Action("Edit")',
                    formMethod: 'POST',
                    showClose: false,
                    buttons: [
                        {
                            label: 'OK',
                            value: true,
                            isPrimary: true,
                            callback: function (data) {
                                notify('success', 'OEM equipment make \'' + data.name + '\' successfully updated');
                                filter(_currentPage, _currentSort);
                            }
                        },
                        { label: 'Cancel', value: false }
                    ]
                });
        }

        function deleteMake(id) {
            notify();
            bootdialog.confirm(
                'Are you sure you want to delete this OEM equipment make?',
                { title: 'Delete OEM Equipment Make' },
                function (e) {
                    if (e) {
                        $.ajax({
                            type: 'POST',
                            async: false,
                            url: '@Url.Action("Delete")',
                            data: AddAntiForgeryToken({ id: id }),
                            success: function (data) {
                                if (data.data != null) {
                                    notify('success', 'OEM equipment make \'' + data.data.name + '\' successfully deleted');
                                    filter(_currentPage, _currentSort);
                                } else {
                                    for (var i = 0; i < data.errors.length; i++)
                                        notify('error', 'There was an error deleting the OEM equipment make', data.errors[i].message);
                                }
                            },
                            error: function (xhr, status, error) {
                                notify('error', 'There was an error deleting the OEM equipment make', error);
                            },
                            dataType: 'json'
                        });
                    }
                }
            );
        }

    </script>
}

<div class="row">
    <div class="span3">
        <div class="well well-side">
            @using (Html.BeginForm("SearchGrid", null, FormMethod.Get, new {id = "frmSearch"}))
            {
                <div class="vertical-control-group">
                    @Html.CustomLabelFor(m => m.Criteria.Name)
                    @Html.CustomTextBoxFor(m => m.Criteria.Name)
                </div>
                <div class="vertical-control-group-commands">
                    @Html.CustomLinkButton("Search", new { @class = "btn-primary", onclick = "filter(1, 'Name');", title = "Click to search" })
                    @Html.CustomLinkButton("Reset", new { onclick = "resetSearch();", title = "Click to reset" })
                </div>
                @Html.HiddenFor(m => m.Criteria.Page)
                @Html.HiddenFor(m => m.Criteria.SortExpression)
            }
            <div class="vertical-control-group-divider"></div>
            <div class="vertical-control-group-commands">
                <a href="javascript:void(0);" class="btn btn-inverse tip command-add" title ="Create new make">New Make</a>
            </div>
        </div>
    </div>
    <div class="span9" id="SearchGrid">
        @{
            Html.RenderAction("Loading", "Master", new { area = "", text = "Loading makes. Please wait..." });  
        }
    </div>
</div>

<table id="dlgNewEdit" class="vtableform hide">
    <tr>
        <td>@Html.CustomLabelFor(m => new NewEditModel().Name)</td>
        <td>
            @Html.HiddenFor(m => new NewEditModel().OemEquipmentMakeId)
            @Html.CustomTextBoxFor(m => new NewEditModel().Name, new { @class = "focus w300" })
            @Html.ValidationMessageFor(m => new NewEditModel().Name)
        </td>
    </tr>
    <tr>
        <td>@Html.CustomLabelFor(m => new NewEditModel().Description)</td>
        <td>
            @Html.CustomTextAreaFor(m => new NewEditModel().Description, new { @class = "w300" })
            @Html.ValidationMessageFor(m => new NewEditModel().Description)
        </td>
    </tr>
</table>

1 个答案:

答案 0 :(得分:0)

我刚刚启动了一个MVC3项目,并将其添加为索引视图。

@using MvcApplication3.Models
@model NewEditModel

@{
    ViewBag.Title = "Home Page";
}

<div>
    @using (Html.BeginForm())
    {
        @Html.TextBoxFor(m=>m.Name)
        <input type="submit" value="submit"/>
    }
</div>

在HomeController中我添加了:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(NewEditModel model)
    {
        //model contains the name from the view
        return View();
    }
}

从表单发布的值显示在模型中。

所以不需要new NewEditModel()


因此,基于您的视图,我仍然建议使用部分视图。

将表格拉成部分视图,例如名为“_SearchTable”,设置模型并使用m => m.Property语法,然后在视图中,您只需将表替换为@Html.Partial("_SearchTable", new NewEditModel())

这是一个新的局部视图:

@model NewEditModel
<table id="dlgNewEdit" class="vtableform hide">
    <tr>
        <td>@Html.CustomLabelFor(m => m.Name)</td>
        <td>
            @Html.HiddenFor(m => m.OemEquipmentMakeId)
            @Html.CustomTextBoxFor(m => m.Name, new { @class = "focus w300" })
            @Html.ValidationMessageFor(m => m.Name)
        </td>
    </tr>
    <tr>
        <td>@Html.CustomLabelFor(m => m.Description)</td>
        <td>
            @Html.CustomTextAreaFor(m => m.Description, new { @class = "w300" })
            @Html.ValidationMessageFor(m => m.Description)
        </td>
    </tr>
</table>

并且您的索引视图变为:

@model IndexModel

@section startupscripts
{
    $('.command-add').on('click', function() { addMake(); })

    $('#SearchGrid')
        .on('click', '.command-edit', function() { editMake($(this).data('id')); })
        .on('click', '.command-delete', function() { deleteMake($(this).data('id')); });

    filter(@Model.Criteria.Page.GetValueOrDefault(1), '@Model.Criteria.SortExpression');
}

@section scripts {
    <script type="text/javascript">
        var _currentPage, _currentSort;
        function filter(page, sort) {
            ...
        }

        function resetSearch() {
            ...
        }

        function addMake() {

            notify();

            bootdialog.prompt($('#dlgNewEdit'),
                {
                    title: 'New OEM Equipment Make',
                    formAction: '@Url.Action("New")',
                    formMethod: 'POST',
                    showClose: false,
                    buttons: [
                        {
                            label: 'OK',
                            value: true,
                            isPrimary: true,
                            callback: function (data) {
                                notify('success', 'New OEM equipment make \'' + data.name + '\' successfully created');
                                filter(_currentPage, _currentSort);
                            }
                        },
                        { label: 'Cancel', value: false }
                    ]
                });
        }

        function editMake(id) {

            notify();

            var bError = false;

            // Load the information from the DB
            $.ajax({
                url: '@Url.Action("Edit")',
                data: { id: id },
                async: false,
                cache: false,
                type: 'GET',
                error: function (xhr, status, error) {
                    notify('error', 'There was an error querying the database', error);
                    bError = true;
                },
                success: function (data) {
                    if (data.errors) {
                        for (var i = 0; i < data.errors.length; i++)
                            notify('error', 'There was an error querying the database', data.errors[i].message);
                        bError = true;
                    } else {
                        $('#dlgNewEdit #@Html.IdFor(m => new NewEditModel().OemEquipmentMakeId)').val(id);
                        $('#dlgNewEdit #@Html.IdFor(m => new NewEditModel().Name)').val(data.data.name);
                        $('#dlgNewEdit #@Html.IdFor(m => new NewEditModel().Description)').val(data.data.description);
                    }
                }
            });

            if (bError) return;

            bootdialog.prompt($('#dlgNewEdit'),
                {
                    title: 'Edit OEM Equipment Make',
                    formAction: '@Url.Action("Edit")',
                    formMethod: 'POST',
                    showClose: false,
                    buttons: [
                        {
                            label: 'OK',
                            value: true,
                            isPrimary: true,
                            callback: function (data) {
                                notify('success', 'OEM equipment make \'' + data.name + '\' successfully updated');
                                filter(_currentPage, _currentSort);
                            }
                        },
                        { label: 'Cancel', value: false }
                    ]
                });
        }

        function deleteMake(id) {
            notify();
            bootdialog.confirm(
                'Are you sure you want to delete this OEM equipment make?',
                { title: 'Delete OEM Equipment Make' },
                function (e) {
                    if (e) {
                        $.ajax({
                            type: 'POST',
                            async: false,
                            url: '@Url.Action("Delete")',
                            data: AddAntiForgeryToken({ id: id }),
                            success: function (data) {
                                if (data.data != null) {
                                    notify('success', 'OEM equipment make \'' + data.data.name + '\' successfully deleted');
                                    filter(_currentPage, _currentSort);
                                } else {
                                    for (var i = 0; i < data.errors.length; i++)
                                        notify('error', 'There was an error deleting the OEM equipment make', data.errors[i].message);
                                }
                            },
                            error: function (xhr, status, error) {
                                notify('error', 'There was an error deleting the OEM equipment make', error);
                            },
                            dataType: 'json'
                        });
                    }
                }
            );
        }

    </script>
}

<div class="row">
    <div class="span3">
        <div class="well well-side">
            @using (Html.BeginForm("SearchGrid", null, FormMethod.Get, new {id = "frmSearch"}))
            {
                <div class="vertical-control-group">
                    @Html.CustomLabelFor(m => m.Criteria.Name)
                    @Html.CustomTextBoxFor(m => m.Criteria.Name)
                </div>
                <div class="vertical-control-group-commands">
                    @Html.CustomLinkButton("Search", new { @class = "btn-primary", onclick = "filter(1, 'Name');", title = "Click to search" })
                    @Html.CustomLinkButton("Reset", new { onclick = "resetSearch();", title = "Click to reset" })
                </div>
                @Html.HiddenFor(m => m.Criteria.Page)
                @Html.HiddenFor(m => m.Criteria.SortExpression)
            }
            <div class="vertical-control-group-divider"></div>
            <div class="vertical-control-group-commands">
                <a href="javascript:void(0);" class="btn btn-inverse tip command-add" title ="Create new make">New Make</a>
            </div>
        </div>
    </div>
    <div class="span9" id="SearchGrid">
        @{
            Html.RenderAction("Loading", "Master", new { area = "", text = "Loading makes. Please wait..." });  
        }
    </div>
</div>

@Html.Partial("_SearchTable", new NewEditModel())