WCF OperationContracte方法的WebGet属性可以有多个ResponseFormat类型吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (25)

我有一个描述在WCF服务中使用的方法的ServiceContract。该方法具有定义UriTemplate和ResponseFormat的WebGet属性。

我想重用一个方法,并有不同的UriTemplates和不同的ResponseFormats的多个WebGet属性。基本上我希望避免使用多种方法来区分返回类型是XML还是JSON。在我见过的所有例子中,我都需要为每个WebGet属性创建一个不同的方法。这是一个示例OperationContract

[ServiceContract]
public interface ICatalogService
{
    [OperationContract]
    [WebGet(UriTemplate = "product/{id}/details?format=xml", ResponseFormat = WebMessageFormat.Xml)]
    Product GetProduct(string id);

    [OperationContract]
    [WebGet(UriTemplate = "product/{id}/details?format=json", ResponseFormat = WebMessageFormat.Json)]
    Product GetJsonProduct(string id);
}

使用上面的例子,我想为这样的xml和json返回类型使用GetProduct方法:

[ServiceContract]
public interface ICatalogService
{
    [OperationContract]
    [WebGet(UriTemplate = "product/{id}/details?format=xml", ResponseFormat = WebMessageFormat.Xml)]
    [WebGet(UriTemplate = "product/{id}/details?format=json", ResponseFormat = WebMessageFormat.Json)]
    Product GetProduct(string id);
}

有没有办法实现这一点,所以我不会坚持写不同的方法来返回不同的ResponseFormats?

提问于
用户回答回答于

如果我没有记错,下面的方法适用于我:

JSON服务合同:

[ServiceContract]
public interface IServiceJson {
  [OperationContract()]
  [WebGet(UriTemplate = "Operation/?param={param}",
                         ResponseFormat = WebMessageFormat.Json)]
  ReturnType Operation(string param);
}

联系人xml服务:

[ServiceContract]
public interface IServiceXml {
  [OperationContract(Name = "OperationX")]
  [WebGet(UriTemplate = "Operation/?param={param}",
                         ResponseFormat = WebMessageFormat.Xml)]
  ReturnType Operation(string param);
}

两者的实施:

public class ServiceImplementation : IServiceJson, IServiceXml {
  ReturnType Operation(string param) {
    // Implementation
  }
}

和web.config配置(注意json和xml响应的端点):

  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttp">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="serviceBehaviour">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="serviceBehaviour" name="ServiceImplementation">
        <endpoint address="json/" behaviorConfiguration="webHttp" binding="webHttpBinding"
         bindingConfiguration="webHttpBindingSettings" contract="IServiceJson">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="xml/" behaviorConfiguration="webHttp" binding="webHttpBinding"
         bindingConfiguration="webHttpBindingSettings" contract="IServiceXml">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingSettings">
          <readerQuotas maxStringContentLength="5000000"/>
        </binding>
      </webHttpBinding>
    </bindings>
  </system.serviceModel>

现在你可以像这样调用你的服务:json response:http:// yourServer / json / Operation /?param = value xml response:http:// yourServer / xml / Operation /?param = value

用户回答回答于

你可以这样做

[ServiceContract]
public interface ICatalogService
{
    [OperationContract]
    [WebGet(UriTemplate = "product/{id}/details?format={format}")]
    Stream GetProduct(string id, string format);
}

然后在你的代码中基于参数指定的值处理序列化。

对于XML编写处理序列化的帮助器方法。

public static Stream GetServiceStream(string format, string callback, DataTable dt, SyndicationFeed sf)
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
            if (format == "xml")
            {
                XmlSerializer xmls = new XmlSerializer(typeof(DataTable));
                xmls.Serialize(writer, dt);
                WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
            }
            else if (format == "json")
            {
                var toJSON = new JavaScriptSerializer();
                toJSON.RegisterConverters(new JavaScriptConverter[] { new JavaScriptDataTableConverter() });
                writer.Write(toJSON.Serialize(dt));
                WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";
            }
            else if (format == "jsonp")
            {
                var toJSON = new JavaScriptSerializer();
                toJSON.RegisterConverters(new JavaScriptConverter[] { new JavaScriptDataTableConverter() });
                writer.Write(callback + "( " + toJSON.Serialize(dt) + " );");
                WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";
            }
            else if (format == "rss")
            {
                XmlWriter xmlw = new XmlTextWriter(writer);
                sf.SaveAsRss20(xmlw);
                WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
            }
            else if (format == "atom")
            {
                XmlWriter xmlw = new XmlTextWriter(writer);
                sf.SaveAsAtom10(xmlw);
                WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
            }
            else
            {
                writer.Write("Invalid formatting specified.");
                WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
            }

            writer.Flush();
            stream.Position = 0;
            return stream;
        }
}

扫码关注云+社区