2011-12-15 64 views
1

信息,我有一个很大的对象,我使出使用@Html.Serialize()序列化:TryUpdateModel包含列表的模型去除模型

[Serializable] 
public class ModelB 
{ 
    public List<ModelA> ListOfModelA { get; set; } 
    // more stuff 
} 

该对象包含从包含几个属性的类对象的列表。其中一些我包括他们在我看来,而其他人我甚至懒得把他们作为隐藏的领域,因为我有他们在我的序列化模型。

[Serializable] 
public class ModelA 
{ 
    public string StringA { get; set; } 
    public string StringB { get; set; } 
    // more stuff 
    public string HiddenStringA { get; set; } 
    public string HiddenStringB { get; set; } 
    // more stuff 
} 

现在,当我回来后与我的变更形式我reconstract我的模型,然后我用从形式获得的值的字典更新。

[HttpPost] 
public ActionResult Edit([Deserialize] ModelTwo model, 
         FormCollection form) 
{ 
    TryUpdateModel(model, form.ToValueProvider()); 

    // more stuff 
} 

我踩在我的代码,我做了更新之前,我看到我的反序列化的模型包含一个列表ListOfModelA,里面包含了应该在那里的所有元素,并在他们,我可以看到所有的HiddenStringA和HiddenStringB属性。然后我偷看形式里面,我看到这样的与键的字典:

ListOfModelA[0].StringA 
ListOfModelA[0].StringB 
ListOfModelA[1].StringB 
ListOfModelA[1].StringB 

同时也有针对性质的这样一个休息NO键:

ListOfModelA[0].HiddenStringA 

接下来,我动一个更进一步,我让代码执行TryUpdateModel。现在,查看ListOfModelA属性的内部,所有元素都被替换为所有隐藏值为空的新元素。这就好像更新重建了整个元素(只有有限的信息),而不是只更新其拥有信息的属性。

这是预期的行为?有没有办法保持我的模型,并只更新字典中有键的属性?

感谢,

帕诺斯

回答

0

我的问题比上述的一个更复杂的,但我发现的具体设计solultion是大致如下。我将模型的一部分作为列表序列化,并通过动作的参数绑定整个模型。这样我就可以避免使用TryUpdateModel,尽管这不是导致我麻烦的原因。然后,我从表单创建的模型中将非空值插入到反序列化模型中,最后我将后者的相应部分指向前者。

[HttpPost] 
public ActionResult Edit(ModelTwo model, 
         [Deserialize] List<ModelA> serializedList) 
{ 
    serializedList.InjectFrom<NonNullLoopValueInjection>(model.ListOfModelA); 
    model.ListOfModelA = serializedList; 

    // more stuff 
} 

对于注射,我用Value Injecter其中NonNullLoopValueInection定义如下

public class NonNullLoopValueInjection : LoopValueInjection 
{ 
    protected override bool AllowSetValue(object value) 
    { 
     return value != null; 
    } 
} 

也许不是最好的设计,但它的工作,它可能会导致我更好的东西。任何反馈都是值得欢迎的。