Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Add support for @namespace to configure the namespace the generated class is in #1159

@DamianEdwards

Description

@DamianEdwards

The Problem

The classes that are generated by Razor files are placed in a fixed namespace of AspNetCore.

As part of Razor Pages, it is idiomatic to specify the page's model using @model, e.g.:

@* ~/Pages/Index.cshtml *@
@page
@model IndexModel

The class IndexModel is specified in a sibling CS file named for the CSHTML file it applies to, e.g. Index.cshtml.cs

In page-focused layout it's also normal to nest identically named files in sub-folders as the site structure is built up, e.g.

~/
  /Pages
    _ViewImports.cshtml
    Index.cshtml
    Index.cshtml.cs <-- namespace App.Pages { public class IndexModel : PageModel {
    /Account
      Index.cshtml
      Index.cshtml.cs <-- namespace App.Pages.Account { public class IndexModel : PageModel {
      /Manage
        Index.cshtml
        Index.cshtml.cs <-- namespace App.Pages.Account.Manage { public class IndexModel : PageModel {

It's also common to have a _ViewImports.cshtml in the pages root to set the default namespace imports for all pages, e.g.:

@using App
@using App.Pages

You might also include subsequent _ViewImports.cshtml files in the sub-folders to import namespaces for types declared in those sub-folders, e.g.:

@using App.Pages.Account.Manage

This results in it being impossible to refer to page models via @model without using the fully qualified class name (including namespace), as there are multiple namespaces imported where the model class name is present. This isn't ideal as it makes it harder to move the page around independently of its content, such that it breaks if you decide to reorganize the layout.

@* ~/Pages/Account/Manage/Index.cshtml *@
@page
@model App.Pages.Account.Manage.IndexModel

The Proposal

Let's introduce support for changing the namespace of the generated view/page class via the @namespace directive. This directive would be set in the _ViewImports.cshtml of new ASP.NET Core projects (via the project templates) to the application's root namespace by default, much like the default @using directives are today.

The directive will take a very similar form to the @using directive, allowing specification of a namespace following white-space after the directive. At design-time it will be projected to the namespace declaration line in the generated file buffer.

@namespace App.Pages

Only a single instance of the @namespace directive is supported, and it can be overridden by more specific _ViewImports.cshtml files (more specific based on folder depth, similar to @model).

The actual namespace used will be the combination of that specified by the closest @namespace directive in a _ViewImports.cshtml flie, combined with the names of the sub-folders down to the folder containing the page (the path). This way, the namespace will typically only need to be set once for the application in the root _ViewImports.cshtml file, e.g.:

~/
  /Pages
    _ViewImports.cshtml <-- @namespace App.Pages
    Index.cshtml <-- generated namespace: App.Pages
    Index.cshtml.cs <-- namespace App.Pages { public class IndexModel : PageModel {
    /Account
      Index.cshtml <-- generated namespace: App.Pages.Account
      Index.cshtml.cs <-- namespace App.Pages.Account { public class IndexModel : PageModel {
      /Manage
        Index.cshtml <-- generated namespace: App.Pages.Account.Manage
        Index.cshtml.cs <-- namespace App.Pages.Account.Manage { public class IndexModel : PageModel {
      /Custom
        _ViewImports.cshtml <-- @namespace Custom
        Index.cshtml <-- generated namespace: Custom
        Index.cshtml.cs <-- namespace Custom { public class IndexModel : PageModel {

If no @namespace is specified in a view/page's directives (inherited or direct), the existing default namespace AspNetCore will be used.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions