jos*_*rry 12 .net c# types web-services coerce
我已经开始为FedEx的webservice API编写一个接口.他们有3种不同的API,我很感兴趣; 费率,发货和跟踪.我正在使用SvcUtil.exe生成服务代理.
FedEx在自己的WSDL文件中指定了不同的服务端点.每个服务端点都有自己的xml命名空间(例如http://fedex.com/ws/rate/v5和http://fedex.com/ws/ship/v5)
服务端点确实使用了相当多的相同类型,例如Address,Measurements,Weight,AuthenticationDetail,ClientDetail等......
这就是问题所在,我可以同时向SvcUtil.exe提供所有WSDL文件,通常它会将任何相同的类型合并为一个共享类型,但由于FedEx的每个服务都在它们自己的命名空间中,他们在该命名空间下的每个WSDL文件中重新声明这些类型,而不是每个命名空间的Address,Address1和Address2.
为了解决这个问题,我现在要做的是分别通过svcutil运行每个WSDL,并将它们分别放在自己的.NET命名空间中(例如FedEx.Rate,FedEx.Ship,FedEx.Track).这个问题是现在我在每个命名空间中都有一个不同的地址类型(Fedex.Rate.Address,FedEx.Ship.Address).
这使得很难概括像GetAuthenticationDetail()工厂方法之类的服务之间使用的代码,因此我不必在每个使用不同服务的地方重复该代码.
在C#中是否有任何方法可以将FedEx.Rate.Address强制转换为FedEx.Ship.Address?
如果类型相同,并且您可以控制源类,则可以在类中定义转换运算符,并且任何带有Rate.Address意志的函数也会自动获取Ship.Address.例如:
namespace Rate {
class Address {
string Street;
string City;
// ...
public static implicit operator Ship.Address(Rate.Address addr) {
Ship.Address ret;
ret.Street = addr.Street;
ret.City = addr.City;
// ...
return ret;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的C#有点生疏,但我希望你明白这个想法.
所以这是我如何使用反射实现隐式转换运算符.SvcUtil创建了部分类,因此我为每个转换方向添加了一个隐式转换运算符,因此在客户端代码中您只需键入即可Type1 = Type2.
在这个片段中,WebAuthenticationCredentials是WebAuthenticationDetails的一个属性,因此如果类型不同(内置函数),则迭代源对象的属性时,它会检查类型的名称(没有命名空间),并使用这些属性递归调用复制函数.
internal class ReflectionCopy
{
public static ToType Copy<ToType>(object from) where ToType : new()
{
return (ToType)Copy(typeof(ToType), from);
}
public static object Copy(Type totype, object from)
{
object to = Activator.CreateInstance(totype);
PropertyInfo[] tpis = totype.GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo[] fpis = from.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
// Go through each property on the "to" object
Array.ForEach(tpis, tpi =>
{
// Find a matching property by name on the "from" object
PropertyInfo fpi = Array.Find(fpis, pi => pi.Name == tpi.Name);
if (fpi != null)
{
// Do the source and destination have identical types (built-ins)?
if (fpi.PropertyType == tpi.PropertyType)
{
// Transfer the value
tpi.SetValue(to, fpi.GetValue(from, null), null);
}
else
{
// If type names are the same (ignoring namespace) copy them recursively
if (fpi.PropertyType.Name == tpi.PropertyType.Name)
tpi.SetValue(to, Copy(fpi.PropertyType, tpi.GetValue(from, null)), null);
}
}
});
return to;
}
}
namespace Rate
{
partial class WebAuthenticationDetail
{
public static implicit operator Ship.WebAuthenticationDetail(WebAuthenticationDetail from)
{
return ReflectionCopy.Copy<Ship.WebAuthenticationDetail>(from);
}
}
partial class WebAuthenticationCredential
{
public static implicit operator Ship.WebAuthenticationCredential(WebAuthenticationCredential from)
{
return ReflectionCopy.Copy<Ship.WebAuthenticationCredential>(from);
}
}
}
namespace Ship
{
partial class WebAuthenticationDetail
{
public static implicit operator Rate.WebAuthenticationDetail(WebAuthenticationDetail from)
{
return ReflectionCopy.Copy<Rate.WebAuthenticationDetail>(from);
}
}
partial class WebAuthenticationCredential
{
public static implicit operator Rate.WebAuthenticationCredential(WebAuthenticationCredential from)
{
return ReflectionCopy.Copy<Rate.WebAuthenticationCredential>(from);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3018 次 |
| 最近记录: |