如何在 Silverlight 中使用使用 ProtoBuf-net 序列化器的 WCF 服务?
现在是凌晨 2 点,我整个晚上都在试图弄清楚这个问题:如何在 Silverlight 中使用使用 ProtoBuf-net 序列化器的 WCF 服务?
只是为了澄清一件事:从我的测试控制台应用程序调用服务时,它们运行得很好。
顶级服务是通过使用 BasicHttpEndpoint 公开的(为了兼容性),但如果这能解决我的问题,我对其他绑定非常开放。
无论如何,在 .NET(不是 Silverlight)中,我可以按如下方式使用服务:
我有一个通用方法 GetService,它为我创建服务:
... Code removed ...
EndpointAddress endpointAddress = new EndpointAddress(address);
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential)
{
MaxReceivedMessageSize = int.MaxValue,
MaxBufferSize = int.MaxValue,
};
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
ContractDescription contract = ContractDescription.GetContract(typeof(TServiceType));
ServiceEndpoint serviceEndpoint = new ServiceEndpoint(contract, binding, new EndpointAddress(address));
factory = new ChannelFactory<TServiceType>(serviceEndpoint);
AddBehaviors(serviceEndpoint);
ClientCredentials defaultCredentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();
factory.Endpoint.Behaviors.Remove(defaultCredentials);
factory.Endpoint.Behaviors.Add(credentials);
... Code removed ...
然后提取 AddBehavior 方法:
private static void AddBehaviors(ServiceEndpoint serviceEndpoint, int maxItemsInObjectGraph = int.MaxValue)
{
foreach (OperationDescription operation in serviceEndpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior operationBehavior = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (operationBehavior != null)
{
operation.Behaviors.Remove(operationBehavior);
}
ProtoOperationBehavior protoOperationBehavior = operation.Behaviors.Find<ProtoOperationBehavior>();
if (protoOperationBehavior == null)
{
protoOperationBehavior = new ProtoOperationBehavior(operation);
operation.Behaviors.Add(protoOperationBehavior);
}
protoOperationBehavior.MaxItemsInObjectGraph = int.MaxValue;
}
}
不幸的是,在 Silverlight 中不可能执行此操作:(所以我需要一些其他方法来实现同样的目标,现在我很感激任何建议!
It's 2am, and I've been trying to figure out this the whole evening: How do I consume an WCF service in Silverlight which uses the ProtoBuf-net serializer?
Just to clarify one thing: The service(s) works great when calling them from my test console app.
The top level service is exposed by using the BasicHttpEndpoint (for compability), but I'm very open for other bindings if that solves my problem.
Anyway, in .NET (not Silverlight) I can consume the services as follows:
I have an generic method, GetService, which creates the service for me:
... Code removed ...
EndpointAddress endpointAddress = new EndpointAddress(address);
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential)
{
MaxReceivedMessageSize = int.MaxValue,
MaxBufferSize = int.MaxValue,
};
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
ContractDescription contract = ContractDescription.GetContract(typeof(TServiceType));
ServiceEndpoint serviceEndpoint = new ServiceEndpoint(contract, binding, new EndpointAddress(address));
factory = new ChannelFactory<TServiceType>(serviceEndpoint);
AddBehaviors(serviceEndpoint);
ClientCredentials defaultCredentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();
factory.Endpoint.Behaviors.Remove(defaultCredentials);
factory.Endpoint.Behaviors.Add(credentials);
... Code removed ...
Then the AddBehavior method is extracted:
private static void AddBehaviors(ServiceEndpoint serviceEndpoint, int maxItemsInObjectGraph = int.MaxValue)
{
foreach (OperationDescription operation in serviceEndpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior operationBehavior = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (operationBehavior != null)
{
operation.Behaviors.Remove(operationBehavior);
}
ProtoOperationBehavior protoOperationBehavior = operation.Behaviors.Find<ProtoOperationBehavior>();
if (protoOperationBehavior == null)
{
protoOperationBehavior = new ProtoOperationBehavior(operation);
operation.Behaviors.Add(protoOperationBehavior);
}
protoOperationBehavior.MaxItemsInObjectGraph = int.MaxValue;
}
}
Unfortunately it's not possible to do this in Silverlight:( So I need some other way to achieve the same thing, and right now I'm stuck. Any suggestions is highly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Silverlight 没有
DataContractSerializerOperationBehavior
类(它是内部的),因此您不能使用“传统”方式替换序列化器。这是可以做到的,但需要很多步骤。我在 http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/24/wcf-extensibility-custom-serialization-in-silverlight.aspx。Silverlight doesn't have the
DataContractSerializerOperationBehavior
class (it's internal), so you can't use the "traditional" way of replacing the serializer. It's possible to do, but it requires a lot of steps. I published one way of doing it in the post at http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/24/wcf-extensibility-custom-serialization-in-silverlight.aspx.是的,这是一种痛苦。卡洛斯对此有一个很好的答案,但减少的选项可能是“通过 WCF 边界传输
byte[]
或Stream
,并手动处理序列化/反序列化”。在大多数情况下,这是对Serializer.*
方法的单行调用,因此并不太棘手。Yes, it is a pain. Carlos has an excellent answer on this, but a reduced option might be "transfer
byte[]
orStream
over the WCF boundary, and handle the serialize/deserialize manually". In most cases this is a single-line call to aSerializer.*
method, so not overly tricky.