在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
[ASP.NET MVC 专题] [ASP.NET MVC 专题] 如何为Route构造相关的自定义Configuration [ASP.NET MVC 专题] ViewEngine的发展以及应用
背景 大家对配置文件都是非常的熟悉,至于怎么个玩法就各有千秋。本人偶然在一个开源项目中看到牛人写的代码,其中就有关于配置文件的操作的方面。惊叹于代码的艺术的时候,更多的是感叹,唉!高手真多,本人什么时候才能达到这个水平,一步一步来,说不定,3,5几年后哥也成了高手了,哈哈。低调,一定要低调!
Configuration自定义操作基础 先来看本人总结出来的比较肤浅的代码,熟悉下基本操作,然后在看牛人在ASP.NET MVC中如何玩转Configuration。如下图所示,我们先仅仅拿几个类和比较简单的配置文件(下图标红色框的)入手:
Web.config如下:
1 <?xml version="1.0"?>
2 <configuration> 3 <configSections> 4 <section name="demoConfiguration" type="Core.Configuration.Operation.DemoConfigurationSection,Core.Configuration"/> 5 </configSections> 6 <demoConfiguration configSource="config\demo.config"/> 7 <system.web> 8 <compilation debug="true" targetFramework="4.0"/> 9 </system.web> 10 </configuration>
从上面我们看出,增加了一个ConfigurationSection部分,类名为Core.Configuration.Operation.DemoConfigurationSection,程序集为Core.Configuration。<demoConfiguration configSource="config\demo.config"/>中configSource标识了我们的这部分配置内容在config\demo.config的文件中。 demo.config如下:
1 <?xml version="1.0"?>
2 <demoConfiguration value="123"> 3 <items default="default" enable="false"> 4 <add url="www.google.com" name="jasen"></add> 5 <add url="www.google2.com" name="jasen2"></add> 6 <add url="www.google3.com" name="jasen3"></add> 7 </items> 8 </demoConfiguration>
现在,我们增加的configurationSection这部分如何在代码中运用?
Core.Configuration.Operation.DemoConfigurationSection section = (Core.Configuration.Operation.DemoConfigurationSection)System.Configuration.ConfigurationManager.GetSection("demoConfiguration");
// 检索当前应用程序默认配置的指定配置节。
先看下ConfigurationSection
1 public class DemoConfigurationSection : ConfigurationSection
2 { 3 public DemoConfigurationSection() 4 { 5 } 6 7 [ConfigurationProperty("items", IsRequired = false)] 8 public ItemCollection Items 9 { 10 get { return (ItemCollection)(this["items"]); } 11 set { this["items"] = value; } 12 } 13 14 [ConfigurationProperty("value", IsRequired = false)] 15 public string Value 16 { 17 get { return this["value"].ToString(); } 18 set { this["value"] = value; } 19 } 20 }
ConfigurationElementCollection
1 public class ItemCollection:ConfigurationElementCollection
2 { 3 public Item this[int index] 4 { 5 get 6 { 7 return base.BaseGet(index) as Item; 8 } 9 set 10 { 11 if (base.BaseGet(index) != null) 12 { 13 base.BaseRemoveAt(index); 14 } 16 this.BaseAdd(index, value); 17 } 18 } 19 20 protected override ConfigurationElement CreateNewElement() 21 { 22 return new Item(); 23 } 24 25 protected override object GetElementKey(ConfigurationElement element) 26 { 27 return ((Item)element).Name; 28 } 29 30 [ConfigurationProperty("default", IsRequired = true)] 31 public string Default 32 { 33 get { return Convert.ToString(this["default"]); } 34 set { this["default"] = value; } 35 } 36 37 [ConfigurationProperty("enable", IsRequired = true, DefaultValue = true)] 38 public bool Enable 39 { 40 get { return Boolean.Parse(this["enable"].ToString()); } 41 set { this["enable"] = value; } 42 } 43 }
集合中提供对ConfigurationElement的索引(base.BaseGet()与base.BaseAdd()),重写了父类的CreateNewElement(),GetElementKey(ConfigurationElement element)方法。 ConfigurationElement
1 public class Item:ConfigurationElement
2 { 3 [ConfigurationProperty("name", IsRequired = true, IsKey = true)] 4 public string Name 5 { 6 get { return this["name"].ToString(); } 7 set { this["name"] = value; } 8 } 9 10 [ConfigurationProperty("url", IsRequired = true, IsKey = true)] 11 public string Url 12 { 13 get { return this["url"].ToString(); } 14 set { this["url"] = value; } 15 } 16 }
从上往下看的话,整体就是一个树形结构,想必大家都很熟悉。如果我们需要扩展上述的ConfigurationSection,我们仅仅需要多增加ConfigurationEelementCollection以及ConfigurationElement类,看情况而定(可能还有其他属性什么的)。
这样我们就可以将System.Configuration.ConfigurationManager.GetSection("demoConfiguration");强制转换成我们自定义的Core.Configuration.Operation.DemoConfigurationSection 了,进而进行你自己的编码操作。我们可以核查一下我们的操作,是否与我们开始设定的情况一致。我们编写如下方法进行检测。
1 private void DisplaySectionData(Core.Configuration.Operation.DemoConfigurationSection section)
2 { 3 System.Text.StringBuilder sb = new System.Text.StringBuilder(); 4 sb.Append("?xml version=\"1.0\"?<br/>"); 5 sb.Append(string.Format("demoConfiguration value=\"{0}\"<br/>", section.Value)); 6 sb.Append(string.Format(" items default=\"{0}\" enable=\"{1}\"<br/>", section.Items.Default, section.Items.Enable)); 7 foreach (Core.Configuration.Operation.Item item in section.Items){ 8 sb.Append(string.Format(" add url=\"{0}\" name=\"{1}\" /add<br/>", item.Url, item.Name)); 9 } 10 sb.Append(" /items<br/>"); 11 sb.Append("/demoConfiguration<br/>"); 12 13 Response.Write(sb.ToString()); 14 }
编译下项目,显示如下:
是不是和我们预想的结果一样? 肯定一样的,不需要多想。现在基础的应该大家都懂的差不多了。下面看那些高人写的,哈哈,哥也很崇拜!
Configuration自定义操作进阶(ASP.NET MVC) 上面是本人将所有代码分离出来重新构建的(下次我需要运用的),截图中可以基本看出我们的文件和目录情况。(我们把大概的配置文件写好了,这些类什么的都不是问题,依样画葫芦就行!) 其中最重要的就是下面的扩展类(本人稍微重构了一下方法),如下:
public static class RouteCollectionExtensions { private static string defaultpage; private static string extendName; public static string GetDefaultPage(this System.Web.Routing.RouteCollection routes) { return defaultpage; } public static string GetExtendName(this System.Web.Routing.RouteCollection routes) { return extendName; } /// <summary> /// 根据配置的Routing规则来加载Routing规则 /// </summary> public static void RegisterRoutes(this System.Web.Routing.RouteCollection routes, RouteConfigurationSection section) { if (!section.Short.Enable && !section.Map.Enable) throw new ConfigurationErrorsException("Short与Map必须至少有一个开启."); extendName = section.Extend; defaultpage = (section.Short != null && section.Short.Enable) ? section.Short.Default.Replace("$0", extendName) : section.Map.Default.Replace("$0", extendName); HandleIgnoreItemCollection(routes, section); HandleShortRoutingCollection(routes, section); HandleMapRoutingCollection(routes, section); } private static void HandleMapRoutingCollection(System.Web.Routing.RouteCollection routes, RouteConfigurationSection section) { // Manipluate the Routing Table foreach (RoutingItem routingItem in section.Map) { RouteValueDictionary defaults = new RouteValueDictionary(); RouteValueDictionary constraints = new RouteValueDictionary(); if (routingItem.Controller != string.Empty) defaults.Add("controller", routingItem.Controller); if (routingItem.Action != string.Empty) defaults.Add("action", routingItem.Action); foreach (Parameter param in routingItem.Paramaters) { defaults.Add(param.Name, param.Value); if (!string.IsNullOrEmpty(param.Constraint)) { constraints.Add(param.Name, param.Constraint); } } routes.MapRoute(routingItem.Name, routingItem.Url.Replace("$0", section.Extend), defaults, constraints); } } private static void HandleShortRoutingCollection(System.Web.Routing.RouteCollection routes, RouteConfigurationSection section) { // Maniplute the short Routing Table if (section.Short != null && section.Short.Enable) { foreach (RoutingItem item in section.Short) { RouteValueDictionary defaults = new RouteValueDictionary(); RouteValueDictionary constraints = new RouteValueDictionary(); if (item.Controller != string.Empty) defaults.Add("controller", item.Controller); if (item.Action != string.Empty) defaults.Add("action", item.Action); foreach (Parameter param in item.Paramaters) { defaults.Add(param.Name, param.Value); if (!string.IsNullOrEmpty(param.Constraint)) { constraints.Add(param.Name, param.Constraint); } } routes.MapRoute(item.Name, item.Url.Replace("$0", extendName), defaults, constraints); } } } private static void HandleIgnoreItemCollection(System.Web.Routing.RouteCollection routes, RouteConfigurationSection section) { // Manipulate the Ignore List foreach (IgnoreItem ignoreItem in section.Ignore) { RouteValueDictionary ignoreConstraints = new RouteValueDictionary(); foreach (Constraint constraint in ignoreItem.Constraints) ignoreConstraints.Add(constraint.Name, constraint.Value); routes.IgnoreRoute(ignoreItem.Url, ignoreConstraints); } } public static void IgnoreRoute(this RouteCollection routes, string url, RouteValueDictionary constraints) { if (routes == null) throw new ArgumentNullException("routes"); if (url == null) throw new ArgumentNullException("url"); IgnoreRoute ignore = new IgnoreRoute(url); ignore.Constraints = constraints; routes.Add(ignore); } /// <summary> /// 框架的这个方法的defaults、constraints参数都是Object类型的,只好重写 /// </summary> public static |
请发表评论