我不确定如何问这个,所以我做了SSCCE
我有这个简单的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 = "foo@bar.com",
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,如下面的屏幕截图所示。
为什么FileName
具有正确的值而其他人没有?
答案 0 :(得分:3)
反序列化时,XML元素的顺序很重要。默认情况下,订单是按字母顺序排列的,因此您应首先发送EmailAddress
,然后Enc64FileContents
,然后发送FileName
。或者另一种方法是在Order
属性中设置[DataMember]
属性,如下面的 真正的 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 = "foo@bar.com",
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);
}
}
}