c# – 简单的WCF服务,而不是从客户端到服务的所有参数

我不确定如何问这个,所以我做了 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具有正确的值而其他人没有?

解决方法

反序列化时,XML元素的顺序很重要.认情况下,订单是按字母顺序排列的,因此您应首先发送EmailAddress,然后发送Enc64FileContents,然后发送FileName.或者另一种方法是在[DataMember]属性中设置Order属性,如下面真正的SSCCE代码:)
public class StackOverflow_14281800
{
    [ServiceContract]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class EmailService
    {
        [WebInvoke(UriTemplate = "/SendEmail",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",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,xml);
            Console.WriteLine(response);
        }
    }
}

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...