如何使用WCF REST公开接口?

时间:2011-04-19 16:51:08

标签: .net wcf-rest

// 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问题......

1 个答案:

答案 0 :(得分:0)

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

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

解决方案的关键是称为已知类型。 DataContractSerializer需要知道在(反)序列化过程中可能遇到的任何具体类型。

我创建了一个由4个不同项目组成的小样本。 ClientApp,接口,库和服务。

界面包含IFooIService

包含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并将样本下载到某个地方。