如何高逼格读取Web.config中的AppSettings

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何高逼格读取Web.config中的AppSettings相关的知识,希望对你有一定的参考价值。

在ASP.NET网站里(也包括其他有web.config, app.config)的.NET工程里,读AppSettings的值是个很常见的场景。比如:
<add key="EnableAzureWebTrace" value="true"/>

在代码里读的时候就会用到:
ConfigurationManager.AppSettings["EnableAzureWebTrace"];

这个[]索引器返回的是string类型。所以下一步咱们通常需要类型转换才能在代码里拿来用。比如这个例子里,咱们就要转换成bool。其他时候,可能要转换为int等类型。
string enableAzureWebTraceConfig = ConfigurationManager.AppSettings["EnableAzureWebTrace"];
bool enableAzureWebTrace = bool.Parse(enableAzureWebTraceConfig);
if(enableAzureWebTrace)

// do some logic


但问题是,config文件的值对于咱们代码来说是不稳定因素,不可控的,这里拿回来的string未必能正确转换格式。所以通常会用TryParse方法来防爆:
string enableAzureWebTraceConfig = ConfigurationManager.AppSettings["EnableAzureWebTrace"];
bool enableAzureWebTrace = false;
if (bool.TryParse(enableAzureWebTraceConfig, out enableAzureWebTrace) && enableAzureWebTrace)

// do some logic

else

throw new ConfigurationException("EnableAzureWebTrace value must be true of false.");


当然,不要忘了一点。读出来的string有可能首先就是空的。所以又得加上对string的判断,并且考虑到ConfigurationManager.AppSettings[]索引器本身可能会爆,所以还得加try-catch,最终代码就变成这样了:
try

string enableAzureWebTraceConfig = ConfigurationManager.AppSettings["EnableAzureWebTrace"];
if (!string.IsNullOrEmpty(enableAzureWebTraceConfig))

bool enableAzureWebTrace = false;
if (bool.TryParse(enableAzureWebTraceConfig, out enableAzureWebTrace) && enableAzureWebTrace)

// do some logic

else

throw new ConfigurationException("EnableAzureWebTrace value must be true of false.");




catch (ConfigurationException ce)

// error handling logic
throw;


这样的代码非常没有逼格,重用性很差,如果自己的config里面AppSettings比较多,或者一个settings在程序里到处被用,显然不应该每次都把这样的代码到处复制。所以封装一下呗:
public bool IsEnableAzureWebTrace()

try

bool enableAzureWebTrace = false;
string enableAzureWebTraceConfig = ConfigurationManager.AppSettings["EnableAzureWebTrace"];
if (!string.IsNullOrEmpty(enableAzureWebTraceConfig))

if (!bool.TryParse(enableAzureWebTraceConfig, out enableAzureWebTrace))

throw new ConfigurationException("EnableAzureWebTrace value must be true of false.");


return enableAzureWebTrace;

catch (ConfigurationException ce)

// error handling logic
return false;



现在要用到EnableAzureWebTrace的地方都只要调用public bool
IsEnableAzureWebTrace()就行了,就把如何读config的逻辑抽离了。重构的目的是,万一以后读config的机制变了,只
要改这一处。不用到处改。但是,重构的粒度还不够。这个方法只能用来读EnableAzureWebTrace这一个设置。要通用一下,让它也能
读其他bool类型的设置。把key单独的抽出来变成参数:
public bool GetBooleanConfiguration(string key)

try

bool val = false;
string rawConfigValue = ConfigurationManager.AppSettings[key];
if (!string.IsNullOrEmpty(rawConfigValue))

if (!bool.TryParse(rawConfigValue, out val))

throw new ConfigurationException(string.Format("0 value must be true of false.", key));


return val;

catch (ConfigurationException ce)

// error handling logic
return false;



但是这还不够,因为这个方法只能满足于bool类型的config,咱们希望有个公用的方法,能读取其他类型。这时候就需要用泛型了。把返回类型给抽离出来。

难点在于,每种数据类型的类型转换写法不一样。比如bool类型是bool.TryParse,int类型是int.TryParse,怎么把这部分逻辑抽象出来呢?

一种办法是用C#本身的类型转换:
(T) Convert.ChangeType(rawConfigValue, typeof (T));

另一种是把类型转换的逻辑作为委托加在方法的参数里,这样就用lambda表达式去传,咱比较偏向这种方法,因为方法的调用者能非常清晰的知道“该干嘛,该怎么干”。

这时候,如果因为非法类型转换爆,是得让调用者知道的。所以个人偏向把TryParse改为Parse,死就要死个明白。
public T GetConfiguration<T>(Func<string, T> parseFunc, string key)

