2013-01-11 5 views
5

을 통해 제작 클라이언트에서 모든 매개 변수 나는이 그래서 내가 SSCCE간단한 WCF 서비스, 서비스

내가이 간단한 WCF 서비스를 만들어 물어 정확히 어떻게 확신하지 못했습니다

[ServiceContract] 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
public class EmailService 
{ 
    [WebInvoke(UriTemplate = "/SendEmail", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Xml)] 
    public bool SendEmail(EmailData data) 
    { 
     try 
     { 
      byte[] fileBinaryContents = Convert.FromBase64String(data.Enc64FileContents); 
      File.WriteAllBytes(data.FileName, fileBinaryContents); 
      return true; 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 
} 

[DataContract(Namespace = "http://somenamespace/")] 
public class EmailData 
{ 
    [DataMember] 
    public string FileName { get; set; } 

    [DataMember] 
    public string EmailAddress { get; set; } 

    [DataMember] 
    public string Enc64FileContents { get; set; } 
} 

및 Winforms 클라이언트가 webservice 메서드를 호출하도록하려고합니다. 이것은 내가 아래의 스크린 샷 같이

string URI = " http://localhost:59961/EmailService/SendEmail"; 
string fileContents = Convert.ToBase64String(File.ReadAllBytes("test.txt")); 

EmailData emailData = new EmailData 
          { 
           EmailAddress = "[email protected]", 
           Enc64FileContents = fileContents, 
           FileName = "test.txt" 
          }; 

XNamespace ns = "http://somenamespace/"; 
XElement emailDataElement = new XElement(ns + "EmailData"); 
emailDataElement.Add(new XElement(ns + "FileName", emailData.FileName)); 

emailDataElement.Add(new XElement(ns + "Enc64FileContents", emailData.Enc64FileContents)); 
emailDataElement.Add(new XElement(ns + "EmailAddress", emailData.EmailAddress)); 

var xml = emailDataElement.ToString(SaveOptions.DisableFormatting); 

using (WebClient wc = new WebClient()) 
{ 
    wc.Headers[HttpRequestHeader.ContentType] = "application/xml; charset=utf-8"; 
    string response = wc.UploadString(URI, "POST", xml); 
} 

이제 서비스 측면에서, 일부 속성이 null이있을 것입니다. enter image description here

FileName은 올바른 가치를 지니지 만 다른 것들은 그렇지 않은 이유가 무엇입니까?

+1

한 다음이 정말 SSCCE 코드에서와 같이 [DataMember] 속성에 Order 속성을 설정하는 것입니다 :) –

+0

는 파일이 유효하지 않은 문자를 포함하지 xml 값? 인코딩하려고 했습니까? –

+0

@Maras 아주 간단한 텍스트 파일입니다 (단어가 하나뿐입니다). 또한 base64 문자열 대신 일반 문자열을 보내려고 했는데도 도움이되지 않았습니다. –

답변

3

역 직렬화시 XML 요소의 순서가 중요합니다. 기본적으로 순서는 알파벳 순서이므로 먼저 EmailAddress을 보내고 Enc64FileContents을 입력 한 다음 FileName을 보내야합니다. 또는 대안 SSCCE 링크에 대한 :)

public class StackOverflow_14281800 
{ 
    [ServiceContract] 
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
    public class EmailService 
    { 
     [WebInvoke(UriTemplate = "/SendEmail", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Xml)] 
     public bool SendEmail(EmailData data) 
     { 
      try 
      { 
       Console.WriteLine("data.FileName = " + data.FileName); 
       Console.WriteLine("data.EmailAddress = " + data.EmailAddress); 
       Console.WriteLine("data.FileContents = " + new string(Convert.FromBase64String(data.Enc64FileContents).Select(b => (char)b).ToArray())); 
       //byte[] fileBinaryContents = Convert.FromBase64String(data.Enc64FileContents); 
       //File.WriteAllBytes(data.FileName, fileBinaryContents); 
       return true; 
      } 
      catch (Exception) 
      { 
       return false; 
      } 
     } 
    } 

    [DataContract(Name = "EmailData", Namespace = "http://somenamespace/")] 
    public class EmailData 
    { 
     [DataMember(Order = 1)] 
     public string FileName { get; set; } 

     [DataMember(Order = 2)] 
     public string EmailAddress { get; set; } 

     [DataMember(Order = 3)] 
     public string Enc64FileContents { get; set; } 
    } 

    public static void Test() 
    { 
     string baseURI = "http://localhost:59961/EmailService"; 

     var host = new WebServiceHost(typeof(EmailService), new Uri(baseURI)); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     string URI = baseURI + "/SendEmail"; 

     //string fileContents = Convert.ToBase64String(File.ReadAllBytes("test.txt")); 
     string fileContents = Convert.ToBase64String("hello world".Select(c => (byte)c).ToArray()); 

     EmailData emailData = new EmailData 
     { 
      EmailAddress = "[email protected]", 
      Enc64FileContents = fileContents, 
      FileName = "test.txt" 
     }; 

     XNamespace ns = "http://somenamespace/"; 
     XElement emailDataElement = new XElement(ns + "EmailData"); 

     emailDataElement.Add(new XElement(ns + "FileName", emailData.FileName)); 
     emailDataElement.Add(new XElement(ns + "EmailAddress", emailData.EmailAddress)); 
     emailDataElement.Add(new XElement(ns + "Enc64FileContents", emailData.Enc64FileContents)); 

     var xml = emailDataElement.ToString(SaveOptions.DisableFormatting); 

     using (WebClient wc = new WebClient()) 
     { 
      wc.Headers[HttpRequestHeader.ContentType] = "application/xml; charset=utf-8"; 
      string response = wc.UploadString(URI, "POST", xml); 
      Console.WriteLine(response); 
     } 
    } 
} 
+0

감사합니다! 필자는 XML 요소를 재정렬하고 효과가있었습니다. –

+0

+1 좋은 답변입니다. 나는 그 원인이 무엇인지 궁금했다. 나는 알파벳 순서가 요인이 될 줄 몰랐다. –