Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在执行期间动态覆盖WebConfiguration Manager.AppSettings[“SomeProperty”]_C#_Asp.net_Web Config_Overriding - Fatal编程技术网

C# 在执行期间动态覆盖WebConfiguration Manager.AppSettings[“SomeProperty”]

C# 在执行期间动态覆盖WebConfiguration Manager.AppSettings[“SomeProperty”],c#,asp.net,web-config,overriding,C#,Asp.net,Web Config,Overriding,我有这样一个代码: // can't make any changes at that class class MyClass { void SomeMethod() { // some code ... var someVar = WebConfigurationManager.AppSettings["SomeProperty"]; // some code ... } } 我无法更改该代码,但我需要WebConf

我有这样一个代码:

// can't make any changes at that class
class MyClass
{
    void SomeMethod()
    {
        // some code ...

        var someVar = WebConfigurationManager.AppSettings["SomeProperty"];

        // some code ...
    }
}
我无法更改该代码,但我需要WebConfiguration Manager.AppSettings[SomeProperty]根据某些外部条件(例如,根据用户角色)返回不同的值。所以我正在寻找某种方法来覆盖对该属性的访问。在该重写方法中,我将检查用户角色和 返回适当的值

有办法吗


我发现了这个问题:但它似乎不适合我,因为这里WebConfiguration Manager.AppSettings[SomeProperty]的值在应用程序启动时设置一次。而且我需要动态地进行更改。

如果您直接更改Web.config,它们将仅在下一个请求期间有效,而且据我所知,这不是期望的效果

您不能直接影响WebConfiguration Manager.AppSettings[SomeProperty],这是所需的行为,因为AppSettings as配置是静态的

为了达到接近您期望的效果,我建议您使用HttpContext.Current.Items集合,在该集合中,如果满足条件,您将在应用程序_BeginRequest中初始化为特定值,否则默认为WebConfiguration Manager.AppSettings[SomeProperty]。
然后,您将访问HttpContext.Current.Items[SomeProperty],而不是访问WebConfiguration Manager.AppSettings[SomeProperty]。

从web.config检索值后,您似乎需要执行一些逻辑。如果该逻辑修改了该值本身,则可以在web.config中存储格式字符串

下面是一个使用连接字符串设置的示例。我正在使用格式字符串在运行时填充服务器名称:

<add name="sqlconnection" connectionString="Server={0}\SQLEXPRESS;Database=xxx;Trusted_Connection=True;"/>    

<>编辑:如果不能直接编辑类,我会考虑创建一个部分类来实现这一点。

如果你不能改变正在读取AppSt设置的代码,那么就没有办法做你想做的事情。WebConfiguration Manager不可从外部插拔或重播

您必须更改代码。

不,当然不能


如果你不能改变类,那么你就不能改变行为。微软在WebApplicationManager中设置覆盖功能并没有一般原因。通常,人们希望能够更改一个类,或者正确地设计它,以便以正确的方式覆盖它。

在MVC中,为了简化测试和模拟,我倾向于为所有通过接口引用的公共类(如Request、Session和ConfigManager)使用自定义对象。 基本上不需要从头开始实现类,所以您的实现可以是一个包装器,它实际上在引擎盖下使用.NET类,但是它也有机会在中间插入一些自定义逻辑,就像在您的例子中一样。 因此,您可以使用包含您自己的逻辑的方法(如GetAppConfigkey)创建WebConfiguration Manager的包装器。 因此,使用依赖注入的概念很容易,只要您需要,这个类就可以在任何地方使用

因此,举一个简单的例子:

//this will be injected
public MyControllerCtor(IConfig cfg)

public interface IConfig
{
   string GetAppConfig(string key);
}

public class myConfig:IConfig
{
   public string GetAppConfig(string key)
   {    
      //your logic
      var someVar = WebConfigurationManager.AppSettings["SomeProperty"];
      //your logic

      return yourCustomAppSetting;
   }
}

这种方法的最大优点是,如果您想将配置存储在数据库或服务中,并更改代码,只需更改接口实现并注入新实例。

谢谢您的回复。但问题是我已经有了使用WebConfiguration Manager.AppSettings[SomeProperty]的代码,我无法更改它。因此,我需要以某种方式捕获对WebConfiguration Manager.AppSettings[SomeProperty]的所有调用,并覆盖它们。恐怕这不可能。找到并替换将是你最好的朋友。。。对于将来,将这样的行为封装到函数中总是很好的,这样每当您进行更改时,您只需在一个地方进行更改。谢谢您的回复。这是一个有趣的解决方案,我会记下来的。但在这种情况下,它不适合我,因为我有一个类和方法在其中,它包含代码,我不能在那个类中更改任何东西。但再次感谢。这并不意味着他不能在其他地方使用。添加了一个建议,可能有助于你避开不能直接编辑类的事实。
//this will be injected
public MyControllerCtor(IConfig cfg)

public interface IConfig
{
   string GetAppConfig(string key);
}

public class myConfig:IConfig
{
   public string GetAppConfig(string key)
   {    
      //your logic
      var someVar = WebConfigurationManager.AppSettings["SomeProperty"];
      //your logic

      return yourCustomAppSetting;
   }
}