[英]WCF ResponseFormat For WebGet
WCF offers two options for ResponseFormat attribute in WebGet annotation in ServiceContract. WCF在ServiceContract中的WebGet批注中为ResponseFormat属性提供了两个选项。
[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();
The options for ResponseFormat are WebMessageFormat.Json and WebMessageFormat.Xml. ResponseFormat的选项是WebMessageFormat.Json和WebMessageFormat.Xml。 Is it possible to write my own web message format? 是否可以编写自己的网络信息格式? I would like that when client calls foo() method he gets raw string - without json or xml wrappers. 我希望当客户端调用foo()方法时,他会获得原始字符串 - 没有json或xml包装器。
Try using 尝试使用
BodyStyle = WebMessageBodyStyle.Bare
Then return a System.IO.Stream from your function. 然后从函数返回System.IO.Stream。
Here's some code I use to return an image out of a database, but accessible via a URL: 这是我用来从数据库中返回图像的一些代码,但可以通过URL访问:
[OperationContract()]
[WebGet(UriTemplate = "Person/{personID}/Image", BodyStyle = WebMessageBodyStyle.Bare)]
System.IO.Stream GetImage(string personID);
Implementation: 执行:
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);
}
In your case, to return a raw string, set the ContentType to something like "text/plain" and return your data as a stream. 在您的情况下,要返回原始字符串,请将ContentType设置为“text / plain”之类的内容,并将数据作为流返回。 At a guess, something like this: 猜测,这样的事情:
return new System.IO.MemoryStream(ASCIIEncoding.Default.GetBytes(string_to_send));
WebGetAttribute
is shipped by Microsoft, and I don't think you can extend WebMessageFormat
. WebGetAttribute
由Microsoft提供,我认为您不能扩展WebMessageFormat
。 However you could probably extend the WebHttpBinding
that uses WebGetAttribute
. 但是你很可能延长WebHttpBinding
使用WebGetAttribute
。 You could add your own attribute like 您可以添加自己的属性
[WebGet2(UriTemplate = "foo", ResponseFormat = WebMessageFormat2.PlainText)]
string Foo();
In general, customizing the message layout in WCF is called custom message encoder/encoding. 通常,在WCF中自定义消息布局称为自定义消息编码器/编码。 Microsoft provides an example: Custom Message Encoder: Compression Encoder . Microsoft提供了一个示例: 自定义消息编码器:压缩编码器 。 Also another common extension people do is to extend behavior to add custom error handling, so you could look for some example in that direction. 人们另外做的另一个常见扩展是扩展行为以添加自定义错误处理,因此您可以在该方向上寻找一些示例。
I implemented this attribute like this, maybe it will help someone in the future: 我像这样实现了这个属性,也许它将来会有所帮助:
[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();
}
}
There is one way how to achieve this if you're dealing with HTTP, it's not exactly nice, but I thought I could mention it. 如果你正在处理HTTP,有一种方法可以实现这一点,它不是很好,但我想我可以提一下。
You can set the return type of your method to void and just output your raw string directly into the response. 您可以将方法的返回类型设置为void,并将原始字符串直接输出到响应中。
[OperationContract]
[WebGet(UriTemplate = "foo")]
void Foo()
{
HttpContext.Current.Response.Write("bar");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.