我最近遇到了ASP.NET MVC显示模板的问题.说这是我的模特:
public class Model { public int ID { get; set; } public string Name { get; set; } }
这是控制器:
public class HomeController : Controller { public ActionResult Index() { return View(new Model()); } }
这是我的看法:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<DisplayTemplateWoes.Models.Model>" %> <!DOCTYPE html> <html> <head runat="server"> <title>Index</title> </head> <body> <div> <%: Html.DisplayForModel() %> </div> </body> </html>
如果我出于某种原因需要所有字符串的显示模板,我将创建一个String.ascx局部视图,如下所示:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %> <%: Model %> (<%: Model.Length %>)
这是问题 – 在运行时抛出以下异常:
“传入字典的模型项的类型为’System.Int32′,但此字典需要’System.String’类型的模型项”
似乎String.ascx用于Model类的整数和字符串属性.我希望它只用于字符串属性 – 毕竟它被命名为String.ascx而不是Object.ascx或Int32.ascx.
这是设计的吗?如果是的话 – 是否在某处记录了?如果不是 – 它可以被视为一个错误吗?
解决方法
这似乎是设计上的.您将不得不使字符串模板更通用.字符串模板作为每个没有自己模板的非复杂模型的默认模板.
字符串的默认模板(FormattedModelValue是object):
internal static string StringTemplate(HtmlHelper html) { return html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue); }
模板选择如下所示:
foreach (string templateHint in templateHints.Where(s => !String.IsNullOrEmpty(s))) { yield return templateHint; } // We don't want to search for Nullable<T>,we want to search for T (which should handle both T and Nullable<T>) Type fieldType = Nullable.GetUnderlyingType(Metadata.RealModelType) ?? Metadata.RealModelType; // TODO: Make better string names for generic types yield return fieldType.Name; if (!Metadata.IsComplexType) { yield return "String"; } else if (fieldType.IsInterface) { if (typeof(IEnumerable).IsAssignableFrom(fieldType)) { yield return "Collection"; } yield return "Object"; } else { bool isEnumerable = typeof(IEnumerable).IsAssignableFrom(fieldType); while (true) { fieldType = fieldType.BaseType; if (fieldType == null) break; if (isEnumerable && fieldType == typeof(Object)) { yield return "Collection"; } yield return fieldType.Name; } }
因此,如果您只想为字符串创建模板,您应该这样做(String.ascx):
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<object>" %> <% var model = Model as string; %> <% if (model != null) { %> <%: model %> (<%: model.Length %>) <% } else { %> <%: Model %> <% } %>