加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – MVC ViewModel绑定构造与展平

发布时间:2020-12-15 23:57:44 所属栏目:asp.Net 来源:网络整理
导读:在我的ViewModel中(也在我的域模型中),我有一个动态的属性结构,其中Profile元素是基类ProfileVM的List并引用ProfileDefinitionElement(只是为了解释ViewModel而不粘贴整个东西). public class OwnProfileVM{ public OwnProfileVM() {} public ProfileDefinit
在我的ViewModel中(也在我的域模型中),我有一个动态的属性结构,其中Profile元素是基类ProfileVM的List并引用ProfileDefinitionElement(只是为了解释ViewModel而不粘贴整个东西).
public class OwnProfileVM
{
    public OwnProfileVM() {}
    public ProfileDefinitionVM ProfileDefinitionVM { get; set; }
    public ProfileVM ProfileVM { get; set; }
}

所以我使用Linq Single语句绑定我的属性:

@Model.ProfileDefinitionVM.ProfileElementDefinitions.Single(p => p.Key == ProfileElementKey.CompanyName.ToString()).Title

这适用于显示数据.但是当这样回帖时:

@Html.TextBoxFor(model => ((ProfileElementTextVM)model.ProfileVM.ProfileElements
            .Single(p=> p.ProfileElementDefinition.Key == ProfileElementKey.CompanyName.ToString()))
            .Text

..模型属性为null.
这是因为无参数构造函数构建了OwnProfileVM对象而没有填充任何属性.

经过一些研究,我发现有两种方法可以解决这个问题:

>“展平”ViewModel.所以我会为每个Profile Element提供一个固定的属性.这可行,但缺点是我无法使用Automapper映射数据.我必须“手动”将ViewModel填充到模型中.这将导致Controller中的代码更多,并且“更大”,但更简单的ViewModel.见于this article
>找到一种方法将定义数据传递给ViewModel构造函数,以便在回发之前构建属性列表.

现在我的问题:

>第二种方式是否可行,如果是,将如何做?我还没有办法做到这一点.
>如果第一个问题可以回答是,您更喜欢哪种方式?

解决方法

看起来很复杂最好简化一下.

根据我的经验,控制器中的模型属性为null,因为绑定器无法理解如何将表单元素名称与关联的属性相关联.例如,我已经看到了使用foreach的列表:

(model has a) List<Something> Somethings.....

foreach (Something thing in Model.Somethings)
{
    @Html.EditorFor(m => thing)
}

这在生成的html中呈现为< input name =“thing”.....这是无用的.这里的解决方案是使用for循环并通过其路径访问模型的属性,而不是复制指向实例的指针,例如:

for (int i = 0; i < Model.Somethings.Count; i++)
{
    @Html.EditorFor(m => Model.Somethings[i])
}

然后用正确的< input name =“Model.Somethings [i]”.....渲染,并且模型绑定器将理解它. 我希望你在这里遇到的这个问题是类似的.您需要向属性添加必要的访问器,以便在视图中呈现正确的名称和ID,并由绑定器选取. 我不确定你班级的确切定义,所以这个例子不太可能完全正确. 这个类包含一个this [string index]方法,它将使用你的属性键作为索引来获取和设置元素:

public class ProfileElements : List<ProfileElement>
{
    public ProfileElement this[string index]
    {
        get
        {
            return base.First(p => p.ProfileElementDefinition.Key == index);
        }
        set
        {
            base[index] = value;
        }
    }
}

在您看来,您可以使用以下内容:

@Html.TextBoxFor(model => model.ProfileVM.ProfileElements[ProfileElementKey.CompanyName.ToString()].Text)

希望这能满足您的需求.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读