【问题标题】:How to expose an Interface with WCF REST?如何使用 WCF REST 公开接口?
【发布时间】:2011-08-08 20:34:18
【问题描述】:
// 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 实现作为文本/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问题还是实现的问题……

【问题讨论】:

    标签: .net wcf-rest


    【解决方案1】:

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

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

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

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

    接口包含IFooIService

    Library 包含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 并让示例可以在某处下载。

    【讨论】:

    • @Spilarix 我做了一些实验,包括一些可怕的代码来注入带有修改设置的数据合约序列化程序。那没有达到预期的效果。不幸的是,到目前为止我还无法进一步调查:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    相关资源
    最近更新 更多