Darin Dimitrov的答案包含另一个相关问题的链接。该页面上的One of the proposed solutions最终为我们工作。
下面的代码示例适用于MVC 2但在MVC 3中引发异常。有谁知道为什么MVC 3引入了这个突破性的变化?有没有办法让这个在MVC 3中工作,同时仍允许我在视图中将视图模型描述为一个接口?
StackOverflow上还有另一个related question,但它没有告诉我为什么MVC 2和MVC 3之间存在差异。
模型
public interface IPerson {
string Name { get; set; }
}
public interface ISpy : IPerson {
string CodeName { get; set; }
}
public class Spy : ISpy {
public string Name { get; set; }
public string CodeName { get; set; }
}
控制器操作
public ActionResult Index() {
var model = new Spy { Name = "James Bond", CodeName = "007" };
return View(model);
}
MVC2查看(完美运作)
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcApp.Models.ISpy>" %>
<p>CodeName: <%: Html.TextBoxFor(x => x.CodeName) %></p>
<p>Name: <%: Html.TextBoxFor(x => x.Name) %></p>
MVC3查看(抛出异常)
@model MvcApp.Models.ISpy
<p>Name: @Html.TextBoxFor(x => x.Name)</p>
<p>CodeName: @Html.TextBoxFor(x => x.CodeName)</p>
MVC3异常信息
我在下面显示了相关的异常信息,但您可以在此处查看错误页面的整个输出:https://gist.github.com/1443750。
Runtime Exception
System.ArgumentException: The property **`MvcApp.Models.ISpy.Name`** could not be found.
Source Error:
Line 1: @model MvcApp.Models.ISpy
Line 2: <p>CodeName: @Html.TextBoxFor(x => x.CodeName)</p>
Line 3: <p>Name: @Html.TextBoxFor(x => x.Name)</p>
Stack Trace:
[ArgumentException: The property MvcApp.Models.ISpy.Name could not be found.]
System.Web.Mvc.AssociatedMetadataProvider.GetMetadataForProperty(Func`1 modelAccessor, Type containerType, String propertyName) +502169
System.Web.Mvc.ModelMetadata.GetMetadataFromProvider(Func`1 modelAccessor, Type modelType, String propertyName, Type containerType) +101
System.Web.Mvc.ModelMetadata.FromLambdaExpression(Expression`1 expression, ViewDataDictionary`1 viewData) +421
System.Web.Mvc.Html.InputExtensions.TextBoxFor(HtmlHelper`1 htmlHelper, Expression`1 expression, IDictionary`2 htmlAttributes) +58
System.Web.Mvc.Html.InputExtensions.TextBoxFor(HtmlHelper`1 htmlHelper, Expression`1 expression) +50
ASP._Page_Views_Home_Index_cshtml.Execute() in c:\Projects\MvcApplication1\MvcApplication1\Views\Home\Index.cshtml:3
帮助我们Darin Dimitrov,你是我们唯一的希望。
答案 0 :(得分:9)
我已经brought this issue引起了微软的注意。不幸的是,我得到的回答是:抱歉这是设计上的。就个人而言,我从这样的答案得出的结论是,MVC团队正在设计一个有缺陷的产品,如果这是设计的话。并且他们不应该因为做出这样的设计决定而受到指责,他们是因为在发行说明文档的重大变更部分中没有任何提及它而受到指责。如果他们提到它,那么即使我们故意了解这一突破性的变化,当我们做出迁移决定时,这也是我们的错。
无论如何,这是一个related question。
这是MVC团队的回答:
不幸的是,代码实际上正在利用已修复的错误, 用于ModelMetadata目的的表达式的容器 无意中设置为声明类型而不是包含 类型。由于虚拟的需要,必须修复此错误 属性和验证/模型元数据。
基于界面的模型不是我们鼓励的(也不是 鉴于错误修复所施加的限制,可以实际地进行 支持)。切换到抽象基类可以解决问题。
答案 1 :(得分:0)
更改此行:
@model MvcApp.Models.ISpy
要
@model MvcApp.Models.Spy
答案 2 :(得分:0)
我找到了一个可怜的解决方法,允许您使用此模型结构:
@model MvcApp.Models.IPerson
<p>Name: @Html.TextBoxFor(x => x.Name)</p>
@Html.Partial('_SpyBox')
在_SpyBox.cshtml中
@model MvcApp.Models.ISpy
<p>CodeName: @Html.TextBoxFor(x => x.CodeName)</p>
咩。