Asp.net-Mvc

模型綁定在 MVC3 中找不到繼承的介面屬性,但在 MVC2 中工作正常

  • March 6, 2018

更新:問題已解決。

Darin Dimitrov 的回答包含指向另一個相關問題的連結。該頁面上提出的解決方案之一最終為我們工作。


原始問題

下面的程式碼範例在 MVC 2 中工作,但在 MVC 3 中引發異常。有誰知道為什麼 MVC 3 引入了這個重大更改?有沒有辦法讓它在 MVC 3 中工作,同時仍然允許我將視圖模型描述為視圖中的介面?

StackOverflow 上有另一個相關問題,但它沒有給我任何關於為什麼 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

幫助我們達林·季米特洛夫,你是我們唯一的希望。

我已經提請微軟注意這個問題。不幸的是,我得到的回應是:抱歉,這是設計使然。我個人從這樣的答案中得出的結論是 MVC 團隊正在設計一個有缺陷的產品,如果這是設計使然的話。他們不應該因為做出這樣的設計決定而受到責備,他們應該責怪在發行說明文件的重大更改部分中沒有提及它。如果他們提到了這一點,那麼即使我們故意知道重大變化,當我們做出遷移決定時也是我們的錯。

無論如何,這是一個相關的問題

這是 MVC 團隊的回答:

不幸的是,程式碼實際上利用了一個已修復的錯誤,即用於 ModelMetadata 目的的表達式容器被無意中設置為聲明類型而不是包含類型。由於需要虛擬屬性和驗證/模型元數據,因此必須修復此錯誤。

我們不鼓勵使用基於介面的模型(考慮到錯誤修復所施加的限制,我們也不可以實際支持)。切換到抽象基類可以解決這個問題。

我發現了一個可悲的解決方法,它允許您使用這個模型結構:

@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>

嗯。

引用自:https://stackoverflow.com/questions/8448917