1.定义url重写规则,很不幸的是一定要使用特定字符替代&,郁闷ing.........
<UrlReWriter enabled="true" reverse="true">
<url pattern="/BBS/Forum/(d+).shtml" url="/BBS/Forum.aspx?BoardID=$1" repattern="/BBS/Forum.aspx?BoardID=(d+)$" reurl="/BBS/Forum/$1.shtml" />
<url pattern="/BBS/Post/(d+).shtml" url="/BBS/Post.aspx?ArticleID=$1" repattern="/BBS/Post.aspx?ArticleID=(d+)$" reurl="/BBS/Post/$1.shtml"></url>
<url pattern="/BBS/Forum/(d+)/(d+).shtml$" url="/BBS/Forum.aspx?BoardID=$1^type=$2" repattern="/BBS/Forum.aspx?BoardID=(d+)^type=(d+)$" reurl="/BBS/Forum/$1/$2.shtml" />
</UrlReWriter>

2.定义配置文件对应实体类

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Xml;
using System.Web.Caching;

namespace DuwCompontents
{
/// <summary>
/// url重写配置节实体类
/// </summary>
public class UrlReWriter
{
#region
private string _Pattern;
private string _Url;
private string _RePattern;
private string _ReUrl;
#endregion

#region

/// <summary>
/// 反向替换时url地址
/// </summary>
public string ReUrl
{
get { return _ReUrl; }
}

/// <summary>
/// 反向替换时正则
/// </summary>
public string Repattern
{
get { return _RePattern; }
}

/// <summary>
/// 真实url
/// </summary>
public string Url
{
get { return _Url; }
}

/// <summary>
/// 正则
/// </summary>
public string Pattern
{
get { return _Pattern; }
}
#endregion

#region 构造
public UrlReWriter(XmlNode xn) {
_Pattern = xn.Attributes["pattern"].Value;
_Url = xn.Attributes["url"].Value;
_RePattern = xn.Attributes["repattern"].Value;
_ReUrl = xn.Attributes["reurl"].Value;
}
#endregion

}
/// <summary>
/// url重写配置实体类
/// </summary>
public class UrlReWriterConfig
{

#region 私有成员
private static string configFile = "/Configs/UrlReWriter.Config";
private List<UrlReWriter> _UrlRewriter;
private bool _Enabled;
private bool _Reverse;
#endregion

#region 公有属性
/// <summary>
/// 反向匹配支持?
/// </summary>
public bool Reverse
{
get { return _Reverse; }
}
/// <summary>
/// 正向匹配支持?
/// </summary>
public bool Enabled
{
get { return _Enabled; }
}

public List<UrlReWriter> UrlRewriters
{
get { return _UrlRewriter; }
}
#endregion

#region 单件模式
private static UrlReWriterConfig _Config;
static UrlReWriterConfig() {
_Config = new UrlReWriterConfig();
_Config._UrlRewriter = new List<UrlReWriter>();

string file = HttpContext.Current.Server.MapPath( configFile );
XmlDocument xd = new XmlDocument();
xd.Load(file);
XmlElement xe = xd.DocumentElement;
bool enabled = true;
if (xe.Attributes["enabled"] != null)
{
enabled = Boolean.TryParse(xe.Attributes["enabled"].Value, out enabled);
}
_Config._Enabled = enabled;

bool reverse = true;
if (xe.Attributes["reverse"] != null) {
reverse = Boolean.TryParse(xe.Attributes["reverse"].Value, out reverse);
}
_Config._Reverse = reverse;
foreach (XmlNode xn in xe.ChildNodes)
{
if (xn.NodeType == XmlNodeType.Element)
{
UrlReWriter re = new UrlReWriter(xn);
_Config._UrlRewriter.Add(re);
}
}

}
/// <summary>
/// url重写配置实体类
/// </summary>
/// <returns></returns>
public static UrlReWriterConfig Instance()
{
return _Config;
}
#endregion
}
}


