Может ли метод WCF OperationContract атрибут WebGet иметь несколько типов ResponseFormat?
У меня есть ServiceContract, описывающий метод, используемый в службе WCF. Метод имеет атрибут WebGet, который определяет UriTemplate и ResponseFormat.
Я хочу повторно использовать один метод и иметь несколько атрибутов WebGet с разными UriTemplates и различными ResponseFormats. В основном я надеюсь избежать использования нескольких методов, чтобы различать такие вещи, как тип возврата, являющийся 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);
}
Используя вышеприведенный пример, я хотел бы использовать метод GetProduct для типов возвращаемого типа xml и json следующим образом:
[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?
Спасибо!
Ответы
Ответ 1
Вы можете сделать это
[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
Если я правильно помню, ниже метод работал у меня:
Контракт на обслуживание 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
(Извините, если есть ошибки в коде выше, я не запускал его для проверки).