我们知道,在.net中,一个对象的私有变量是无法直接进行修改的,但是,有时候可能会遇到这样奇怪的要求,这时候,我们可以运用.net提供的反射机制,来对一个对象的私有变量来进行修改。下面是一个修改asp.net的Request的Querystring属性的例子,在Request中的QueryString属性是一个只读的属性,要修改这个属性,可以结合Reflectorx工具进行修改
代码 如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using System.Reflection;
using System.Collections.Specialized;
namespace ModifyQueryString
{
public class RemoveQueryStrinModule : IHttpModule
{
public RemoveQueryStrinModule()
{
//
// TODO: Add constructor logic here
//
}
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
RemoveQueryString((HttpApplication)sender);
}
private void RemoveQueryString(HttpApplication context)
{
// <add key="RemoveQueryStrinModule" value="id;name"/>
string configName = ConfigurationManager.AppSettings["RemoveQueryStrinModule"];
if (!string.IsNullOrEmpty(configName))
{
List<string> queryStringName = new List<string>();
string[] nameList = configName.Split(new char[] { ';' });
foreach (string name in nameList)
{
if (!string.IsNullOrEmpty(name))
{
queryStringName.Add(name);
}
}
if (queryStringName.Count > 0)
{
RemoveQueryStringByName(queryStringName, context.Request);
}
}
}
private void RemoveQueryStringByName(List<string> queryStringName, HttpRequest Request)
{
if (queryStringName == null || queryStringName.Count <= 0)
{
return;
}
Type requestType = Request.GetType();
PropertyInfo queryStringProInfo = requestType.GetProperty("QueryString", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
//修改查询参数前,需要获取一下查询参数的值,以便CLR初始化查询参数
queryStringProInfo.GetValue(Request, null);
FieldInfo _queryString = requestType.GetField("_queryString", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
object queryStringValue = _queryString.GetValue(Request);
Type nameObjectCollectionBaseType = typeof(NameObjectCollectionBase);
//修改_queryString字段的IsReadOnly属性
PropertyInfo namePro = nameObjectCollectionBaseType.GetProperty("IsReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
namePro.SetValue(queryStringValue, false, null);
//调用Remove方法移除指定的查询参数
Type nameValueCollectionType = typeof(NameValueCollection);
MethodInfo m = nameValueCollectionType.GetMethod("Remove", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
foreach (string name in queryStringName)
{
m.Invoke(queryStringValue, new object[] { name });
}
}
#endregion
}
}
在web.config文件加上
<appSettings>
<add key="RemoveQueryStrinModule" value="id;name"/>
</appSettings>
<httpModules>
<add name="RemoveQueryStrinModuleName" type="ModifyQueryString.RemoveQueryStrinModule,ModifyQueryString"/>
</httpModules>