如何从Silverlight调用需要Headers的WCF服务

时间:2010-12-20 23:04:34

标签: silverlight wcf soap header

WCF 3.5 SP1服务/从Silverlight 4调用

在供应商创建了WCF API的情况下,既可以作为svc服务,也可以作为自定义代理客户端。

此API的两个方面都位于核心四层抽象之上。

首先有两个抽象的MessageContract类:WcfRequest和WcfResponse。

抽象WcfRequest类型包含使用MessageHeader属性修饰的属性,并包含自定义身份验证标识符和时区等内容。

然后是洋葱的第二层,每个方法分为两个类:GetSomethingRequest和GetSomethingResponse,两者分别从WcfRequest和WcfReponse继承。

接下来是实现层,其中基于WcfRequest和WcfResponse的类型冒泡并由自定义WcfClient类型调用,该类型控制所有ChannelFactory构造,建立绑定,最重要的是,在WcfRequest类型中设置标识符头基于先前在内存中设置的值(如会话密钥)。

最后是对ouside世界的看法,您可以通过id值请求POCO类型。

现在,API的编写方式如果我使用供应商提供的代理,事情将按预期工作 - 身份验证发生并设置此标识符,然后我可以调用方法调用没有问题。

如果你已经做到这一点,感谢你坚持下去。

现在,当我想使用“添加服务引用”或SLSvcUtil编写Silverlight客户端时,会出现问题,所生成的代理客户端类型都没有从WcfRequest标头设置这些标头属性,并且未在消息原型作为传入的参数。

要设置这些标头,我查看了Codeplex上的WCFExtras项目,并尝试使用ClientSoapHeaderHelper例程,但这对Silverlight不起作用(无扩展功能)。

我试图调查OperationContext - 看看我是否可以在那里设置标头,但这是空的 - 至少如果我在客户端代理方法中检查它。

您是否知道如何手动(破解)这些标头到位?

感谢您提供任何帮助......但完全明白这是不是没有点击。

1 个答案:

答案 0 :(得分:1)

我前一段时间遇到了自定义标题的问题...我基本上需要编写与内部类想要的文件略有不同(它是一个apache服务)。

这是我解决这个问题的方法(三个班级)。

在操作上下文中,我创建了一个HeaderSerializer类的新实例。这个类基于HeaderSerializerBase(我的类也是基于XmlObjectSerializer)。 HeaderSerializerBase使用WriteRaw基本上将任何字符串写入您喜欢的标题中(在我的情况下,它存储在应用程序中,但您可以动态地构建它没有问题)。

HTH:)

using (OperationContextScope ocs = new OperationContextScope(client.InnerChannel))
            {

                var ser = new HeaderSerializer();
                OperationContext.Current.OutgoingMessageHeaders.Add(MessageHeader.CreateHeader("SecurityHeader",
                                                                                               "http://somesite.com/schema",
                                                                                               authHeader, ser));                

                var req = new GetPredefinedSearchResultsRequest()
                              {
                                  Someproperty = somevalue
                              };

                client.GetPredefinedSearchResultsAsync(req);
            }




            public class HeaderSerializer : HeaderSerializerBase
            {
                public EPGHeaderSerializer()
                {
                    base.autheHeaderString = XamlingCore.Infrastructure.Resource.ResourceLoader.LoadStringResource("Assembly.Data", "RawHeaderData.txt");
                }
            }




            public class HeaderSerializerBase : XmlObjectSerializer
            {
                protected string autheHeaderString;

                public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
                {
                    throw new NotImplementedException();
                }

                public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
                {
                    writer.WriteRaw(autheHeaderString.ToCharArray(), 0, autheHeaderString.Length);
                }

                public override void WriteEndObject(XmlDictionaryWriter writer)
                {
                    throw new NotImplementedException();
                }

                public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
                {
                    throw new NotImplementedException();
                }

                public override bool IsStartObject(XmlDictionaryReader reader)
                {
                    throw new NotImplementedException();
                }
            }