Strange automatic namespace imports in my Razor vi

2019-07-04 15:45发布

问题:

Today I noticed that e.g. "System" and "System.Web.Security" are imported in all my razor views, although I did not actively import them. I checked:

  • @using directive
  • web.config (EDIT: also global web.config)
  • AddGlobalImport

EDIT:

It seems these namespace imports are hardwired in the Razor Source Code

https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.WebPages.Razor/WebPageRazorHost.cs

    private WebPageRazorHost()
    {
        NamespaceImports.Add("System");
        NamespaceImports.Add("System.Collections.Generic");
        NamespaceImports.Add("System.IO");
        NamespaceImports.Add("System.Linq");
        NamespaceImports.Add("System.Net");
        NamespaceImports.Add("System.Web");
        NamespaceImports.Add("System.Web.Helpers");
        NamespaceImports.Add("System.Web.Security");
        NamespaceImports.Add("System.Web.UI");
        NamespaceImports.Add("System.Web.WebPages");
        NamespaceImports.Add("System.Web.WebPages.Html");

        // ...
    }

It also seems that I can't disable these by setting a "clear" at the beginning of my web.config:

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage" >
        <namespaces>
            <clear />
            <add namespace="System.Web.Helpers" />
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Routing" />
            <add namespace="System.Web.WebPages" />
        </namespaces>
    </pages>
</system.web.webPages.razor>

So this issue might be unfixable unless Razor source is changed.

回答1:

it is common , because it is registered in overall web config file at following location :

systemroot\Microsoft.NET\Framework\versionNumber\CONFIG\Web.config  

it is registered like this :

 <pages>
            <namespaces>
                <add namespace="System" />
                <add namespace="System.Collections" />
                <add namespace="System.Collections.Generic" />
                <add namespace="System.Collections.Specialized" />
                <add namespace="System.ComponentModel.DataAnnotations" />
                <add namespace="System.Configuration" />
                <add namespace="System.Linq" />
                <add namespace="System.Text" />
                <add namespace="System.Text.RegularExpressions" />
                <add namespace="System.Web" />
                <add namespace="System.Web.Caching" />
                <add namespace="System.Web.DynamicData" />
                <add namespace="System.Web.SessionState" />
                <add namespace="System.Web.Security" />
                <add namespace="System.Web.Profile" />                    
                <add namespace="System.Xml.Linq" />
            </namespaces>  
 </pages>

EDIT:

following is from an SO answer here:

In Preview 1 Razor used the WebForms namespaces config section. However in the Beta there is a new config section that is seperate from the WebForms one. You will need to add the follwing to your web.config file (or just start with a brand new project from the template):

<configSections>
  <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
    <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
  </sectionGroup>
</configSections>

<system.web.webPages.razor>
  <pages pageBaseType="System.Web.Mvc.WebViewPage">
    <namespaces>
      <add namespace="MyCustomHelpers" />
    </namespaces>
  </pages>
</system.web.webPages.razor>


回答2:

I ran across this question while answering another one (Removing System.Web.UI from a Razor view). Below is a copy of my answer. It may be useful.

I'm not sure if this is what you're after, but I did a quick experiment. I think it works.

I extended the MvcWebRazorHostFactory a bit. The new factory basically passes along the host created by the base class, but removes the namespace first.

This is the class:

namespace TestCode
{
    using System.Web.WebPages.Razor;
    using System.Web.Mvc;
    using System.Web.Mvc.Razor;

    public class CustomWebRazorHostFactory : MvcWebRazorHostFactory
    {
        public override WebPageRazorHost CreateHost(string virtualPath, string physicalPath)
        {
            WebPageRazorHost host = base.CreateHost(virtualPath, physicalPath);
            host.NamespaceImports.Remove("System.Web.UI");
            return host;
        }
    }
}

Then I changed web.config to use my factory instead of the standard one:

<system.web.webPages.razor>
    <!--<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />-->
    <host factoryType="TestCode.CustomWebRazorHostFactory" />

Bingo!



回答3:

So the answer is: In Razor views some namespaces are always imported. This can't be disabled in configuration because it is hardwired in the code. These namespaces are:

  • System
  • System.Collections.Generic
  • System.IO
  • System.Linq
  • System.Net
  • System.Web
  • System.Web.Helpers
  • System.Web.Security
  • System.Web.UI
  • System.Web.WebPages
  • System.Web.WebPages.Html

I am not 100% sure that this is the complete answer, but as long as there is no opposing comment I will accept it.