ASP.NET MVC 3 HtmlHelper异常无法识别继承的接口上的ModelMetadata怎么办?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (31)

升级到MVC 3 RTM后,我得到一个以前的工作异常。

这是场景。我有几个对象使用相同的底层接口IActivity和IOwned。

IActivity implements IOwned (another interface)

public interface IActivity:IOwned {...}

public interface IOwned 
{
    int? AuthorId {get;set;}
}

我有一个局部视图,它使用IActivity从其他具体部分重用。

这是Activity Partial的定义。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IActivity>" %>
<%: Html.HiddenFor(item => item.AuthorId) %>

但是,它会引发异常。它无法在ModelMetadata中找到AuthorId。

我猜测在以前的版本中,它看着IActivity实现的接口。

任何想法,建议,缺乏在任何地方重复类似的接口?

复制下面的堆栈跟踪。

[ArgumentException: The property IActivity.AuthorId could not be found.]
   System.Web.Mvc.AssociatedMetadataProvider.GetMetadataForProperty(Func`1 modelAccessor, Type containerType, String propertyName) +498313
   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) +393
   System.Web.Mvc.Html.InputExtensions.HiddenFor(HtmlHelper`1 htmlHelper, Expression`1 expression, IDictionary`2 htmlAttributes) +57
   System.Web.Mvc.Html.InputExtensions.HiddenFor(HtmlHelper`1 htmlHelper, Expression`1 expression) +51
   ASP.views_shared_activity_ascx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\Users\...\Documents\Visual Studio 2010\Projects\ngen\trunk\...\Views\Shared\Activity.ascx:3
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
   System.Web.UI.Control.Render(HtmlTextWriter writer) +10
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
   System.Web.UI.Page.Render(HtmlTextWriter writer) +29
   System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +43
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060
提问于
用户回答回答于

在ASP.NET MVC 3中发生了一个突破性变化/错误,System.Web.Mvc.ModelMetadata. FromLambdaExpression它解释了所遇到的异常:

ASP.NET MVC 2.0:

...
case ExpressionType.MemberAccess:
{
    MemberExpression body = (MemberExpression) expression.Body;
    propertyName = (body.Member is PropertyInfo) ? body.Member.Name : null;
    containerType = body.Member.DeclaringType;
    flag = true;
    break;
}
...

ASP.NET MVC 3.0

...
case ExpressionType.MemberAccess:
{
    MemberExpression body = (MemberExpression) expression.Body;
    propertyName = (body.Member is PropertyInfo) ? body.Member.Name : null;
    containerType = body.Expression.Type;
    flag = true;
    break;
}
...

注意containerType变量是如何分配一个不同的值的。所以在你的情况下,在ASP.NET MVC 2.0中,它被分配了值IOwnedAuthorId属性正确的声明类型,而在ASP.NET MVC 3.0中,它被分配给IActivity框架,并且当框架试图找到它崩溃的属性时。

这是原因。就决议而言,我会等待微软的官方声明。在发行说明文档中我找不到任何有关此信息。这是一个错误还是一些需要在这里解决的功能

现在你可以使用非强类型的Html.Hidden("AuthorId")帮助器或者指定IOwned为控件的类型(我知道这两个都是吸)。

用户回答回答于

来自MVC团队:

不幸的是,代码实际上正在利用一个已修复的bug,其中ModelMetadata表达式的容器被无意​​中设置为声明类型而不是包含类型。由于虚拟属性和验证/模型元数据的需要,此错误必须修复。 拥有基于接口的模型并不是我们所鼓励的(也没有考虑到错误修复带来的限制,可以切实支持)。切换到抽象基类将解决问题。

扫码关注云+社区