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

时间:2009-11-17 05:49:46

标签: .net wcf

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

我想重用一个方法,并且具有多个具有不同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而编写不同的方法?

谢谢!

2 个答案:

答案 0 :(得分:12)

你可以这样做

[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;
        }
}

答案 1 :(得分:8)

如果我没记错的话,下面的方法对我有用:

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回复:http://yourServer/json/Operation/?param=value xml回复:http://yourServer/xml/Operation/?param=value

(抱歉,如果上面的代码中有任何错误,我没有运行它进行验证)。

相关问题