转帖|其它|编辑:郝浩|2010-11-24 14:25:53.000|阅读 584 次
概述:大家对配置文件都是非常的熟悉,至于怎么个玩法就各有千秋。本人偶然在一个开源项目中看到某人写的代码,其中就有关于配置文件的操作的方面。本文将介绍如何为Route构造相关的自定义Configuration ,希望对大家有帮助。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
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");
// 检索当前应用程序默认配置的指定配置节。
// 参数: sectionName: 配置节的路径和名称。
// 返回结果: 指定的 System.Configuration.ConfigurationSection 对象,或者,如果该节不存在,则为 null。
public static object System.Configuration.ConfigurationSection.GetSection(string sectionName); 显然返回的是一个object对象,我们接下来需要做的就是该如何定义我们的这部分相关类。
先看下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 void MapRoute( this RouteCollection routes,
string name, string url, RouteValueDictionary defaults,
RouteValueDictionary constraints) {
if (routes == null) throw new ArgumentNullException("routes");
if (url == null) throw new ArgumentNullException("url");
System.Web.Routing.Route route = new System.Web.
Routing.Route(url, new MvcRouteHandler());
route.Defaults = defaults;
route.Constraints = constraints;
routes.Add(name, route);
}
public static RouteConfigurationSection GetSection() {
RouteConfigurationSection section =
(RouteConfigurationSection)ConfigurationManager.GetSection("routeConfiguration");
return section;
}
}
sealed class IgnoreRoute : System.Web.Routing.Route {
public IgnoreRoute(string url)
: base(url, new StopRoutingHandler()) {
}
public override VirtualPathData GetVirtualPath
(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
上面采用了2种处理route的方案,其中包括 public class StopRoutingHandler()这种方式的,它提供一种方式,来指定 ASP.NET 路由不应处理 URL 模式的请求。另外一种就是我们常规的操作。这些扩展方法基本都是实现RouteCollection.Add();
其他的相关类本人就不概述了,因为都是纯粹的机械运动。基本运用代码如下:
1 public static void RegisterRoutes(RouteCollection routes)
2 {
3 //routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
4 //routes.MapRoute(
5 // "Default", // Route name
6 // "{controller}/{action}/{id}", // URL with parameters
7 // new { controller = "Home", action = "Index", id =
UrlParameter.Optional } // Parameter defaults
8 //);
9 Jasen.Core.Mvc.Route.Configuretion.RouteConfigurationSection section =
10 (Jasen.Core.Mvc.Route.Configuretion.RouteConfigurationSection)System.Configuration.ConfigurationManager.GetSection("routeConfiguration");
11 if (section==null) throw new Exception("还没有配置你的Route规则,请配置你的Route规则");
12 RouteTable.Routes.RegisterRoutes(section);
13 }
明显,你仅仅只要配置好你的路由文件就可以了,再也不需要在这个方法里面写好大一片的routes.MapRoute()代码了。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:博客转载