I wasn't exactly sure how to ask this so I made an SSCCE
I have this simple WCF service
[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; }
}
and I'm trying to get a Winforms client to call the webservice method; this is what I have
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);
}
now on the service side, some of the properties are null as shown by the following screenshot.
Why is it that the FileName
has the right value but the others don't ?
The order of the XML elements is important when deserialization. By default, the order is alphabetical, so you should send first the EmailAddress
, then Enc64FileContents
, then FileName
. Or an alternative is to set the Order
property in the [DataMember]
attribute, as in this really SSCCE code below :)
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);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With