Adding Custom attributes to the page directive in asp.net-mvc
I have created a base class that derives from ViewPage with a custom public attribute that I want to be able to set in the @page directive however I am getting the following error.
Error 24 Error parsing attribute 'attrame': Type 'System.Web.Mvc.ViewPage' does not have a public property named 'attrname'.
the directive looks as so
<%@ Page Title="" Language="C#" AttrName="Test" Inherits="Web.Helpers.Views.BaseViewPage" %>
The problem seems to be that it doesn't recognize the base class from the Inherits tag. I thought this should work from reading around on the internet. Has开发者_如何学Go anyone else tried this or have any idea why this isn't working?
This is unfortunately not supported in ASP.NET MVC 1.0 or ASP.NET MVC 2.
The reason for this is an implementation detail of some MVC-specific parser logic that is used in ASPX/ASCX/MASTER files. If the view page's (or view master page's or view user control's) base type is a generic type there is logic that hard-codes the base class for the ASP.NET parser's sake to be just regular ViewPage (or ViewMasterPage or ViewUserControl).
Because the ASP.NET parser looks at the base class that MVC tells is, it will only ever be ViewPage, and thus it doesn't recognize the new property that you added, and thus it reports an error.
It is worth mentioning that this applies only if the base class you specify in the view page is generic. If you use a non-generic type then it should work just fine and you should be able to set values on custom properties.
I can think of two workarounds:
1) Create custom page base types for every type you need. This solution is rather easy, though cumbersome:
public class MyBasePage<TModel> : ViewPage<TModel> {
...
}
public class CustomerPage : MyBasePage<Customer> { }
public class ProductPage : MyBasePage<Product> { }
And then use only the non-generic derived types in the view pages' "inherits" attribute.
2) Copy the MVC source code (see links below) from the ViewTypeParserFilter
into your project and make some small changes. The key method to change is the PreprocessDirective()
method. Towards the bottom is an if() statement that overrides the "inherits" attribute to be one of a few hard-coded values. As you'll see, this code runs only if the declared base type is generic (hence my earlier comment).
It's up to you to decide exactly how you want to change this code. The key thing here is that the type name must be a type that .NET's Type.GetType() method can understand. That is, you have to use the CLR syntax for constructs such as generics and not the C# or VB syntax. For example, while in C# you can say:
System.Web.Mvc.ViewPage<Customer>
In the CLR syntax it's something like:
System.Web.Mvc.ViewPage`1[MyApp.Models.Customer]
Hopefully one of the two options above suits you.
Source code links:
- ASP.NET MVC 1.0 source code download
- ASP.NET MVC 2 RC source code
You need to set the base type in the web.config to get around this. Go to
/Views/Web.config
and change the
configuration/system.web/pages
and change the attribute pageBaseType
to your class.
<pages pageBaseType="Web.Helpers.Views.BaseViewPage" {your other attributes here} />
精彩评论