简体   繁体   English

使用 C# 修改运行时 > 探测属性 web.config

[英]Modify runtime > probing attribute web.config using C#

I host an application on IIS with the following structure:我在 IIS 上托管了一个应用程序,其结构如下:

IISAPP
  - bin
  - plugins
  - scripts
  - default1.aspx
  - web.config

Within the Plugins directory, I host several other ASPX apps within it's own directory so that structure would look like this:在 Plugins 目录中,我在它自己的目录中托管了其他几个 ASPX 应用程序,因此结构如下所示:

IISAPP
  - bin
  - plugins
    - MyPlugin
      - bin
      - scripts
      - default2.aspx
      - web.config
  - scripts
  - default1.aspx
  - web.config

When I navigate to http://IISAPP/ the default1.aspx page is served which is great.当我导航到http://IISAPP/时,会提供 default1.aspx 页面,这很棒。 When I navigate to http://IISAPP/plugins/MyPlugin/default2.aspx the page is not served and it is complaining that it cannot find the dll's.当我导航到http://IISAPP/plugins/MyPlugin/default2.aspx 时,该页面未提供,它抱怨找不到 dll。 This is because the plugin app is looking for the dll's in the bin folder top level application.这是因为插件应用程序正在寻找 bin 文件夹顶级应用程序中的 dll。

I proceeded to add the <probing privatePath="plugins/MyPlugin/bin" /> tag.我继续添加<probing privatePath="plugins/MyPlugin/bin" />标签。 This solved the issue of serving up default2.aspx.这解决了提供 default2.aspx 的问题。

The problem问题

These plugins will be installed using an installer.这些插件将使用安装程序安装。 I have to somehow change that private path to include all folders.我必须以某种方式更改该私有路径以包含所有文件夹。 So if I add a "MyPlugin2", I will have to modify the probing tag in the top level web.config to be <probing privatePath="plugins/MyPlugin/bin;plugins/MyPlugin/bin" /> .因此,如果我添加“MyPlugin2”,我将不得不将顶层 web.config 中的探测标记修改为<probing privatePath="plugins/MyPlugin/bin;plugins/MyPlugin/bin" />

I need to modify the privatePath attribute in the below web.config inside of the probing element in the runtime section using C# and then saving the config file.我需要使用 C# 在runtime部分的probing元素内修改下面 web.config 中的privatePath属性,然后保存配置文件。 I have tried to do this using the configuration manager but cannot locate the proper path.我尝试使用配置管理器执行此操作,但找不到正确的路径。 When it seems right, it results in null.当它看起来正确时,它会导致 null。

I played around with the following too:我也玩过以下游戏:

var config = System.Xml.Linq.XDocument.Load(System.Web.HttpContext.Current.Server.MapPath("~/Web.config"));
var runtimeNode = config.Root.Element("runtime").Element("assemblyBinding").Element("probing").Attribute("privatePath");

In this case the document loads but for the life of me I cannot get to that privatepath value to update it and save the config.在这种情况下,文档会加载,但在我的一生中,我无法获得该 privatepath 值来更新它并保存配置。

I also tried XMLDocument but I cannot load the xml due to line 1 in the web.config.我也尝试了XMLDocument ,但由于 web.config 中的第 1 行,我无法加载 xml。 I don't really want to remove it and apart from that, the solution feels a bit sloppy.我真的不想删除它,除此之外,解决方案感觉有点草率。

UPDATE I tried the following:更新我尝试了以下方法:

var config = System.Xml.Linq.XDocument.Load(System.Web.HttpContext.Current.Server.MapPath("~/Web.config"));
System.Xml.Linq.XElement runtimeNode = config.Root.Element("runtime");
System.Xml.Linq.XElement assemblyBindingNode = runtimeNode.Element("assemblyBinding");
System.Xml.Linq.XElement probingNode = assemblyBindingNode.Element("probing");
System.Xml.Linq.XAttribute att = probingNode.Attribute("privatePath");

att.Value = "new value";
config.Save(System.Web.HttpContext.Current.Server.MapPath("~/Web.config.xml"));

It works up to the runtime node.它适用于运行时节点。 it is like it cannot find the assemblyBinding node within the runtime node.就像在运行时节点中找不到 assemblyBinding 节点一样。

web.config web.config

 <?xml version="1.0"?> <configuration> <configSections> <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > <section name="MyProject.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </sectionGroup> </configSections> <appSettings> <add key="WebFilePath" value="D:\Web Solutions\WEB" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.6.2"/> <httpRuntime targetFramework="4.5"/> <httpModules> <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/> </httpModules> </system.web> <connectionStrings> <add name="DB" connectionString="" providerName="System.Data.SqlClient"/> </connectionStrings> <system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0"/> <remove name="OPTIONSVerbHandler"/> <remove name="TRACEVerbHandler"/> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/> </handlers> <validation validateIntegratedModeConfiguration="false"/> <modules> <remove name="ApplicationInsightsWebTracking"/> <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler"/> </modules> </system.webServer> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/> <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/> <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/> </dependentAssembly> <probing privatePath="INeedToChangeThisValue" /> </assemblyBinding> </runtime> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/> <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/> </compilers> </system.codedom> </configuration>

Looks like this is an xml namespace issue, got it working using XmlDocument . 看起来这是一个xml名称空间问题,可以通过XmlDocument使用它。 My only concern is that usually ASP.Net will do assembly resolving at startup which means that you might need to restart the app after setting the privatePath , I've used ConfigurationManager.RefreshSection("runtime") , that might refresh the section and get things working. 我唯一关心的是,通常ASP.Net会在启动时进行程序集解析,这意味着您可能需要在设置privatePath之后重新启动应用程序,我已经使用过ConfigurationManager.RefreshSection("runtime") ,这可能会刷新该节并获取工作正常。

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(Server.MapPath("~/web.config"));

XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ass", "urn:schemas-microsoft-com:asm.v1");

var probing = xmlDoc.SelectSingleNode("//runtime/ass:assemblyBinding/ass:probing", nsmgr) as XmlElement;
probing?.SetAttribute("privatePath", "bin;plugins/bin");

xmlDoc.Save(Server.MapPath("~/web.config"));

ConfigurationManager.RefreshSection("runtime");

Did @matt_lethargic's recommendation work? @matt_lethargic 的推荐有用吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM