Использование типа значения в строго типизированном пользовательском элементе управления MVC view

У меня есть пользовательский элемент управления MVC со следующей базовой структурой:

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

<%= Math.Round(Model) %>

Что дает это сообщение об ошибке, когда я его использую:

Сообщение об ошибке компилятора: CS0452: тип "десятичный" должен быть ссылочным типом, чтобы использовать его в качестве параметра "TModel" в универсальном типе или методе "System.Web.Mvc.ViewUserControl".

Есть ли способ заставить это работать (каким-то образом обманывая фреймворк в трактовку десятичной дроби как ссылочного типа?) Или то, что я пытаюсь сделать, в корне неверно?

7 ответов

Решение

Я бы посоветовал вам обернуть тип значения в ViewModel. Это даст некоторую гибкость в будущем (что может или не может быть необходимо).

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) %>

Не нужно переходить в класс, если вы хотите быстрый путь, используйте это

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

Также вы можете рассмотреть вопрос об использовании

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

и подтвердить по коду

ViewUserControl объявляется следующим образом:

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

Таким образом, вы не можете обмануть его в компиляции с типом значения. Я бы рекомендовал обернуть Decimal объект в другом классе.

Вы можете обернуть значение в классе:

 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) %>

Модель представляет собой DTO от контроллера до представления. Вы должны создать свой собственный DTO даже с одним десятичным свойством. Ответственность за представление заключается только в рендеринге, Math.Round должен выполняться контроллером.

Хотя я решительно поддерживаю все ответы, приведенные выше, заявив, что нужно обернуть десятичное значение в классе для поддержки дальнейшего развития, вы можете быстро решить свою проблему, сделав десятичное число обнуляемым ("десятичное?"), Поскольку System.Nullable является ссылочным типом.

Я не очень знаком с ASP.Net MVC Framework, но ошибка в том, что ваша модель должна быть классом, а не примитивным типом, что довольно стандартно с точки зрения контроллера представления модели.

Чтобы это сработало, вам понадобится такой класс:

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

а затем заменить вашу строку с <%= Math.Round(Model.TheValue) %>,

Обратите внимание, странный дизайн, когда пользовательский элемент управления имеет двойное значение. Если это просто пример приложения, тогда хорошо, но в противном случае вы можете пересмотреть, как наилучшим образом использовать пользовательские элементы управления.

Другие вопросы по тегам