如何在MVC3中使用辅助函数进行复杂模型绑定?

时间:2012-04-03 18:49:03

标签: asp.net-mvc-3

我有一个复杂的模型,我传递给我的视图,它适用于显示,但一旦我传回它,它都是空的。我的模型如下

public class LeavingShopSetupViewModel
{
    public LeavingShopSetupViewModel()
    {

    }
    ...Additional constructor here....

    public BasicSetupAccessor BasicSetupAccessor { get; set; }

    public SetupAcessor SetupAcessor { get; set; }

    public FrontSuspensionAccessor FrontSuspensionAcessor { get; set; }

    public RearSuspensionAccessor RearSuspensionAccessor { get; set; }

    public BrakeAccessor BrakeAccessor { get; set; }

    public void SaveSetup()
    {
        ...Save code.....
    }
}

每个对象都由简单的对象组成,如双精度,字符串,整数....

我的观点如下w / javascript代码

@using RIS.Models.EventModels
@model LeavingShopSetupViewModel
<script type="text/javascript">
    $(function() {
        $("#submit_btn").click(function() {
            var form = $('#setupForm');
            $.ajax({
                type: 'post',
                url: "@Url.Action("SaveSetup","Events")",
                data: form.serialize()
            });
            return false; // <-- cancel the default event
        });

    });
</script>
<form id="setupForm">
    <fieldset>
        <legend>Leaving Shop Setup</legend>
        <div class="row-fluid">
            <div class="span4">
                ...Boilerplate code.....
                @BuildSheetHelpers.DoubleTextBox("FARB Link Length", Model.BasicSetupAccessor.SwayBarLinkLengthLF, Model.BasicSetupAccessor.SwayBarLinkLengthLR)
                @BuildSheetHelpers.DoubleTextBox("Bump Stop Gap", Model.BasicSetupAccessor.BumpStopGapL, Model.BasicSetupAccessor.BumpStopGapR)
                @BuildSheetHelpers.DoubleTextBox("Total BS Height", Model.BasicSetupAccessor.BumpRubberHeightTotalL, Model.BasicSetupAccessor.BumpRubberHeightTotalR)
            ...plenty more code that is all similar to this.....
            </div>
        </div>
    </fieldset>
    <a class="btn btn-primary" id="submit_btn">Save Setup</a>

    @Html.HiddenFor(model => model.SetupAcessor)
    @Html.HiddenFor(model => model.BasicSetupAccessor)
    @Html.HiddenFor(model => model.BrakeAccessor)
    @Html.HiddenFor(model => model.FrontSuspensionAcessor)
    @Html.HiddenFor(model => model.RearSuspensionAccessor)
</form>

我的助手功能如下

@helper DoubleTextBox(string displayTag, double? left, double? right)
{
    <div class="row-fluid form-inline">
        <input type="text" class="span4 data" value="@left"/>
        <label  class="span4 pagination-centered">@displayTag</label>
        <input type="text" class="span4 data" value="@right"/>
    </div>
}

SaveSetup操作只是

public ActionResult SaveSetup(LeavingShopSetupViewModel setup)
    {
        setup.SaveSetup();
        return null;
    }

当我在上面的动作中设置断点时,setup变量只包含空值。我怎样才能将完整模型传回去?

2 个答案:

答案 0 :(得分:0)

根据您的评论,我建议您使用EditorTemplates替换助手。编辑器模板是与@Html.EditorFor()助手一起使用的部分视图。

This question建议Brad Wilson's blog发布教程。它不使用Razor,但MVC3的其他一切都是一样的。

因此,您需要为每个需要显示的类型定义EditorTemplate,然后将所有hiddens替换为编辑器:

@Html.EditorFor(model => model.SetupAcessor)
@Html.EditorFor(model => model.BasicSetupAccessor)
@Html.EditorFor(model => model.BrakeAccessor)
@Html.EditorFor(model => model.FrontSuspensionAcessor)
@Html.EditorFor(model => model.RearSuspensionAccessor)

此外,表格上有很多隐藏字段。您可能需要考虑使用SQL / Cache / Session /等持久保存这些值服务器端。

答案 1 :(得分:0)

我想通过对我的帮助函数进行一些修改来包含名称和id,以便jquery.serialize()正确地序列化属性。我还必须编写一个不复杂的viewmodel,并且帮助函数的一些通用方法使它可以很好地工作。该代码如下以供将来参考。找到了通用帮助函数的信息here on stackoverflow

@functions
{
    public static HelperResult DoubleTextBox<T>(T targeObject, string label, Expression<Func<T, double?>> leftTarget, Expression<Func<T, double?>> rightTarget) 
    { 
        var leftExpr = (MemberExpression)leftTarget.Body; 
        var leftProp = (PropertyInfo)leftExpr.Member; 
        var leftValue = leftProp.GetValue(targeObject, null);
        var rightExpr = (MemberExpression)rightTarget.Body; 
        var rightProp = (PropertyInfo)rightExpr.Member; 
        var rightValue = rightProp.GetValue(targeObject, null);

        return DoubleTextBox(label, leftValue, leftProp.Name, rightValue, rightProp.Name);
    } 
}
@helper DoubleTextBox(string displayTag, object leftValue, string leftName, object rightValue, string rightName)
{    
    <div class="row-fluid form-inline">
        <input type="text" class="span4 data" value="@leftValue" id="@leftName" name="@leftName"/>
        <label  class="span4 pagination-centered">@displayTag</label>
        <input type="text" class="span4 data" value="@rightValue" id="@rightName" name="@rightName"/>
    </div>
}