代码之家  ›  专栏  ›  技术社区  ›  Ian Suttle

wcf operationcontract方法的webget属性是否可以具有多个responseformat类型?

  •  17
  • Ian Suttle  · 技术社区  · 15 年前

    我有一个ServiceContract,它描述了在WCF服务中使用的方法。该方法有一个定义uritemplate和responseformat的webget属性。

    我希望重用一个方法,并拥有多个具有不同uritemplates和不同responseformat的webget属性。基本上,我希望避免使用多个方法来区分返回类型是xml还是json。到目前为止,在我看到的所有示例中,我都需要为每个webget属性创建一个不同的方法。这是一份操作合同样本

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

    有没有办法做到这一点,让我不必为了返回不同的响应格式而编写不同的方法?

    谢谢!

    2 回复  |  直到 12 年前
        1
  •  12
  •   Bill the Lizard    14 年前

    你可以这么做

    [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;
            }
    }
    
        2
  •  8
  •   tomaszm    14 年前

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

    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

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

    推荐文章