【问题标题】:ASP MVC - Cast ViewModel Object to another typeASP MVC - 将 ViewModel 对象转换为另一种类型
【发布时间】:2016-01-26 12:27:33
【问题描述】:

我有一个这样的 ViewModel:

public class Column {

    public string Name;

    public string Type;

    public object Content;

}

Content 可以是 intstring... 根据 Type 我调用特定的 EditorTemplate : Column_int, Column_string...没问题。
不过,我确实有一个我也想使用的类型 GeoPoint,以及相应的 EditorTemplate Column_GeoPoint。问题是在我的控制器中,当我发布 ViewModel 时:

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

我得到一个演员表异常。
关于如何在 ViewModel 中将一个对象合并到另一个对象中的任何想法?

【问题讨论】:

  • 你可以用泛型代替对象
  • 您不想只制作 2 个编辑器模板吗? 1 表示 int 变量,1 表示字符串。
  • 我的意思是 2 个模型和 2 个编辑器模板。
  • @teovankot 为什么不呢?这似乎正是您想要做的事情。
  • 调试代码时,内容在强制转换失败之前的内容是什么?

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


【解决方案1】:

如果您收到符合您期望格式的正确数据,您需要提供自定义转换方法/帮助程序/扩展。

在此处查看如何编写自定义显式转换:https://msdn.microsoft.com/en-us/library/xhbhezf4.aspx

【讨论】:

    【解决方案2】:

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

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

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

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

    最好有多个视图模型,这样就没有未使用的属性(将来维护起来可能会令人困惑)——这是继承的完美案例。或者按照其他地方的建议使用该属性的泛型。

    【讨论】:

      【解决方案3】:

      您总是可以偷懒并在您的 Column 视图模型中添加一个 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 具有相同的结构。即使他们不这样做,也应该很容易看到如何修改此方法以允许这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-23
        • 2012-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-02
        • 2012-01-01
        相关资源
        最近更新 更多