Base View Page in ASP.NET MVC 6

In ASP.NET MVC 5, I used a basic ViewPage with several properties:

public String PageTitle { get; set; } public String PageDescription { get; set; } public String[] BodyCssClasses { get; set; } 

Then on each performance I would:

 @{ PageTitle = "Title ..." PageDescription" = "Description ..." BodyCssClasses = new String[] { "main", "home" } } 

On the main page, I would just use something like:

 <title>@Title</title> 

With this approach, I was able to use Strong Typed for page properties ...

Can I use the base view page in ASP.NET MVC 6?

Since there is no Web.Config, how can this be done?

Any suggestions on the best options for defining page information are welcome.

UPDATE

I followed the suggestion and I use:

 public abstract class ViewPageBase<TModel> : RazorPage<TModel> { public String Title { get; set; } } // ViewPageBase 

Then on _ViewImports I have:

 @inherits ViewPageBase<TModel> 

In _Layout.cshtml I have:

 <title>@Title</title> 

And finally, on the view that uses this layout, I:

 @{ Title = "Page Title"; Layout = "_Layout"; } 

Everything compiles and starts, but the page title is always empty.

Does anyone know why?

+7
asp.net-mvc asp.net-core-mvc
source share
3 answers

You probably want the base view page to inherit from RazorPage .

 public abstract class ViewPageBase<TModel> : RazorPage<TModel> { } 

You can then configure all your pages to inherit from this in the _ViewImports.cshtml file.

 @inherits ViewPageBase<TModel> 

UPDATE

Not sure if this is the best approach, but I'm wondering if you can use a generic ViewBag to exchange data between your view and layout.

Return the properties in the base page class using the ViewBag:

 public abstract class ViewPageBase<TModel> : RazorPage<TModel> { public string Title { get { return ViewBag.Title; } set { ViewBag.Title = value; } } } 

Set the property in your view:

 @{ Title = "Home Page"; } 

Use the property in _Layout.cshtml:

 <title>@Title</title> 
+3
source share

It looks like you are looking for the @inherits Razor directive.

For example:

@inherits MyBaseViewPage

+1
source share

The technique you described in your update will technically work.

Unfortunately, as @Peter notes, you get one instance of your custom ViewPage for presentation and another instance for layout. Since you are using two different instances, you cannot set a property in the view and expect access to this property in the layout. What is the answer to your updated question:

Everything compiles and starts, but the page title is always empty. Does anyone know why?

@Peter offers work using ViewBag . I would like to suggest an additional workaround using dependency injection.

For example, consider placing your own properties in your own class with your interface:

 public IPageMetaData { string PageTitle { get; set; } string PageDescription { get; set; } string[] BodyCssClasses { get; set; } } public PageMetaData : IPageMetaData { public string PageTitle { get; set; } public string PageDescription { get; set; } public string[] BodyCssClasses { get; set; } } 

Now register this with the .Net Core input infrastructure. Use the Scoped , so only one instance will be created for each web request. In a vanilla project, this happens in Startup.cs , in the ConfigureServices method:

 public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddScoped<IPageMetaData, PageMetaData>(); } 

Finally, update the _ViewImports.cshtml file to insert this object into your views:

 @inject Your.Namespace.Goes.Here.IPageMetaData MetaData; 

Your views will now have an ambient MetaData property that will correspond to an instance of each web request of the PageMetaData class. You can access it from both views and from the layout:

 @{ // In a view MetaData.PageTitle = "Set a page title"; } @* In a layout *@ <title>@MetaData.PageTitle</title> 
+1
source share

All Articles