代码之家  ›  专栏  ›  技术社区  ›  kristian

在强类型MVC视图用户控件中使用值类型

  •  4
  • kristian  · 技术社区  · 15 年前

    我有一个具有以下基本结构的MVC用户控件:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Decimal>" %>
    
    <%= Math.Round(Model) %>
    

    当我使用它时,它会给出这个错误消息:

    编译器错误消息:CS0452: 类型“decimal”必须是引用 键入以用作参数 泛型类型或方法中的“tmodel” 'system.web.mvc.viewUserControl'

    有没有一种方法可以使这个方法起作用(可能会以某种方式诱使框架将十进制视为引用类型?)或者我想做的是根本错误的?

    7 回复  |  直到 14 年前
        1
  •  8
  •   Jon Erickson    15 年前

    我建议您将值类型包装在一个视图模型中。这将为将来提供一些灵活性(可能需要,也可能不需要)。

    public class MyUserControlViewModel
    {
        public Decimal MyValue { get; private set; }
    
        public MyUserControlViewModel(Decimal dec)
        {
            MyValue = dec;
        }
    }
    
    
    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyUserControlViewModel>" %>
    
    <%= Math.Round(Model.MyValue) %>
    
        2
  •  5
  •   user543518    14 年前

    不必全神贯注地上课,如果你想快点,就用这个

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Nullable<Decimal>>" %>
    

    你也可以考虑使用

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>
    

    并通过代码验证

        3
  •  3
  •   John G    15 年前

    ViewUserControl 声明如下:

    public class ViewUserControl<TModel> : ViewUserControl
    where TModel : class
    

    因此,您不能欺骗它使用值类型进行编译。我建议把你的 Decimal 其他类中的对象。

        4
  •  2
  •   user434917    15 年前

    可以将值包装在类中:

     public class Wrapper
    {
            public Wrapper(decimal d)
            {
                this.Value = d;   
            }
            Decimal Value { get; set; }
    }
    

    观点:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Wrapper>" %>
    <%= Math.Round(Model.Value) %>
    
        5
  •  1
  •   Andrea Balducci    15 年前

    模型是从控制器到视图的DTO。即使只有一个十进制属性,也应该创建自己的DTO。视图的职责只是渲染,Math.Round应该由控制器执行。

        6
  •  0
  •   Tim Hoolihan    15 年前

    我对ASP.NET MVC框架不太熟悉,但错误是您的模型必须是类,而不是基本类型,从模型视图控制器的角度来看,这是相当标准的。

    要使其发挥作用,您需要一个类,如:

    class MyDouble : Model   // or whatever MVC calls it's Model
    {
       public TheValue {
         get;
         set;
       }
    }
    

    然后将您的行替换为 <%= Math.Round(Model.TheValue) %> .

    注意,只有一个双值的自定义控件似乎是一种奇怪的设计。如果这只是一个示例应用程序,那么很好,但是如果不是这样,您可能需要重新考虑如何最好地使用自定义控件。

        7
  •  0
  •   Andrei Rînea    15 年前

    虽然我强烈支持上面的所有答案,但是声明要将十进制值包装在一个类中以支持进一步的开发,您可以通过使decimal可以为空(“decimal?”)来快速解决您的问题。因为System.Nullable是引用类型。