【发布时间】:2011-01-20 00:12:48
【问题描述】:
如何将 DataContractSurrogate 用于我的 WCF REST 服务(使用 WebServiceHostFactory 托管)?
我没有看到添加方法,即使我添加了自定义 IOperationBehavior,WebServiceHost 也会自动覆盖并忽略它。
【问题讨论】:
标签: .net wcf datacontractserializer datacontract
如何将 DataContractSurrogate 用于我的 WCF REST 服务(使用 WebServiceHostFactory 托管)?
我没有看到添加方法,即使我添加了自定义 IOperationBehavior,WebServiceHost 也会自动覆盖并忽略它。
【问题讨论】:
标签: .net wcf datacontractserializer datacontract
您可以通过以下两个步骤来实现:
首先,实现IDatacontractSurrogate接口:
class MySurrogate : IDataContractSurrogate
{
public Type GetDataContractType(Type type)
{
//Implementation here
}
public object GetObjectToSerialize(object obj, Type targetType)
{
//Implementation here
}
//Implemenentation of the remaining methods...
}
其次,像这样在 ServiceHost 上设置您的代理:
foreach (var endpoint in serviceHost.Description.Endpoints)
{
foreach (var operation in endpoint.Contract.Operations)
{
operation.Behaviors.Find<DataContractSerializerOperationBehavior>().DataContractSurrogate = new MySurrogate();
}
}
请记住在打开服务主机之前执行此操作。否则可能无法正常工作。
如果您使用 IIS 托管并在 .svc 文件中指定 WebServiceHostFactory,那么可以理解,您没有机会设置代理项。为了克服这个问题,您有两种选择:
创建自定义服务行为属性并在其ApplyDispatchBehavior() 方法中设置代理项。一旦您将此属性放在您的服务上,WCF 将自动执行此方法并设置代理项。
Create 通过子类化 WebServiceHost 您自己的自定义服务主机。然后在其ApplyConfiguration() 方法中设置代理项。这也会产生同样的效果。
【讨论】:
我设法让它工作:使用 IIS 中的 WebServiceHostFactory 托管的 WCF 4.0 REST 服务。
我使用自定义属性来注入我的 NHProxyDataContractSurrogate:
public class CanSerializeNHProxyAttribute : Attribute, IContractBehavior
{
public void ApplyClientBehavior(ContractDescription description, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime proxy)
{
foreach (OperationDescription opDesc in description.Operations)
{
ApplyDataContractSurrogate(opDesc);
}
}
public void ApplyDispatchBehavior(ContractDescription description, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatch)
{
foreach (OperationDescription opDesc in description.Operations)
{
ApplyDataContractSurrogate(opDesc);
}
}
private static void ApplyDataContractSurrogate(OperationDescription description)
{
DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dcsOperationBehavior != null)
{
if (dcsOperationBehavior.DataContractSurrogate == null)
dcsOperationBehavior.DataContractSurrogate = new NHProxyDataContractSurrogate();
}
}
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint serviceEndPoint, BindingParameterCollection parameters) { }
public void Validate(ContractDescription contractDescription, ServiceEndpoint serviceEndPoint) { }
}
并将自定义属性应用到我的 ServiceContract:
[ServiceContract]
[CanSerializeNHProxy]
public interface IElementManager
{ ... }
我从这些链接中获得了很多有用的信息:
DataContractSurrogate MSDN page, pointing to custom attribute
DataContractSurrogate implementation for serializing NHibernate proxy objects
希望这会有所帮助。
【讨论】: