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 - 看看我是否可以在那里设置标头,但这是空的 - 至少如果我在客户端代理方法中检查它。
您是否知道如何手动(破解)这些标头到位?
感谢您提供任何帮助......但完全明白这是不是没有点击。
答案 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();
}
}