using System;
using System.ComponentModel;
using System.Reflection;
using System.Web;
namespace Examples.WebParams
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
public class WebParameterAttribute : Attribute
{
string _default;
string _name;
bool _isRequired;
bool _isDefaultForInvalid;
int _maxLength = -1;
int _minLength = -1;
public WebParameterAttribute()
{
}
public WebParameterAttribute(string paramName)
{
_name = paramName;
}
public string ParameterName
{
get{ return _name; }
set{ _name=value; }
}
public string DefaultValue
{
get{ return _default ; }
set{ _default=value ; }
}
public bool IsRequired
{
get{ return _isRequired; }
set{ _isRequired=value; }
}
public bool IsDefaultUsedForInvalid
{
get{ return _isDefaultForInvalid; }
set{ _isDefaultForInvalid=value; }
}
public int MaxLength
{
get { return _maxLength; }
set { _maxLength = value; }
}
protected virtual string GetValue(string paramName, System.Web.HttpRequest request)
{
if (request.HttpMethod.ToLower()=="post")
return request.Form[paramName];
else
return request.QueryString[paramName];
}
public static void SetValues(object target, System.Web.HttpRequest request)
{
System.Type type = target.GetType();
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
MemberInfo[] members = new MemberInfo[fields.Length + properties.Length];
fields.CopyTo(members, 0);
properties.CopyTo(members, fields.Length);
for(int f=0;f0)
{
if (member.MemberType==MemberTypes.Property)
{
ParameterInfo[] ps = ((PropertyInfo)member).GetIndexParameters();
if (ps!=null && ps.Length>0)
throw new NotSupportedException("Cannot apply WebParameterAttribute to indexed property");
}
attrib = attribs[0];
paramName = (attrib.ParameterName!=null) ? attrib.ParameterName : member.Name;
paramValue = attrib.GetValue(paramName, request);
usingDefault = false;
if (paramValue == null)
{
if (attrib.DefaultValue!=null)
{
paramValue = attrib.DefaultValue;
usingDefault = true;
}
else if (!attrib.IsRequired)
return; // Just skip the member
else
throw new Exception("Missing required parameter");
}
if(attrib.MaxLength >= 0 && paramValue.Length > attrib.MaxLength)
throw new Exception(string.Format("parametr more then {0} symbols", attrib.MaxLength));
converter=TypeDescriptor.GetConverter(GetMemberUnderlyingType(member));
if (converter==null || !converter.CanConvertFrom(paramValue.GetType()))
throw new Exception(String.Format("Could not convert from {0}", paramValue.GetType()));
try
{
typedValue=converter.ConvertFrom(paramValue);
SetMemberValue(member, target, typedValue);
}
catch
{
if (!usingDefault && attrib.IsDefaultUsedForInvalid && attrib.DefaultValue!=null)
{
typedValue=converter.ConvertFrom(attrib.DefaultValue);
SetMemberValue(member, target, typedValue);
}
else
throw;
}
}
}
catch(Exception err)
{
throw new ApplicationException("Property/field {0} could not be set from request - " + err.Message, err);
}
}
private static void SetMemberValue(MemberInfo member, object target, object value)
{
switch(member.MemberType)
{
case MemberTypes.Field:
((FieldInfo)member).SetValue(target, value);
break;
case MemberTypes.Property:
((PropertyInfo)member).SetValue(target, value, new Object[0]);
break;
}
}
private static Type GetMemberUnderlyingType(MemberInfo member)
{
switch(member.MemberType)
{
case MemberTypes.Field:
return ((FieldInfo)member).FieldType;
case MemberTypes.Property:
return ((PropertyInfo)member).PropertyType;
default:
throw new ArgumentException("Expected a FieldInfo or PropertyInfo", "member");
}
}
}