3.实现IHttpModule(不使用ajax.net(atlas)可以不用处理AjaxPageFilter相关)
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Xml;
using System.Text.RegularExpressions;

namespace DuwCompontents
{
public interface IRawPath
{
string GetPath();
}
public class DuwHttpModule : IHttpModule, IRawPath
{

#region IRawPath 成员
//private string _rawPath = "";
//public string GetPath()
//{
// return _rawPath;
//}

#endregion
#region IHttpModule 成员

void IHttpModule.Dispose()
{
}

void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
//context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);
}

#endregion

#region 事件
//void context_ReleaseRequestState(object sender, EventArgs e)
//{
// HttpResponse response = HttpContext.Current.Response;

// if (response.ContentType == "text/plain")
// {
// AjaxPageFilter filter = new AjaxPageFilter(response.Filter);
// response.Filter = filter;
// filter.RawPath = this;
// }
//}


void context_BeginRequest(object sender, EventArgs e)
{
//这儿处理url重写
string rawUrl = HttpContext.Current.Request.RawUrl;
//_rawPath = rawUrl ;
UrlReWriterConfig config = UrlReWriterConfig.Instance();
if (HttpContext.Current.Request.Path.EndsWith(".shtml") && config.Enabled )
{
List<UrlReWriter> rewriters = UrlReWriterConfig.Instance().UrlRewriters;

foreach (UrlReWriter rewriter in rewriters)
{
string s_url = rewriter.Url.Replace("^", "&");
Regex r = new Regex(rewriter.Pattern, RegexOptions.IgnoreCase);
if (r.IsMatch(rawUrl))
{
s_url = r.Replace(rawUrl, s_url);
HttpContext.Current.RewritePath(s_url);
break;
}

}
}

}
#endregion

}
}

4.配置IIS,主目录/配置,使用aspnet_isapi.dll处理.shtml.取消确认文件是否存在选择项

5,配置web.Config.支持自定义httpModule
<System.Web>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<!--type="完全限定名,程序集"-->
<add name="DuwHttpModule" type="DuwCompontents.DuwHttpModule,DuwCompontents"/>
</httpModules>
</System.Web>

6重写page类
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using DuwCompontents;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;

