因为项目里面需要记录一下重写的方法以备后用
首先增加一个继承IHttpHandler的截获类
代码
public class UserControlRenderingHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string fileType = context.Request.FilePath;
string appRelativePath = context.Request.AppRelativeCurrentExecutionFilePath;
string controlPath = appRelativePath.ToLower().Replace(".uc", ".ascx");
ViewManager<UserControl> viewManager = new ViewManager<UserControl>();
UserControl control = viewManager.LoadViewControl(controlPath);
SetPropertyValues(control, context);
context.Response.ContentType = "text/html";
context.Response.Write(viewManager.RenderView(control));
}
private static Dictionary<
Type,
Dictionary<
PropertyInfo,
List<UserControlRenderingPropertyAttribute>>> s_metadataCache =
new Dictionary<
Type,
Dictionary<
PropertyInfo,
List<UserControlRenderingPropertyAttribute>>>();
private static Dictionary<PropertyInfo, object> s_defaultValueCache =
new Dictionary<PropertyInfo, object>();
private static object s_mutex = new object();
private static Dictionary<
PropertyInfo,
List<UserControlRenderingPropertyAttribute>> GetMetadata(Type type)
{
if (!s_metadataCache.ContainsKey(type))
{
lock (s_mutex)
{
if (!s_metadataCache.ContainsKey(type))
{
s_metadataCache[type] = LoadMetadata(type);
}
}
}
return s_metadataCache[type];
}
private static Dictionary<
PropertyInfo,
List<UserControlRenderingPropertyAttribute>> LoadMetadata(Type type)
{
Dictionary<PropertyInfo, List<UserControlRenderingPropertyAttribute>> result = new Dictionary<PropertyInfo, List<UserControlRenderingPropertyAttribute>>();
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
foreach (PropertyInfo p in properties)
{
object[] oo = p.GetCustomAttributes(typeof(UserControlRenderingPropertyAttribute), true);
if (oo.Length > 0)
{
List<UserControlRenderingPropertyAttribute> list = new List<UserControlRenderingPropertyAttribute>();
list.Add(((UserControlRenderingPropertyAttribute)oo[0]));
result[p] = list;
}
}
return result;
}
private static object GetDefaultValue(PropertyInfo property)
{
if (!s_defaultValueCache.ContainsKey(property))
{
lock (s_mutex)
{
if (!s_defaultValueCache.ContainsKey(property))
{
object[] attributes = property.GetCustomAttributes(typeof(DefaultValueAttribute), true);
object value = attributes.Length > 0 ?
((DefaultValueAttribute)attributes[0]).Value : null;
s_defaultValueCache[property] = value;
}
}
}
return s_defaultValueCache[property];
}
public static void SetPropertyValues(UserControl control, HttpContext context)
{
Dictionary<
PropertyInfo,
List<UserControlRenderingPropertyAttribute>> metadata = GetMetadata(control.GetType());
foreach (PropertyInfo property in metadata.Keys)
{
object value = GetValue(metadata[property], context) ?? GetDefaultValue(property);
if (value != null)
{
property.SetValue(control, Convert.ChangeType(value, property.PropertyType), null);
}
}
}
private static object GetValue(
IEnumerable<UserControlRenderingPropertyAttribute> metadata,
HttpContext context)
{
foreach (UserControlRenderingPropertyAttribute att in metadata)
{
NameValueCollection collection = (att.Source == UserControlRenderingPropertySource.QueryString) ?
context.Request.QueryString : context.Request.Form;
object value = collection[att.Key];
if (value != null) return value;
}
return null;
}
public bool IsReusable
{
get
{
return false;
}
}
上面类相关的东西
代码
public class ViewManager<T> where T : UserControl
{
private AjaxPageBase m_pageHolder;
public T LoadViewControl(string path)
{
this.m_pageHolder = new AjaxPageBase();
return (T)this.m_pageHolder.LoadControl(path);
}
public string RenderView(T control)
{
StringWriter output = new StringWriter();
this.m_pageHolder.Controls.Add(control);
HttpContext.Current.Server.Execute(this.m_pageHolder, output, true);
return output.ToString();
}
}
代码
public class AjaxPageBase : Page
{
public override void VerifyRenderingInServerForm(Control control)
{
}
protected override void OnError(EventArgs e)
{
}
}
下面这个是对form表单的参数截获
代码
public enum UserControlRenderingPropertySource
{
Form,
QueryString
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class UserControlRenderingPropertyAttribute : Attribute
{
string _key;
public string Key
{
get { return _key; }
set { _key = value; }
}
UserControlRenderingPropertySource _source;
public UserControlRenderingPropertySource Source
{
get { return _source; }
set { _source = value; }
}
}
这样就将用户的控件.ascx转成.uc的方式 重新写出来了。
解决了.ascx不能直接访问的问题。
web.config的<httpHandlers>节增加
<add verb="*" path="*.uc" type="Core.Web.UserControlRenderingHandler"/>
再到IIS6中增加映射
IIS7配置