try

T val = default(T);
string rawConfigValue = ConfigurationManager.AppSettings[key];
if (!string.IsNullOrEmpty(rawConfigValue))

return parseFunc(rawConfigValue);

return val;

catch (ConfigurationException ce)

// error handling logic
return default(T);



现在,调用这个方法就能这样去写:
GetConfiguration<bool>(bool.Parse, "EnableAzureWebTrace");

看起来已经很牛逼了。但其实还不够。考虑到之前说的config值为空字符串的问题,安全一点的做法是,当遇到空字符串时候,返回一个默认值。因为
这种错误,并不是key不存在的错误,而是key存在,但是值没填。非法值是应该认为错误的。但是空值个人认为更应该处理为一种“警告”,是应该有
fallback的策略的,而非不可饶恕的错误。为了返回默认值,咱们可以多加一个委托。
public T GetConfiguration<T>(Func<string, T> parseFunc, Func<T> defaultTValueFunc, string key)

try

string rawConfigValue = ConfigurationManager.AppSettings[key];
return !string.IsNullOrEmpty(rawConfigValue) ?
parseFunc(rawConfigValue) :
defaultTValueFunc();

catch (ConfigurationException ce)

// error handling logic
return default(T);



现在,调用者就能灵活处理遇到config为空时候的默认值了:
GetConfiguration<bool>(bool.Parse, () => false, "EnableAzureWebTrace");

但是如果每次都在条件判断里写上面那样的语句是挺麻烦的,在一般的系统开发中,常常会用一个管理配置的Settings类来对应
Web.config里的设置表,维护这个关系。为了使用方便,咱们会把每个Settings的名字,也就是key,作为属性去暴露给调用者,于是就能
这样写:
public bool EnableAzureWebTrace

get

return GetConfiguration<bool>(bool.Parse, () => false, "EnableAzureWebTrace");



以为装逼结束了吗?当然不行!没发现,属性名称和传进去的string类型的key名称是重复的吗?这样写代码是不是有点蛋疼?而且最惨的是,
在VS2015,C#6.0之前(也就是下版本的C#),string这种东西,要是写错了是编译不出来的,所以应该尽量避免用string传
key。经常会发生改了属性名,没有一起改string值的悲剧。比如MVVM框架的RaisePropertyChanged(string)就经常坑
爹(题外话)。。。

好在,.NET4.5有个CallerMemberName特性,意思是”调用咱的方法叫什么名字”,就能帮咱们把这个string参数撸掉。

所以,只需要把方法签名里的string key改成:
public T GetConfiguration<T>(Func<string, T> parseFunc, Func<T> defaultTValueFunc, [CallerMemberName]string key = "")

这样这个方法被调用的时候,key就会自动赋值为调用它的方法或属性名。然后,刚才的那个属性就能够这样去写:
public bool EnableAzureWebTrace

get

return GetConfiguration<bool>(bool.Parse, () => false);



以为装逼真的结束了吗?还有最后一步。万一要是碰到有些情况,属性名真的和appSettings里的key名字不一样怎么办?为了灵活处理这种
边缘情况,还可以加个参数,强撸这种名称不一样的情况,如果这个参数被赋值了(下面的supressKey),就用它去读config而不用传入
的key。

下面给出咱博客里读AppSettings的通用代码:
private T TryGetValueFromConfig<T>(Func<string, T> parseFunc, Func<T> defaultTValueFunc,
[CallerMemberName]string key = "", string supressKey = "")

try

if (!supressKey.IsNullOrEmptyOrWhiteSpace())

key = supressKey;


var node = ConfigurationManager.AppSettings[key];
return !string.IsNullOrEmpty(node) ? parseFunc(node) : defaultTValueFunc();

catch (Exception ex)

Logger.Error(string.Format("Error Reading web.config on AppSettings node: 0", key), ex);
return default(T);



现在,就能灵活装逼了,给几个例子:

string类型,属性名和key不一样,默认值“FileSystemImageProvider”:
public string PostImageProvider

get

return TryGetValueFromConfig(_ => _, () => "FileSystemImageProvider", supressKey: "ImageProvider");



bool类型,默认值想要true
public bool IncludeSiteDomainForImageUploadUrl

get

return TryGetValueFromConfig(bool.Parse, () => true);



int类型,默认值为20
public int CacheSlideExpireTimeSpanFallbackMinutes

get

return TryGetValueFromConfig(int.Parse, () => 20);