namespace DuwControls
{
public class DuwPage : Page
{


#region 事件
protected override void Render(HtmlTextWriter writer)
{
//替换掉form action
config = UrlReWriterConfig.Instance();
if (config.Enabled) {
if (writer is System.Web.UI.Html32TextWriter)
{
writer = new FormFixerHtml32TextWriter(writer.InnerWriter);
}
else
{
writer = new FormFixerHtmlTextWriter(writer.InnerWriter);
}
}
//如果要求支持反向匹配
if(config.Reverse){
FindHyperLink(Controls);
}

base.Render(writer);
}
#endregion

#region 替换所有的服务端超链接
private void FindHyperLink(ControlCollection controls) {
foreach (Control ctrl in controls) {
if (ctrl is HyperLink) {
ReplaceUrl(ctrl as HyperLink);
}
else if (ctrl is System.Web.UI.HtmlControls.HtmlAnchor) {
ReplaceUrl(ctrl as System.Web.UI.HtmlControls.HtmlAnchor);
}
else if (ctrl.Controls.Count > 0)
{
FindHyperLink(ctrl.Controls);
}
}
}
private void ReplaceUrl(System.Web.UI.HtmlControls.HtmlAnchor hl)
{
UrlReWriterConfig config = UrlReWriterConfig.Instance();
List<UrlReWriter> rewriters = UrlReWriterConfig.Instance().UrlRewriters;

foreach (UrlReWriter rewriter in rewriters)
{


string s_url = rewriter.Repattern.Replace("^", "&");
Regex r = new Regex(s_url, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string rawUrl = hl.HRef;
rawUrl = Regex.Replace(rawUrl, s_url, rewriter.ReUrl);
if (hl.HRef != rawUrl)
{
hl.HRef = rawUrl;
break;
}
}
}
private void ReplaceUrl(HyperLink hl) {
UrlReWriterConfig config = UrlReWriterConfig.Instance();
List<UrlReWriter> rewriters = UrlReWriterConfig.Instance().UrlRewriters;

foreach (UrlReWriter rewriter in rewriters)
{


string s_url = rewriter.Repattern.Replace("^", "&");
Regex r = new Regex(s_url, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string rawUrl = hl.NavigateUrl;
rawUrl = Regex.Replace(rawUrl, s_url, rewriter.ReUrl);
if (hl.NavigateUrl != rawUrl)
{
hl.NavigateUrl = rawUrl;
break;
}

}
}
#endregion

#region 替换掉Form的action

#region FormFixerHtml32TextWriter
internal class FormFixerHtml32TextWriter : System.Web.UI.Html32TextWriter
{
private string _url; // 假的URL

internal FormFixerHtml32TextWriter(TextWriter writer)
: base(writer)
{
_url = HttpContext.Current.Request.RawUrl;
}

public override void WriteAttribute(string name, string value, bool encode)
{
// 如果当前输出的属性为form标记的action属性,则将其值替换为重写后的虚假URL
if (_url != null && string.Compare(name, "action", true) == 0)
{
value = _url;
}
base.WriteAttribute(name, value, encode);
}
}
#endregion

#region FormFixerHtmlTextWriter
internal class FormFixerHtmlTextWriter : System.Web.UI.HtmlTextWriter
{
private string _url;
internal FormFixerHtmlTextWriter(TextWriter writer)
: base(writer)
{
_url = HttpContext.Current.Request.RawUrl;
}

public override void WriteAttribute(string name, string value, bool encode)
{
if (_url != null && string.Compare(name, "action", true) == 0)
{
value = _url;
}

base.WriteAttribute(name, value, encode);
}
}
#endregion

#endregion
}
}

7继续使用页面过滤器,使支持ajax.net(atlas)
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;

namespace DuwCompontents
{
public class AjaxPageFilter : Stream
{
IRawPath _context = null;
Stream responseStream;
long position;
StringBuilder responseHtml;

public AjaxPageFilter(Stream inputStream)
{
responseStream = inputStream;
responseHtml = new StringBuilder();
}

public override bool CanRead
{
get { return true; }
}

public override bool CanSeek
{
get { return true; }
}

public override bool CanWrite
{
get { return true; }
}

public override void Close()
{
responseStream.Close();
}

public override void Flush()
{
responseStream.Flush();
}

public override long Length
{
get { return 0; }
}

public override long Position
{
get { return position; }
set { position = value; }
}

public override long Seek(long offset, SeekOrigin origin)
{
return responseStream.Seek(offset, origin);
}

public override void SetLength(long length)
{
responseStream.SetLength(length);
}

public override int Read(byte[] buffer, int offset, int count)
{
return responseStream.Read(buffer, offset, count);
}

public override void Write(byte[] buffer, int offset, int count)
{
string finalHtml = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);

// Transform the response
string formAction = RawPath.GetPath();
if (!String.IsNullOrEmpty(formAction))
{
finalHtml = Regex.Replace(finalHtml, "\|\d+\|formAction\|\|[^\|]+\|",
"|" + formAction.Length.ToString() + "|formAction||" + formAction + "|",
RegexOptions.IgnoreCase);
}

// Write the response
byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);
responseStream.Write(data, 0, data.Length);
}

public IRawPath RawPath
{
get
{
return _context;
}
set
{
_context = value;

}
}
}
}

