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

を持っており、私は、Webサービスメソッドを呼び出すWinformsクライアントを取得しようとしています。これは、私は次のスクリーンショットで示すように

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

1以下この本当に SSCCEのコードのように、[DataMember]属性にOrderプロパティを設定することです:) –

+0

は、あなたのファイルがために有効でない任意の文字が含まれていませんxmlの値は?あなたはそれらをエンコードしようとしましたか? –

+0

@Marasそれはスーパーシンプルなテキストファイルです(単語は1つしかありません)。私も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すばらしい答え。私はこれの原因が何であるか疑問に思った。私はアルファベット順が要因であることを知らなかった。 –

関連する問題