2009-06-14 2 views
21

WCF는 ServiceContract의 WebGet 주석에 ResponseFormat 특성에 대한 두 가지 옵션을 제공합니다.WCF ResponseFormat WebGet의 경우

[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 래퍼없이 원시 문자열을 얻길 바랍니다.

답변

8

WebGetAttribute은 Microsoft에서 배송하며 WebMessageFormat을 확장 할 수 있다고 생각하지 않습니다. 그러나 WebGetAttribute을 사용하는 WebHttpBinding을 확장 할 수 있습니다.

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

일반적으로 WCF에서 메시지 레이아웃을 사용자 지정하는 것을 사용자 지정 메시지 인코더/인코딩이라고합니다. Microsoft는 예 : Custom Message Encoder: Compression Encoder을 제공합니다. 또한 사용자가 수행하는 또 다른 공통 확장은 사용자 정의 오류 처리를 추가하기 위해 동작을 확장하므로 해당 방향으로 몇 가지 예를 찾을 수 있습니다.

BodyStyle = WebMessageBodyStyle.Bare 

그런 다음 함수에서 System.IO.Stream을 반환하여

45

보십시오.

여기에 몇 가지 내가 데이터베이스에서 이미지를 반환하는 데 사용하는 코드 만 접근은 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)); 
+4

니스 :

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

0

당신이 HTTP를 처리하는 경우이, 정확히 좋은 아니다 달성하는 방법을 한 가지 방법이 있습니다,하지만 난 그것을 언급 수 있다고 생각.

메서드의 반환 형식을 void로 설정하고 원시 문자열을 응답에 직접 출력 할 수 있습니다.

[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(); 
    } 
} 
2

나는 어쩌면 미래에 사람을 도움이 될 것 같은이 속성을 구현했습니다. 그것은 작동합니다 - WebMessageFormat.Raw가 있어야하는 것처럼 보입니다. 감사.