8.取消3(DuwHttpModule)中的注释,转而支持AjaxPageFilter,
至此url重写工作完成,但是反向匹配虽然可以使我们几乎不用改任何一句代码
就支持全站的url重写,却是一个很浪费资源的行为,并不建议使用
http://blog.csdn.net/baozhenliang/archive/2007/04/30/1593280.aspx
<UrlReWriter enabled="true" reverse="true">
<url pattern="/BBS/Forum/(d+).shtml" url="/BBS/Forum.aspx?BoardID=$1" repattern="/BBS/Forum.aspx?BoardID=(d+)$" reurl="/BBS/Forum/$1.shtml" />
<url pattern="/BBS/Post/(d+).shtml" url="/BBS/Post.aspx?ArticleID=$1" repattern="/BBS/Post.aspx?ArticleID=(d+)$" reurl="/BBS/Post/$1.shtml"></url>
<url pattern="/BBS/Forum/(d+)/(d+).shtml$" url="/BBS/Forum.aspx?BoardID=$1^type=$2" repattern="/BBS/Forum.aspx?BoardID=(d+)^type=(d+)$" reurl="/BBS/Forum/$1/$2.shtml" />
</UrlReWriter>
2.定义配置文件对应实体类
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Xml;
using System.Web.Caching;
namespace DuwCompontents
{
/// <summary>
/// url重写配置节实体类
/// </summary>
public class UrlReWriter
{
#region
private string _Pattern;
private string _Url;
private string _RePattern;
private string _ReUrl;
#endregion
#region
/// <summary>
/// 反向替换时url地址
/// </summary>
public string ReUrl
{
get { return _ReUrl; }
}
/// <summary>
/// 反向替换时正则
/// </summary>
public string Repattern
{
get { return _RePattern; }
}
/// <summary>
/// 真实url
/// </summary>
public string Url
{
get { return _Url; }
}
/// <summary>
/// 正则
/// </summary>
public string Pattern
{
get { return _Pattern; }
}
#endregion
#region 构造
public UrlReWriter(XmlNode xn) {
_Pattern = xn.Attributes["pattern"].Value;
_Url = xn.Attributes["url"].Value;
_RePattern = xn.Attributes["repattern"].Value;
_ReUrl = xn.Attributes["reurl"].Value;
}
#endregion
}
/// <summary>
/// url重写配置实体类
/// </summary>
public class UrlReWriterConfig
{
#region 私有成员
private static string configFile = "/Configs/UrlReWriter.Config";
private List<UrlReWriter> _UrlRewriter;
private bool _Enabled;
private bool _Reverse;
#endregion
#region 公有属性
/// <summary>
/// 反向匹配支持?
/// </summary>
public bool Reverse
{
get { return _Reverse; }
}
/// <summary>
/// 正向匹配支持?
/// </summary>
public bool Enabled
{
get { return _Enabled; }
}
public List<UrlReWriter> UrlRewriters
{
get { return _UrlRewriter; }
}
#endregion
#region 单件模式
private static UrlReWriterConfig _Config;
static UrlReWriterConfig() {
_Config = new UrlReWriterConfig();
_Config._UrlRewriter = new List<UrlReWriter>();
string file = HttpContext.Current.Server.MapPath( configFile );
XmlDocument xd = new XmlDocument();
xd.Load(file);
XmlElement xe = xd.DocumentElement;
bool enabled = true;
if (xe.Attributes["enabled"] != null)
{
enabled = Boolean.TryParse(xe.Attributes["enabled"].Value, out enabled);
}
_Config._Enabled = enabled;
bool reverse = true;
if (xe.Attributes["reverse"] != null) {
reverse = Boolean.TryParse(xe.Attributes["reverse"].Value, out reverse);
}
_Config._Reverse = reverse;
foreach (XmlNode xn in xe.ChildNodes)
{
if (xn.NodeType == XmlNodeType.Element)
{
UrlReWriter re = new UrlReWriter(xn);
_Config._UrlRewriter.Add(re);
}
}
}
/// <summary>
/// url重写配置实体类
/// </summary>
/// <returns></returns>
public static UrlReWriterConfig Instance()
{
return _Config;
}
#endregion
}
}

