2013-01-11 35 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); 
} 

現在在服務端,一些屬性爲空,如下面的截圖所示。 enter image description here

爲什麼FileName有正確的價值,但其他人卻沒有?

+1

+1這個真的 SSCCE代碼SSCCE鏈接:) –

+0

做你的文件包含無效的任何字符xml值?你有試過編碼嗎? –

+0

@Maras它是一個超級簡單的文本文件(只有一個單詞)。我也嘗試發送一個普通的字符串,而不是base64字符串,這也沒有幫助。 –

回答

3

反序列化時,XML元素的順序非常重要。默認情況下,訂單是按字母順序排列的,因此您應先發送EmailAddress,然後Enc64FileContents,然後FileName。或者另一種是設置Order屬性在屬性[DataMember],如下:)

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很好的答案。我想知道這是什麼原因。我不知道按字母順序排列是一個因素。 –