参考技术A 这个就和读取xml是一样的, 你使用vs编程的话,添加了,configurationMangeer引用以后,就可以直接操作webconfig.这个文件了,而不需要像读取xml一样,写路径什么的 具体的读法,楼上的回答了。

用Nginx+Telegraf+Influxb+Grafana构建高逼格Nginx集群监控系统

日常生产环境搭建了Nginx集群后,就需要继续深入研究的就是日常Nginx监控。

Nginx如何监控?相信百度就可以找到:nginx-status

通过Nginx-status,实时获取到Nginx监控数据后,如何和现有监控系统集成?一个很好的解决方案:

Nginx+Telegraf+Influxdb+Grafana

即通过Telegraf监控插件定时收集Nginx的监控状态,存储到时序数据库Influxdb中,然后通过Grafana展现即可。

 

一、Nginx启用nginx-status功能

源码编译安装的nginx,那么需要在编译的时候加上对应的模块

./configure --with-http_stub_status_module
使用 ./configure --help 能看到更多的模块支持。然后编译安装即可。

如果是直接 apt-get install 安装的 nginx,那么使用命令来查看是否支持 stub_status 这个模块。

如下命令: nginx –V 看看是否有 --with-http_stub_status_module 这个模块。

 

 

修改Nginx配置文件:在Server章节中增加:

location /nginx-status {
allow 127.0.0.1; //允许的IP
deny all;
stub_status on;
access_log off;
}
Reload 重启Nginx,查看Nginx-Status

 

 

输出信息的说明:

active connections – 活跃的连接数量
server accepts handled requests — 总共处理了11989个连接 , 成功创建11989次握手, 总共处理了11991个请求
reading — 读取客户端的连接数
writing — 响应数据到客户端的数量
waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接.
 

二、Telegraf安装配置Nginx监控

关于Telegraf的安装,请参考官方介绍

https://www.influxdata.com/time-series-platform/telegraf/

 

 

wget https://dl.influxdata.com/telegraf/releases/telegraf-1.4.3-1.x86_64.rpm
sudo yum localinstall telegraf-1.4.3-1.x86_64.rpm
然后,在配置文件teldgraf.conf中配置Influxdb连接

 

 

增加对Nginx的监控

 

 

配置完成,重启telegraf服务即可。

 

三、Grafana集成Nginx监控

Grafana中支持Influxdb数据源,配置上上个步骤的Influxdb数据源之后,我们定制Nginx监控图表:

数据源:Influxdb

FROM:nginx

SELECT:field(accepts)

https://ds.163.com/user/21375d6745f641c1bb4307b181773267/
https://m.ds.163.com/user/4374a18d7123493890d023a568441492
https://m.ds.163.com/user/21375d6745f641c1bb4307b181773267/
https://ds.163.com/user/4374a18d7123493890d023a568441492
https://www.chahaoba.com/%E5%88%86%E7%B1%BB:%E6%9D%8F%E5%BD%A9%E6%80%BB%E4%BB%A3Q1530667
https://tw.m.chahaoba.com/%E6%9D%8F%E5%BD%A9%E6%80%BB%E4%BB%A31530667
https://ds.163.com/user/21375d6745f641c1bb4307b181773267/
http://search.jd.com/Search?keyword=%e6%9d%8f%e5%bd%a9%e4%bb%a3%e7%90%86Q1530667&enc=utf
http://search.jd.com/Search?keyword=%e6%9d%8f%e5%bd%a9%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%90%86Q1530667&enc=utf

展现效果:

以上我们通过Nginx+Telegraf+Influxb+Grafana,实现了Nginx的监控,非常方便。

你们在日常实际生产环境对Nginx的状态监控使用的是何种技术?

最新整理的Java技术干货文档资料:【Java核心知识点整理】涵盖29个Java核心技术详解,JVM,Redis,Nginx,Spring Boot,Spring Cloud,Kafka,并发编程,Tomcat,MyBatis,BAT面试题,Java技术精讲视频等。转发+关注,私信回复“干货”即可获得免费领取方式。

掌握了这些知识点,面试时在候选人中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。
————————————————
版权声明:本文为CSDN博主「Java技术剑vx:tkzl6666」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yelvgou9995/java/article/details/105208264

以上是关于如何高逼格读取Web.config中的AppSettings的主要内容,如果未能解决你的问题,请参考以下文章

如何打造一个高逼格的云运维平台?

如何定义一个高逼格的原生JS插件

如何高逼格的输出hello world

构建一套高逼格 Nginx 集群监控系统!

TOP 互联网公司大牛带你打造高逼格自动化平台

如何阅读web.config文件中的appSettings部分?