对用户控件的访问方式重写

因为项目里面需要记录一下重写的方法以备后用

首先增加一个继承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配置

对用户控件的访问方式重写

你可能感兴趣的:(用户)