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

时间:2022-10-16 04:09:56

I have a feeling this could be a basic question!

我有一种感觉,这可能是一个基本问题!

I have a complex object ie a document object which contains properties that are lists of other objects. It has been created by deserializing some XML.

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

I would like to pass the entire Model to the View

我想将整个模型传递给View

Return ViewResult(MyDoc)

In the View some properties are edited. Control is then returned back to the Post Controller:

在视图中编辑了一些属性。然后将控制权返回给后置控制器:

        [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(Document myDoc)

"myDoc" now just represents my Form's fields. I suspect this is ModelBinding at work. So I guess I need to persist my complex object in a hidden field(example would be great) or as a session object. However I am a bit confused how my updated field gets merged back into the persisted object(hidden or session).

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

2 个解决方案

#1


3  

You are right, this is model binding at work.

你是对的,这是工作中的模型绑定。

The binding occurs almost automatically when you use HtmlHelpers such as :

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

@Html.TextboxFor(model => model.PropertyName)

This line actually creates something a little bit like this :

这条线实际上创造了一些像这样的东西:

<input type="textbox" id="Modelobject_PropertyName" name="ModelObject.PropertyName" />

Then when you submit your form, the DefaultModelBinder is able to deserialize the POST value and create and object of the given type (at least it will try), if it can't find a corresponding entry, the property will be null and if an entry have no corresponding property, it will be ignored (unless you have other parameters).

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

You can read this article it's a little bit old, but it's still pretty accurate.

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

As an exemple:

作为例子:

Let's say you have a simple object :

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

public class IndexModel
{
    public string MyProperty { get; set; }
    public bool MyCheckbox { get; set; }
}

A simple controler :

一个简单的控制器:

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);
    }
}

And a simple view :

一个简单的观点:

@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" />
}

You will see, when you submit the form, that the model is recreated completely.

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

If you don't want to display the actual value of a property, but still need it persisted:

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

@Html.HiddenFor(model => model.MyProperty)

This will generate a hidden field that will be posted back and, therefor, persisted.

这将生成一个隐藏的字段,该字段将被回发并因此保持不变。

Happy coding !

快乐的编码!

#2


5  

Is storing that large object in the view entirely necessary?

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

The View seems to have no control over that content, so you probably don't want to send all that data to the View. It seems you are applying a mind-set based on ViewState, which doesn't really fit very well with MVC, IMHO.

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

Communication between the View and the Controller is done through ViewModels, and there's usually no need to store any large serialized data and making that go back and forth when interacting with the server.

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

Can't you create a ViewModel that represents only the useful data for the view (the fields), and get that data back in your Action by receiving the ViewModel during POST, and afterwards synchronize the information you obtained from the View with what you load from your XML only at that time?

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

#1


3  

You are right, this is model binding at work.

你是对的,这是工作中的模型绑定。

The binding occurs almost automatically when you use HtmlHelpers such as :

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

@Html.TextboxFor(model => model.PropertyName)

This line actually creates something a little bit like this :

这条线实际上创造了一些像这样的东西:

<input type="textbox" id="Modelobject_PropertyName" name="ModelObject.PropertyName" />

Then when you submit your form, the DefaultModelBinder is able to deserialize the POST value and create and object of the given type (at least it will try), if it can't find a corresponding entry, the property will be null and if an entry have no corresponding property, it will be ignored (unless you have other parameters).

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

You can read this article it's a little bit old, but it's still pretty accurate.

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

As an exemple:

作为例子:

Let's say you have a simple object :

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

public class IndexModel
{
    public string MyProperty { get; set; }
    public bool MyCheckbox { get; set; }
}

A simple controler :

一个简单的控制器:

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);
    }
}

And a simple view :

一个简单的观点:

@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" />
}

You will see, when you submit the form, that the model is recreated completely.

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

If you don't want to display the actual value of a property, but still need it persisted:

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

@Html.HiddenFor(model => model.MyProperty)

This will generate a hidden field that will be posted back and, therefor, persisted.

这将生成一个隐藏的字段,该字段将被回发并因此保持不变。

Happy coding !

快乐的编码!

#2


5  

Is storing that large object in the view entirely necessary?

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

The View seems to have no control over that content, so you probably don't want to send all that data to the View. It seems you are applying a mind-set based on ViewState, which doesn't really fit very well with MVC, IMHO.

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

Communication between the View and the Controller is done through ViewModels, and there's usually no need to store any large serialized data and making that go back and forth when interacting with the server.

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

Can't you create a ViewModel that represents only the useful data for the view (the fields), and get that data back in your Action by receiving the ViewModel during POST, and afterwards synchronize the information you obtained from the View with what you load from your XML only at that time?

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