c# wcf webget responseformat

c# - WCF ResponseFormat para WebGet



(4)

Hay una manera de lograr esto si se trata de HTTP, no es exactamente bueno, pero pensé que podría mencionarlo.

Puede establecer que el tipo de devolución de su método se anule y simplemente envíe su cadena sin procesar directamente a la respuesta.

[OperationContract] [WebGet(UriTemplate = "foo")] void Foo() { HttpContext.Current.Response.Write("bar"); }

WCF ofrece dos opciones para el atributo ResponseFormat en la anotación WebGet en ServiceContract.

[ServiceContract] public interface IService1 { [OperationContract] [WebGet(UriTemplate = "greet/{value}", BodyStyle = WebMessageBodyStyle.Bare)] string GetData(string value); [OperationContract] [WebGet(UriTemplate = "foo", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)] string Foo();

Las opciones para ResponseFormat son WebMessageFormat.Json y WebMessageFormat.Xml. ¿Es posible escribir mi propio formato de mensaje web? Me gustaría que cuando el cliente llama al método foo () obtiene una cadena sin formato, sin envoltorios json o xml.


Implementé este atributo así, tal vez ayudará a alguien en el futuro:

[AttributeUsage(AttributeTargets.Method)] public class WebGetText : Attribute, IOperationBehavior { public void Validate(OperationDescription operationDescription) { } public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { dispatchOperation.Formatter = new Formatter(dispatchOperation.Formatter); } public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { } public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { } } public class Formatter : IDispatchMessageFormatter { IDispatchMessageFormatter form; public Formatter (IDispatchMessageFormatter form) { this.form = form; } public void DeserializeRequest(Message message, object[] parameters) { form.DeserializeRequest(message, parameters) } public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) { IEnumerable<object> cl = (IEnumerable<object>)result; StringBuilder csvdata = new StringBuilder(); foreach (object userVariableClass in cl) { Type type = userVariableClass.GetType(); PropertyInfo[] fields = type.GetProperties(); // Dim header As String = String.Join(";", fields.Select(Function(f) f.Name + ": " + f.GetValue(userVariableClass, Nothing).ToString()).ToArray()) // csvdata.AppendLine("") // csvdata.AppendLine(header) csvdata.AppendLine(ToCsvFields(";", fields, userVariableClass)); csvdata.AppendLine(""); csvdata.AppendLine("=====EOF====="); csvdata.AppendLine(""); } Message msg = WebOperationContext.Current.CreateTextResponse(csvdata.ToString()); return msg; } public static string ToCsvFields(string separator, PropertyInfo[] fields, object o) { StringBuilder linie = new StringBuilder(); foreach (PropertyInfo f in fields) { if (linie.Length > 0) { } object x = f.GetValue(o, null); if (x != null) { linie.AppendLine(f.Name + ": " + x.ToString()); } else { linie.AppendLine(f.Name + ": Nothing"); } } return linie.ToString(); } }


Intenta usar

BodyStyle = WebMessageBodyStyle.Bare

A continuación, devuelve un System.IO.Stream de su función.

Aquí hay un código que utilizo para devolver una imagen de una base de datos, pero accesible a través de una URL:

[OperationContract()] [WebGet(UriTemplate = "Person/{personID}/Image", BodyStyle = WebMessageBodyStyle.Bare)] System.IO.Stream GetImage(string personID);

Implementación:

public System.IO.Stream GetImage(string personID) { // parse personID, call DB OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse; if (image_not_found_in_DB) { context.StatusCode = System.Net.HttpStatusCode.Redirect; context.Headers.Add(System.Net.HttpResponseHeader.Location, url_of_a_default_image); return null; } // everything is OK, so send image context.Headers.Add(System.Net.HttpResponseHeader.CacheControl, "public"); context.ContentType = "image/jpeg"; context.LastModified = date_image_was_stored_in_database; context.StatusCode = System.Net.HttpStatusCode.OK; return new System.IO.MemoryStream(buffer_containing_jpeg_image_from_database); }

En su caso, para devolver una cadena sin formato, configure ContentType a algo así como "texto / normal" y devuelva sus datos como una secuencia. En una suposición, algo como esto:

return new System.IO.MemoryStream(ASCIIEncoding.Default.GetBytes(string_to_send));


WebGetAttribute es enviado por Microsoft, y no creo que pueda extender WebMessageFormat . Sin embargo, probablemente podría extender el WebHttpBinding que usa WebGetAttribute . Podría agregar su propio atributo como

[WebGet2(UriTemplate = "foo", ResponseFormat = WebMessageFormat2.PlainText)] string Foo();

En general, la personalización del diseño del mensaje en WCF se llama codificador / codificación de mensaje personalizado. Microsoft proporciona un ejemplo: Encoder de mensajes personalizados: Encoder de compresión . También otra extensión común que las personas hacen es extender el comportamiento para agregar un manejo de error personalizado, por lo que podría buscar algún ejemplo en esa dirección.