Base View Page in ASP.NET MVC 6

落花浮王杯 提交于 2019-12-06 23:49:27

问题


On ASP.NET MVC 5 I used a base ViewPage with a few properties:

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

Then on each view I would have:

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

On the master page I would simply use something like:

<title>@Title</title>

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

Is it possible to use a Base View Page in ASP.NET MVC 6?

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

Any suggestions for better options to define page head info is welcome.

UPDATE

I followed the suggested and I am using:

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

Then on _ViewImports I have:

@inherits ViewPageBase<TModel>

On _Layout.cshtml I have:

<title>@Title</title>

And finally on a view which uses that layout I have:

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

Everything compiles and runs but the page title is always empty.

Does anyone has any idea why?


回答1:


You'll probably want to make your base view page inherit from RazorPage.

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

Then you should be able to 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 wonder if you could use the common ViewBag to share data between your View and the Layout.

Back the properties in your base page class with 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>



回答2:


The technique you have described in your update will technically work.

Unfortunately, as @Peter notes, you get one instance of your custom ViewPage for the view, and a different instance for the layout. Because you are using two different instances, you cannot set a property on the view and expect to access that property on the layout. That's the answer to your updated question:

Everything compiles and runs but the page title is always empty. Does anyone has any idea why?

@Peter has offered a work around using the ViewBag. I'd like to offer an additional workaround using dependency injection.

For instance, consider placing your custom properties in their own class, with its own 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 dependency injection framework. Use the Scoped lifecycle, so only one instance will be created per-web request. In a vanilla project, this takes place in Startup.cs, in the ConfigureServices method:

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

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

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

Now your views will have a ambient MetaData property that will correspond to a per-web request instance 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>



回答3:


Sounds like you're looking for the @inherits Razor directive.

For instance:

@inherits MyBaseViewPage



来源:https://stackoverflow.com/questions/32563279/base-view-page-in-asp-net-mvc-6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!