ASP MVC - 将ViewModel对象转换为另一种类型

时间:2016-01-26 12:27:33

标签: c# asp.net asp.net-mvc

我有一个像这样的ViewModel:

public class Column {

    public string Name;

    public string Type;

    public object Content;

}

内容可以是 int 字符串 ...根据类型,我调用特定的EditorTemplate : Column_int Column_string ......没问题。
但是,我确实有一个 GeoPoint 类型,我想使用相应的EditorTemplate Column_GeoPoint 。问题是在我的控制器中,当ViewModel被发布时,我这样做:

GeoPoint geoPoint = ((GeoPoint) mViewModel.Content);

我得到了施法例外。
关于如何在ViewModel中将对象合并到另一个对象中的任何想法?

3 个答案:

答案 0 :(得分:0)

如果您收到预期格式的正确数据,则需要提供自定义强制转换方法/帮助/扩展。

请参阅此处如何编写自定义显式广播:https://msdn.microsoft.com/en-us/library/xhbhezf4.aspx

答案 1 :(得分:0)

默认模型绑定器无法通过GeoPoint将对象转换为cast。我之前没有使用GeoPoint,但快速谷歌没有显示如何从字符串轻松转换,如果您的编辑正确处理它可能不相关

您需要正确/手动(通过代码)进行转换。

您最好的选择是始终使用 viewmodel 中的正确的强类型,即:

public class ColumnViewModel {
    public string Name;
    public string Type;
    public string ContentString;
    public int ContentInt;
    public GeoPoint ContentGeoPoint;
}

即不要使用弱类型,模糊的"对象"属性处理不同的场景。

然后将其映射到控制器中的DTO:

public class Column {
    public string Name;
    public string Type;
    public object Content;
}

public ActionResult PostAction(ColumnViewModel model)
{
    var dto = new Column();
    switch (model.Type)
    {
        case "int": 
            dto.Content = dto.ContentInt;

        case "geo": 
            dto.Content = dto.ContentGeoPoint;
            break;

       // etc
    }
}

最好有多个视图模型,因此没有未使用的属性(将来可能会令人困惑) - 一个完美的继承案例。或者在其他地方建议使用泛型作为此属性。

答案 2 :(得分:0)

您可以始终保持懒惰,并在Column viewmodel中添加ToGeoPoint()方法。

看起来像是:

public class Column {

    public string Name;

    public string Type;

    public object Content;

    public GeoPoint ToGeoPoint() {
        GeoPoint point = new GeoPoint();
        point.Name = this.Name;
        point.Type = this.Type;
        point.Content = this.Content;
        return point;
    }

}

当然,这假设GeoPoint和Column具有相同的结构。即使它们没有,也应该很容易看到如何修改此方法以实现这一点。