WCF responseformat 용 wekget
-
13-09-2019 - |
문제
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();
ResponseFormat의 옵션은 WebMessageFormat.json 및 webMessageFormat.xml입니다. 내 자신의 웹 메시지 형식을 작성할 수 있습니까? 클라이언트가 foo () 메소드를 호출 할 때 JSON 또는 XML 래퍼없이 원시 문자열을받습니다.
해결책
WebGetAttribute
Microsoft가 선적하면 확장 할 수 있다고 생각하지 않습니다. WebMessageFormat
. 그러나 당신은 아마도 확장 할 수 있습니다 WebHttpBinding
그것은 사용합니다 WebGetAttribute
. 자신의 속성을 추가 할 수 있습니다
[WebGet2(UriTemplate = "foo", ResponseFormat = WebMessageFormat2.PlainText)]
string Foo();
일반적으로 WCF에서 메시지 레이아웃을 사용자 정의하는 것을 사용자 정의 메시지 엔코더/인코딩이라고합니다. Microsoft는 예를 제공합니다. 사용자 정의 메시지 인코더 : 압축 인코더. 또한 사람들이하는 또 다른 일반적인 확장은 행동을 확장하여 사용자 정의 오류 처리를 추가하여 해당 방향으로 몇 가지 예를 찾을 수 있습니다.
다른 팁
사용해보십시오
BodyStyle = WebMessageBodyStyle.Bare
그런 다음 기능에서 System.io.stream을 반환하십시오.
다음은 데이터베이스에서 이미지를 반환하는 데 사용하지만 URL을 통해 액세스 할 수 있습니다.
[OperationContract()]
[WebGet(UriTemplate = "Person/{personID}/Image", BodyStyle = WebMessageBodyStyle.Bare)]
System.IO.Stream GetImage(string personID);
구현:
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);
}
귀하의 경우 원시 문자열을 반환하려면 ContentType를 "Text/Plain"과 같은 것으로 설정하고 데이터를 스트림으로 반환하십시오. 추측 할 때 다음과 같은 것 :
return new System.IO.MemoryStream(ASCIIEncoding.Default.GetBytes(string_to_send));
이 속성을 구현했는데 앞으로 누군가에게 도움이 될 것입니다.
[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();
}
}
HTTP를 다루는 경우이를 달성하는 방법이 있습니다. 정확히 좋지는 않지만 언급 할 수 있다고 생각했습니다.
메소드의 리턴 유형을 무효로 설정하고 원시 문자열을 응답에 직접 출력 할 수 있습니다.
[OperationContract]
[WebGet(UriTemplate = "foo")]
void Foo()
{
HttpContext.Current.Response.Write("bar");
}