如何在 Silverlight 中使用使用 ProtoBuf-net 序列化器的 WCF 服务?

发布于 2024-12-11 19:05:57 字数 2123 浏览 0 评论 0原文

现在是凌晨 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

并安 2024-12-18 19:05:57

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.

梦里人 2024-12-18 19:05:57

是的,这是一种痛苦。卡洛斯对此有一个很好的答案,但减少的选项可能是“通过 WCF 边界传输 byte[]Stream,并手动处理序列化/反序列化”。在大多数情况下,这是对 Serializer.* 方法的单行调用,因此并不太棘手。

Yes, it is a pain. Carlos has an excellent answer on this, but a reduced option might be "transfer byte[] or Stream over the WCF boundary, and handle the serialize/deserialize manually". In most cases this is a single-line call to a Serializer.* method, so not overly tricky.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文