Я не знал точно, как это задать, поэтому сделал 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 вызвать метод веб-службы; это то, что у меня есть
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
правильное значение, а у других - нет?
1 ответ
Порядок элементов 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);
}
}
}
Похожие вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.