问题
I'm currently creating a CMS system and found that the following doesn't work.
I do have a work around that isn't exactly ideal and feels dirty. I'm cool with it for now and not really that interested in a different approach (but don't let that stop you answering). What I am after is some kind of explaination on why it doesn't work - is it a bug in ASP.NET MVC?
It's hard to explain so I'll let my code (minus alot of fluff) do the talking... hope it makes sense!
EDIT: It seems that the compiler totally ignores the second masterpage's 'inherits' attribute - see at the bottom of the question.
ContentViewData.cs - notice it inherits from BaseViewData
public class ContentViewData : BaseViewData
{
public MyCMS.Data.Models.Content ContentItem { get; set; }
}
Site.Master - Notice the strongly typed viewdata of type BaseViewData
<%@ Master
Language="C#"
Inherits="System.Web.Mvc.ViewMasterPage<MyCMS.WebSite.ViewData.BaseViewData>" %>
Content.Master - Notice the strongly typed viewdata of type ContentViewData and the fact that it's a child masterpage of Site.Master
<%@ Master
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewMasterPage<MyCMS.WebSite.ViewData.ContentViewData>" %>
...blah blah blah...
<% Html.RenderPartial("ContentItemImage", Model.ContentItem); %>
ContentItemImage.ascx
<%@ Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<MyCMS.Data.Models.Content>" %>
<% if (Model.HasPrimaryPhoto)
{ %>
<img src="/content/photos/<%= Model.GetPrimaryPhoto.ThumbFileName %>"
title="<%= Model.GetPrimaryPhoto.Caption %>" />
<% } %>
Now inside the Content.Master if I try and render the ContentItemImage partial and refer to a property on the ContentViewData object (specifically the 'ContentItem' property) like I have - repeated below.
<% Html.RenderPartial("ContentItemImage", Model.ContentItem); %>
If falls over on that line with the following error
Compilation Error
CS1061: 'object' does not contain a definition for 'ContentItem' and no extension method 'ContentItem' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
BUT if I change things up like so, it all works fine and dandy.
Content.Master - Notice I'm passing into RenderPartial() the whole Model (ContentViewData object) rather than trying to refer to a property on the ContentViewData object
<%@ Master
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewMasterPage<MyCMS.WebSite.ViewData.ContentViewData>" %>
...blah blah blah...
<% Html.RenderPartial("ContentItemImage", Model); %>
ContentItemImage.ascx - notice the changed strongly typed viewdata from MyCMS.Data.Models.Content to the ContentViewData class.
<%@ Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<MyCMS.WebSite.ViewData.ContentViewData>" %>
<% if (Model.ContentItem.HasPrimaryPhoto)
{ %>
<img src="/content/photos/<%= Model.ContentItem.GetPrimaryPhoto.ThumbFileName %>"
title="<%= Model.ContentItem.GetPrimaryPhoto.Caption %>" />
<% } %>
So yeah, that works but it aint go not alibi.
Thanks in advance, Charles.
EDIT: Interestingly it seems that the compiler totally ignores the second master page's 'inherits' attribute.
Eg. I can do this and it still compiles without a complaint...
<%@ Master
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewMasterPage<ThisDoesntExist.AtAll>" %>
回答1:
Interesting...A resonable guess would be that your ContentViewData object is being upcast to BaseViewData due to some interaction with your nested master page (if that is indeed the case, someone else will need to weigh in as to why).
You could verify trying this:
<% Html.RenderPartial("ContentItemImage", ((MyCMS.WebSite.ViewData.ContentViewData)Model).ContentItem); %>
The reason your workaround "works" is because your partial view is typed for ContentViewData, so when you pass in Model it is downcast to that type.
回答2:
As you can see from my edit, it seems that the compiler totally ignores the nested master page's 'inherits' attribute.
This leads me to believe that a nested masterpage in ASP.NET MVC will always inherit from it's parent masterpage and as I've witnessed, totally ignore the inherits attribute.
EDIT: There must be some magic going on here... If I remove the 'inherits' attribute it won't compile because it doesn't know about the HtmlHelper class. But if I have the 'inherits' attribute in there with garbage inside it, it does compile.
Doesn't work
<%@ Master
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master" %>
Does work
<%@ Master
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="Sysasfdaasdtem.Web.Mvsdfc.ViewMasterPage<ThisDoesntExist.AtAll>" %>
Very odd indeed.
回答3:
Just try to do the next thing:
<%@ Master
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewMasterPage<MyCMS.WebSite.ViewData.ContentViewData>" %>
...blah blah blah...
<%= string.Empty %>
...blah blah blah...
<% Html.RenderPartial("ContentItemImage", Model.ContentItem); %>
Don't ask anything, just try to put <%= string.Empty %> in your master page's code and then use your strongly typed Model property.
来源:https://stackoverflow.com/questions/928911/strongly-typed-master-pages-polymorphism-nested-masterpages-ignore-inherit-att