您的位置:首页 > 其它

利用反射实现WSDL实体与自定义实体之间的转换

2011-05-30 17:54 483 查看
场景:

WebService中的传入/传出参数是一个字段非常多的一个对象,我们往往是在业务逻辑层来引用WebService,而值是从页面层传入的,因此需要自己定义一个实体,来实现页面层往业务逻辑层之间的传值。

如果两个实体之间字段非常多的话,可以利用反射来实现两个实体之间的转换。

首先,我们自定义一个Attribute,用于表示实体中某个属性,在WSDL中的名称(WSDL中的属性名称与自定义的不一定一致,比如用Java开发的WebService,在C#中调用,属性的编码规范不一样):

[AttributeUsage(AttributeTargets.All,AllowMultiple=true)]
publicclassWSDLFieldNameAttribute:Attribute
{
publicstringFieldName
{
get;
set;
}
publicTypeFieldType
{
get;
set;
}
publicWSDLFieldNameAttribute(stringField)
{
FieldName=Field;
FieldType=typeof(string);
}
publicWSDLFieldNameAttribute(stringField,Typetype)
{
FieldName=Field;
FieldType=type;
}
}


使用方法:

[WSDLFieldNameAttribute("fromDate")]
[Description("开始日期,格式“yyyyMMdd”")]
publicstringFromDate
{
get;
set;
}


转换类:

publicstaticclassWSDLFieldMappingUtil
{
///<summary>
///fillwsdlentityfromentity
///</summary>
///<paramname="wsdlObject"></param>
///<paramname="entity"></param>
publicstaticvoidFillInWSDLEntity(objectwsdlObject,objectentity)
{
TypewsdlType=wsdlObject.GetType();
TypeentityType=entity.GetType();

PropertyInfowsdlProperty;
PropertyInfo[]pi=entityType.GetProperties();

foreach(PropertyInfoentityPropertyinpi)
{
WSDLFieldNameAttribute[]myAttribute=(WSDLFieldNameAttribute[])entityProperty.GetCustomAttributes(typeof(WSDLFieldNameAttribute),false);
if(myAttribute.Length==0)
{
continue;
}

if(entityProperty.PropertyType.IsEnum)
{
if(myAttribute.Length==1&&myAttribute[0].FieldType==typeof(string))
{
wsdlProperty=wsdlType.GetProperty(myAttribute[0].FieldName);
if(wsdlProperty==null)
continue;

varvalue=entityProperty.GetValue(entity,null);
if(value!=null)
{
wsdlProperty.SetValue(wsdlObject,EnumAttributeHelper.GetSqlByEnum(value),null);
}
}
else
{
thrownewException(string.Empty);
}
}
else
{
wsdlProperty=wsdlType.GetProperty(myAttribute[0].FieldName);
if(wsdlProperty==null)
continue;

varvalue=entityType.GetProperty(entityProperty.Name).GetValue(entity,null);
if(value!=null)
{
if(wsdlProperty.PropertyType!=entityProperty.PropertyType)
{
if(wsdlProperty.PropertyType.IsEnum)
{
value=Enum.Parse(wsdlProperty.PropertyType,value.ToString());
}
elseif(entityProperty.PropertyType==typeof(DateTime))
{
value=((DateTime)value).ToString("yyyyMMdd");
}
else
{
value=Convert.ChangeType(value,wsdlProperty.PropertyType);
}
}

wsdlProperty.SetValue(wsdlObject,value,null);
}
else
{
if(wsdlProperty.PropertyType==typeof(string))
{
wsdlProperty.SetValue(wsdlObject,"",null);
}
}
}
}
}

///<summary>
///fillentityfromwsdlentity
///</summary>
///<paramname="wsdlObject"></param>
///<paramname="entity"></param>
publicstaticvoidFillInEntityFromWSDLObject(objectentity,objectwsdlObject)
{
if(wsdlObject==null)
return;

TypewsdlType=wsdlObject.GetType();
TypeentityType=entity.GetType();

PropertyInfowsdlProperty;
PropertyInfo[]pi=entityType.GetProperties();

foreach(PropertyInfoentityPropertyinpi)
{
WSDLFieldNameAttribute[]myAttribute=(WSDLFieldNameAttribute[])entityProperty.GetCustomAttributes(typeof(WSDLFieldNameAttribute),false);
if(myAttribute.Length==0)
{
continue;
}

if(entityProperty.PropertyType.IsEnum)
{
if(myAttribute.Length==1&&myAttribute[0].FieldType==typeof(string))
{
wsdlProperty=wsdlType.GetProperty(myAttribute[0].FieldName);
if(wsdlProperty==null)
continue;

varvalue=wsdlProperty.GetValue(wsdlObject,null);
if(value!=null&&value.ToString()!="")
{
entityProperty.SetValue(entity,EnumAttributeHelper.GetEnumBySqlValue(entityProperty,value.ToString()),null);
}
}
else
{
thrownewException(string.Empty);
}
}
else
{
wsdlProperty=wsdlType.GetProperty(myAttribute[0].FieldName);
if(wsdlProperty==null)
continue;

varvalue=wsdlProperty.GetValue(wsdlObject,null);
if(value!=null)
{
if(value.ToString()=="")
{
if(entityProperty.PropertyType==typeof(string))
{
entityProperty.SetValue(entity,value,null);
}
continue;
}

if(wsdlProperty.PropertyType!=entityProperty.PropertyType)
{
if(entityProperty.PropertyType==typeof(DateTime))
{
if(value.ToString().Length==8)
{
value=value.ToString().Substring(0,4)+"-"+value.ToString().Substring(4,2)+"-"+value.ToString().Substring(6,2);
}
}
value=Convert.ChangeType(value,entityProperty.PropertyType);
}

entityProperty.SetValue(entity,value,null);
}
}
}
}
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

上面代码需要注意的是,在某些时候,某个属性在传输的时候是以字符串的形式传输或者存储的,而在我们自定义的实体中,为了提高代码的可读性,而使用枚举

如:在数据库中存储的值分别是:O,C,P,D

publicenumDcoumentStatusEnum
{
[SqlValue("O")]
Open=0,
[SqlValue("C")]
Close=1,
[SqlValue("P")]
Paid=2,
[SqlValue("D")]
Delivered=3
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

因此需要对枚举做些特殊处理,自定义一个SqlValueAttribute:

[AttributeUsage(AttributeTargets.All)]
publicclassSqlValueAttribute:Attribute
{
publicstringText
{
get;
set;
}
publicSqlValueAttribute(stringtext)
{
Text=text;
}
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

利用反射,根据SqlValue获取枚举,或者根据枚举获取SqlValue,性能可能会比较低,暂时也没想出什么好的办法。

publicstaticobjectGetEnumBySqlValue(PropertyInfopInfo,stringsqlValue)
{
FieldInfo[]pi=pInfo.PropertyType.GetFields();
foreach(FieldInfopinpi)
{
SqlValueAttribute[]myAttribute=(SqlValueAttribute[])p.GetCustomAttributes(typeof(SqlValueAttribute),false);
foreach(SqlValueAttributeminmyAttribute)
{
if(m.Text==sqlValue.Trim())
{
stringa=p.ToString();
returnEnum.Parse(pInfo.PropertyType,p.Name);
}
}
}
returnnull;
}
publicstaticstringGetSqlByEnum(objectenumValue)
{
FieldInfo[]pi=enumValue.GetType().GetFields();
foreach(FieldInfopinpi)
{
if(p.Name==enumValue.ToString())
{
SqlValueAttribute[]myAttribute=(SqlValueAttribute[])p.GetCustomAttributes(typeof(SqlValueAttribute),false);
foreach(SqlValueAttributeminmyAttribute)
{
returnm.Text;
}
}
}
returnnull;
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: