// Service file
[WebInvoke(UriTemplate = "Send/{country}", Method = "POST")]
public int Send(IFoo item, string country)
// Interface file
public interface IFoo
{
string firstMember { get; set; }
string secondMember { get; set; }
}
// Implementation file
public class FooImpl : IFoo
{
string specificMember { get; set; }
}
我使用http://example.com/MyService/Send/ {COUNTRY} /
的帖子调用我的REST服务
我希望能够将IFoo实现作为text / xml参数提供,例如:
<FooImpl xmlns="http://schemas.datacontract.org/2004/07/Hello">
<firstMember>Hello</firstMember>
<secondMember>World</secondMember>
<SpecificMember>!</SpecificMember>
</FooImpl>
当我在Send方法声明中声明FooImpl类型时它起作用,但是当我使用IFoo类型时它不起作用。(错误400:错误请求)
服务助手显示:
<anyType xmlns:d1="http://www.w3.org/2001/XMLSchema" i:type="d1:schema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/" />
所以,我不知道我的参数或实现问题是否是xml问题......
答案 0 :(得分:0)
<强>更新强>:
好吧,似乎我原来的假设是错误的。即使已正确设置了已知类型,我也会得到与您相同的错误。显然,默认情况下不使用DataContractSerializer,添加行为以选择自定义序列化程序对REST端点没有影响。我需要进一步挖掘...
原帖:
在服务契约中使用接口有点复杂,因为最终需要将数据反序列化为具体类型:接口无法实例化。
解决方案的关键是称为已知类型。 DataContractSerializer需要知道在(反)序列化过程中可能遇到的任何具体类型。
我创建了一个由4个不同项目组成的小样本。 ClientApp,接口,库和服务。
界面包含IFoo
和IService
。
库包含FooImpl
,因为客户端和服务器都需要访问此类型。然而,这个库是“可插拔的”。您可以动态添加IFoo
的更多实现。
猜猜服务和 ClientApp 包含:)
服务合同需要特殊的KnownTypeAttribute:
[ServiceContract]
[ServiceKnownType(typeof(IFoo))]
public interface IService
{
[OperationContract]
string GetData(IFoo value);
}
现在,您可以在客户端和服务器上配置在App.config中实现IFoo的具体类型(或其任何名称):
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="Interface.IFoo, Interface">
<knownType type="Library.FooImpl, Library" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
如果您不需要这种可插拔结构,则应该可以使用
[KnownType(typeof(FooImpl))]
而不是整个复杂的结构。
如果我能找到明天的时间,我会用这个来测试WCF REST并将样本下载到某个地方。