如何在更新一小部分时在视图中保留复杂对象

EdB*_*EdB 10 asp.net-mvc xml-serialization asp.net-mvc-3

我觉得这可能是一个基本问题!

我有一个复杂的对象,即包含属性列表的文档对象.它是通过反序列化一些XML创建的.

我想将整个模型传递给View

Return ViewResult(MyDoc)
Run Code Online (Sandbox Code Playgroud)

在视图中编辑了一些属性.然后控制返回到后置控制器:

        [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(Document myDoc)
Run Code Online (Sandbox Code Playgroud)

"myDoc"现在只代表我的Form的字段.我怀疑这是ModelBinding在起作用.所以我想我需要将我的复杂对象保存在隐藏字段中(例如很棒)或者作为会话对象.但是我有点困惑我的更新字段如何合并回到持久对象(隐藏或会话).

Pab*_*meo 5

是否完全需要在视图中存储大对象?

View相比似乎没有该内容无法控制,所以你可能不希望所有的数据发送到View.看来你正在应用一个基于的思维模式ViewState,它与MVC,恕我直言不太匹配.

通信View和通信之间的通信Controller完成ViewModels,并且通常不需要存储任何大的序列化数据,并且在与服务器交互时来回传递.

你不能创建一个ViewModel只代表视图(字段)的有用数据,并Action通过ViewModel在POST期间接收到你的数据,然后将从View获得的信息与从XML加载的信息同步只在那个时候?

  • 嗨巴勃罗,这两个答案对我来说都是正确的,但我不能同时打勾.但是我已经标记了两个.非常感谢.埃德 (2认同)

Yan*_*net 3

你是对的,这就是模型绑定的作用。

当您使用 HtmlHelpers 时,绑定几乎自动发生,例如:

@Html.TextboxFor(model => model.PropertyName)
Run Code Online (Sandbox Code Playgroud)

这行代码实际上创建了一些类似这样的东西:

<input type="textbox" id="Modelobject_PropertyName" name="ModelObject.PropertyName" />
Run Code Online (Sandbox Code Playgroud)

然后,当您提交表单时,它DefaultModelBinder能够反序列化 POST 值并创建给定类型的对象(至少它会尝试),如果找不到相应的条目,则该属性将为 null,如果条目没有相应的属性,它将被忽略(除非你有其他参数)。

你可以阅读这篇文章,它有点旧,但仍然相当准确。

举个例子:

假设您有一个简单的对象:

public class IndexModel
{
    public string MyProperty { get; set; }
    public bool MyCheckbox { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

一个简单的控制器:

public class TestingController : Controller
{
    [OutputCache(Duration=0, NoStore = true)]
    public ActionResult Index()
    {
        return View(new IndexModel { MyProperty = "hi" });
    }

    [HttpPost]
    [OutputCache(Duration=0, NoStore = true)]
    public ActionResult Index(IndexModel model)
    {
        model.MyProperty += "!";
        ModelState.Clear();
        return View(model);
    }
}
Run Code Online (Sandbox Code Playgroud)

和一个简单的视图:

@model MvcApp.Models.IndexModel

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(model => model.MyProperty)<p />
        @Html.TextBoxFor(model => model.MyProperty) 
    </div>
    <div>
        @Html.LabelFor(model => model.MyCheckbox)<p />
        @Html.CheckBoxFor(model => model.MyCheckbox)
    </div> 

    <input type="submit" />
}
Run Code Online (Sandbox Code Playgroud)

当您提交表单时,您将看到模型已完全重新创建。

如果您不想显示属性的实际值,但仍需要保留它:

@Html.HiddenFor(model => model.MyProperty)
Run Code Online (Sandbox Code Playgroud)

这将生成一个隐藏字段,该字段将被回发并保留。

编码愉快!