0
// 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问题还是实现问题......

4

1 回答 1

0

更新
好的,看来我最初的假设是错误的。即使正确设置了已知类型,我也会遇到与您相同的错误。显然,默认情况下不使用 DataContractSerializer,添加行为以选择自定义序列化程序对 REST 端点没有影响。我需要做一些进一步的挖掘......

原帖
在服务契约中使用接口有点复杂,因为最终需要将数据反序列化为具体类型:接口无法实例化。

解决方案的关键是一种称为已知类型的东西。DataContractSerializer 需要了解它在(反)序列化期间可能遇到的任何具体类型。

我创建了一个包含 4 个不同项目的小示例。ClientApp、接口、库和服务。

接口包含IFooIService

包含FooImpl,因为客户端和服务器都需要访问此类型。然而,这个库是“可插拔的”。您可以即时添加更多实现IFoo

猜猜ServiceClientApp包含什么:)

服务契约需要特殊的 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 并使示例可在某处下载。

于 2011-04-19T20:56:06.760 回答