EditorTemplate中奇怪的MVC模型行为

时间:2014-12-19 21:26:59

标签: asp.net asp.net-mvc

在剃须刀EditorTemplate中,以下命令如何为同一ViewModel生成不同的值:

@Html.TextAreaFor(model => model.Value)
@Model.Value

不,在Value get属性中,值不会更改

更新1: 对不起家伙的短信,你知道,累了,沮丧...... 做了一个样本,摆脱了所有的部分和模板。 给文本框编号1,点击添加,编号2,点击添加,编号3,点击添加。 删除号码2。 结果是文本框和显示值之间不同步。

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        TestModel testModel = TestModel.Create();
        Session["model"] = testModel;
        return View("Index", testModel);
    }

    [HttpPost]
    public ActionResult Submit(TestModel submitModel, string submit)
    {
        // merge values in current form
        var testModel = Session["model"] as TestModel;
        if (testModel == null) throw new Exception("No current model found.");
        testModel.MergeFieldValues(submitModel);

        if (submit.StartsWith("Add_"))
        {
            var rowGroupId = Guid.Parse(submit.Substring("Add_".Length));
            TestRowGroup rowGroup = testModel.Groups.SelectMany(g => g.RowGroups).Single(rg => rg.RowGroupId == rowGroupId);
            rowGroup.AddFieldRow();
        }
        if (submit.StartsWith("Del_"))
        {
            var fieldRowId = Guid.Parse(submit.Substring("Del_".Length));
            testModel.RemoveFieldRow(fieldRowId);
        }
        return View("Index", testModel);
    }
}

型号:

public class TestModel
{
    public List<TestGroup> Groups { get; set; }

    public static TestModel Create()
    {
        var testModel = new TestModel { Groups = new List<TestGroup>() };
        var grp = new TestGroup { RowGroups = new List<TestRowGroup>() };
        var rowGrp = new TestRowGroup { RowGroupId = Guid.NewGuid(), FieldRows = new List<TestFieldRow>() };
        var fldRow = new TestFieldRow { FieldRowId = Guid.NewGuid(), Fields = new List<TestFormField>() };
        var fld = new TestFormField { FieldId = Guid.NewGuid() };
        fldRow.Fields.Add(fld);
        rowGrp.FieldRows.Add(fldRow);
        grp.RowGroups.Add(rowGrp);
        testModel.Groups.Add(grp);
        return testModel;
    }

    public void MergeFieldValues(TestModel src)
    {
        foreach (var srcField in src.Groups.SelectMany(g => g.RowGroups.SelectMany(rg => rg.FieldRows.SelectMany(fr => fr.Fields))))
        {
            var destField = Groups.SelectMany(g => g.RowGroups.SelectMany(rg => rg.FieldRows.SelectMany(fr => fr.Fields))).FirstOrDefault(f => f.FieldId == srcField.FieldId);
            if (destField == null) throw new Exception("Field not found during merge");
            destField.Value = srcField.Value;
        }
    }

    public void RemoveFieldRow(Guid fieldRowId)
    {
        foreach (var group in Groups)
        {
            foreach (var rowGroup in group.RowGroups)
            {
                rowGroup.FieldRows.RemoveAll(fieldRow => fieldRow.FieldRowId == fieldRowId);
            }
        }
    }   
}

public class TestGroup
{
    public List<TestRowGroup> RowGroups { get; set; }
}

public class TestRowGroup
{
    public List<TestFieldRow> FieldRows { get; set; }
    public Guid RowGroupId { get; set; }

    public void AddFieldRow()
    {
        var newRow = new TestFieldRow
        {
            Fields = new List<TestFormField>()
        };
        newRow.FieldRowId = Guid.NewGuid();
        var fld = new TestFormField { FieldId = Guid.NewGuid() };
        newRow.Fields.Add(fld);
        FieldRows.Add(newRow);
    }
}

public class TestFieldRow
{
    public Guid FieldRowId { get; set; }
    public List<TestFormField> Fields { get; set; }                
}

public class TestFormField
{
    public Guid FieldId { get; set; }
    public string Value { get; set; }
}

查看:

@model FieldTest.Models.TestModel

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
</head>
<body>
    @using (Html.BeginForm("Submit", "Home", FormMethod.Post))
    {
        for (int g = 0; g < Model.Groups.Count; g++)
        {
            for (int rg = 0; rg < Model.Groups[g].RowGroups.Count; rg++)
            {
                for (int fr = 0; fr < Model.Groups[g].RowGroups[rg].FieldRows.Count; fr++)
                {
                    for (int f = 0; f < Model.Groups[g].RowGroups[rg].FieldRows[fr].Fields.Count; f++)
                    {
                        @Html.HiddenFor(model => model.Groups[g].RowGroups[rg].FieldRows[fr].Fields[f].FieldId)

                        @Model.Groups[g].RowGroups[rg].FieldRows[fr].Fields[f].Value
                        @Html.TextBoxFor(model => model.Groups[g].RowGroups[rg].FieldRows[fr].Fields[f].Value)

                        <button onclick="return confirm('Are you sure you would like to remove this row?');" type="submit" value="@string.Format("Del_{0}", Model.Groups[g].RowGroups[rg].FieldRows[fr].FieldRowId)" name="submit">Remove</button>
                        <hr />
                    }
                }
                <button type="submit" value="@string.Format("Add_{0}", Model.Groups[g].RowGroups[rg].RowGroupId)" name="submit">Add</button>
            }
        }
        <input type="submit" value="Submit" name="submit" />
    }
</body>
</html>

1 个答案:

答案 0 :(得分:0)

更重要的是,你确定这是一个EditorTemplate问题吗?如果您将代码放在主视图中,它是否也会发生?你试过吗?或者你认为这是一个EditorTemplate问题?

由于您忽略了为您的问题提供任何上下文,我们所能做的就是猜测。您很可能在后期操作中修改了视图模型的内容,现在很惊讶Html帮助程序使用旧值而不是模型中的值。

如果是这样,这是“按设计”,并且有详细记录(关于这个问题,已经有数百个问题已经出现在SO上)。在后期操作中,MVC助手更喜欢ModelState的内容而不是模型本身。您必须清除ModelState才能解决它。