Использование типа значения в строго типизированном пользовательском элементе управления 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) %>
,
Обратите внимание, странный дизайн, когда пользовательский элемент управления имеет двойное значение. Если это просто пример приложения, тогда хорошо, но в противном случае вы можете пересмотреть, как наилучшим образом использовать пользовательские элементы управления.