3.实现IHttpModule(不使用ajax.net(atlas)可以不用处理AjaxPageFilter相关)
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Xml;
using System.Text.RegularExpressions;
namespace DuwCompontents
{
public interface IRawPath
{
string GetPath();
}
public class DuwHttpModule : IHttpModule, IRawPath
{
#region IRawPath 成员
//private string _rawPath = "";
//public string GetPath()
//{
// return _rawPath;
//}

#endregion
#region IHttpModule 成员
void IHttpModule.Dispose()
{
}
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
//context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);
}
#endregion
#region 事件
//void context_ReleaseRequestState(object sender, EventArgs e)
//{
// HttpResponse response = HttpContext.Current.Response;
// if (response.ContentType == "text/plain")
// {
// AjaxPageFilter filter = new AjaxPageFilter(response.Filter);
// response.Filter = filter;
// filter.RawPath = this;
// }
//}

void context_BeginRequest(object sender, EventArgs e)
{
//这儿处理url重写
string rawUrl = HttpContext.Current.Request.RawUrl;
//_rawPath = rawUrl ;
UrlReWriterConfig config = UrlReWriterConfig.Instance();
if (HttpContext.Current.Request.Path.EndsWith(".shtml") && config.Enabled )
{
List<UrlReWriter> rewriters = UrlReWriterConfig.Instance().UrlRewriters;
foreach (UrlReWriter rewriter in rewriters)
{
string s_url = rewriter.Url.Replace("^", "&");
Regex r = new Regex(rewriter.Pattern, RegexOptions.IgnoreCase);
if (r.IsMatch(rawUrl))
{
s_url = r.Replace(rawUrl, s_url);
HttpContext.Current.RewritePath(s_url);
break;
}
}
}
}
#endregion
}
}
4.配置IIS,主目录/配置,使用aspnet_isapi.dll处理.shtml.取消确认文件是否存在选择项
5,配置web.Config.支持自定义httpModule
<System.Web>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<!--type="完全限定名,程序集"-->
<add name="DuwHttpModule" type="DuwCompontents.DuwHttpModule,DuwCompontents"/>
</httpModules>
</System.Web>
6重写page类
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using DuwCompontents;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;
namespace DuwControls
{
public class DuwPage : Page
{

#region 事件
protected override void Render(HtmlTextWriter writer)
{
//替换掉form action
config = UrlReWriterConfig.Instance();
if (config.Enabled) {
if (writer is System.Web.UI.Html32TextWriter)
{
writer = new FormFixerHtml32TextWriter(writer.InnerWriter);
}
else
{
writer = new FormFixerHtmlTextWriter(writer.InnerWriter);
}
}
//如果要求支持反向匹配
if(config.Reverse){
FindHyperLink(Controls);
}
base.Render(writer);
}
#endregion
#region 替换所有的服务端超链接
private void FindHyperLink(ControlCollection controls) {
foreach (Control ctrl in controls) {
if (ctrl is HyperLink) {
ReplaceUrl(ctrl as HyperLink);
}
else if (ctrl is System.Web.UI.HtmlControls.HtmlAnchor) {
ReplaceUrl(ctrl as System.Web.UI.HtmlControls.HtmlAnchor);
}
else if (ctrl.Controls.Count > 0)
{
FindHyperLink(ctrl.Controls);
}
}
}
private void ReplaceUrl(System.Web.UI.HtmlControls.HtmlAnchor hl)
{
UrlReWriterConfig config = UrlReWriterConfig.Instance();
List<UrlReWriter> rewriters = UrlReWriterConfig.Instance().UrlRewriters;
foreach (UrlReWriter rewriter in rewriters)
{

string s_url = rewriter.Repattern.Replace("^", "&");
Regex r = new Regex(s_url, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string rawUrl = hl.HRef;
rawUrl = Regex.Replace(rawUrl, s_url, rewriter.ReUrl);
if (hl.HRef != rawUrl)
{
hl.HRef = rawUrl;
break;
}
}
}
private void ReplaceUrl(HyperLink hl) {
UrlReWriterConfig config = UrlReWriterConfig.Instance();
List<UrlReWriter> rewriters = UrlReWriterConfig.Instance().UrlRewriters;
foreach (UrlReWriter rewriter in rewriters)
{

string s_url = rewriter.Repattern.Replace("^", "&");
Regex r = new Regex(s_url, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string rawUrl = hl.NavigateUrl;
rawUrl = Regex.Replace(rawUrl, s_url, rewriter.ReUrl);
if (hl.NavigateUrl != rawUrl)
{
hl.NavigateUrl = rawUrl;
break;
}

}
}
#endregion
#region 替换掉Form的action
#region FormFixerHtml32TextWriter
internal class FormFixerHtml32TextWriter : System.Web.UI.Html32TextWriter
{
private string _url; // 假的URL
internal FormFixerHtml32TextWriter(TextWriter writer)
: base(writer)
{
_url = HttpContext.Current.Request.RawUrl;
}
public override void WriteAttribute(string name, string value, bool encode)
{
// 如果当前输出的属性为form标记的action属性,则将其值替换为重写后的虚假URL
if (_url != null && string.Compare(name, "action", true) == 0)
{
value = _url;
}
base.WriteAttribute(name, value, encode);
}
}
#endregion
#region FormFixerHtmlTextWriter
internal class FormFixerHtmlTextWriter : System.Web.UI.HtmlTextWriter
{
private string _url;
internal FormFixerHtmlTextWriter(TextWriter writer)
: base(writer)
{
_url = HttpContext.Current.Request.RawUrl;
}
public override void WriteAttribute(string name, string value, bool encode)
{
if (_url != null && string.Compare(name, "action", true) == 0)
{
value = _url;
}
base.WriteAttribute(name, value, encode);
}
}
#endregion
#endregion
}
}
7继续使用页面过滤器,使支持ajax.net(atlas)
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;
namespace DuwCompontents
{
public class AjaxPageFilter : Stream
{
IRawPath _context = null;
Stream responseStream;
long position;
StringBuilder responseHtml;
public AjaxPageFilter(Stream inputStream)
{
responseStream = inputStream;
responseHtml = new StringBuilder();
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Close()
{
responseStream.Close();
}
public override void Flush()
{
responseStream.Flush();
}
public override long Length
{
get { return 0; }
}
public override long Position
{
get { return position; }
set { position = value; }
}
public override long Seek(long offset, SeekOrigin origin)
{
return responseStream.Seek(offset, origin);
}
public override void SetLength(long length)
{
responseStream.SetLength(length);
}
public override int Read(byte[] buffer, int offset, int count)
{
return responseStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
string finalHtml = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
// Transform the response
string formAction = RawPath.GetPath();
if (!String.IsNullOrEmpty(formAction))
{
finalHtml = Regex.Replace(finalHtml, "\|\d+\|formAction\|\|[^\|]+\|",
"|" + formAction.Length.ToString() + "|formAction||" + formAction + "|",
RegexOptions.IgnoreCase);
}
// Write the response
byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);
responseStream.Write(data, 0, data.Length);
}
public IRawPath RawPath
{
get
{
return _context;
}
set
{
_context = value;
}
}
}
}
8.取消3(DuwHttpModule)中的注释,转而支持AjaxPageFilter,
至此url重写工作完成,但是反向匹配虽然可以使我们几乎不用改任何一句代码
就支持全站的url重写,却是一个很浪费资源的行为,并不建议使用
http://blog.csdn.net/baozhenliang/archive/2007/04/30/1593280.aspx

浙公网安备 33010602011771号