Can a WCF OperationContract method's WebGet attribute have multiple ResponseFormat types?

前端 未结 2 1194
醉酒成梦
醉酒成梦 2021-02-01 21:50

I have a ServiceContract describing a method used in a WCF service. The method has a WebGet attribute which defines a UriTemplate and ResponseFormat.

I want to reuse a

相关标签:
2条回答
  • 2021-02-01 22:13

    You can do this

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

    And then in your code handle serialization based off the value specified on the parameter.

    For XML write a helper method that handles your serialization.

    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;
            }
    }
    
    0 讨论(0)
  • 2021-02-01 22:23

    If I remember correctly, below method worked for me:

    Contract for json service:

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

    Contact for xml service:

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

    Implementation for both:

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

    And web.config configuration (note endpoints for json and xml responses):

      <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>
    

    Now you can call your service like this: json response: http://yourServer/json/Operation/?param=value xml response: http://yourServer/xml/Operation/?param=value

    (Sorry if there are any bugs in code above, I didn't run it for verification).

    0 讨论(0)
提交回复
热议问题