如何从WebService反序列化xmlResult或在没有SOAP的情况下使用webService?

时间:2015-10-31 08:39:55

标签: c# xml linq web-services

我有一个带有方法和控制台应用程序的Web服务,我使用了Web服务

[WebMethod]
public Foo HelloWorld(Foo foo)
{
    Foo foo2 = new Foo();
    foo2.Id = 10;
    foo2.Name = "roman";
    return foo2;
}

以及我使用此网络方法的应用程序:

using (WebClient client = new WebClient())
{
    {
        //how to replace this block on a short line likes Foo result = webService.WebMethod(params)
        client.Headers.Add("SOAPAction","\"http://tempuri.org/HelloWorld\"");

        client.Headers.Add("Content-Type", "text/xml; charset=utf-8");
        string payload = @"<?xml version=""1.0"" encoding=""utf-8""?>
                           <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
                                          xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
                                          xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
                               <soap:Body>
                                   <HelloWorld xmlns=""http://tempuri.org/"">
                                       <foo>
                                           <Id>10</Id>
                                           <Name>23</Name>
                                       </foo>
                                   </HelloWorld>
                               </soap:Body>
                           </soap:Envelope>";

        var data = Encoding.UTF8.GetBytes(payload);
        var result = client.UploadData("http://localhost:22123/Service1.asmx", data);
        Console.WriteLine(Encoding.Default.GetString(result));
    }
}

结果是:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <HelloWorldResponse xmlns="http://tempuri.org/">
            <HelloWorldResult>
                <Id>10</Id>
                <Name>roman</Name>
            </HelloWorldResult>
        </HelloWorldResponse>
    </soap:Body>
</soap:Envelope>

我的问题:

  1. 如何在一条小线上替换很多代码行?
  2. 如何使用Linq to XML反序列化webResult或者还有其他方法可以解决这个问题?

2 个答案:

答案 0 :(得分:1)

如果您有权访问该服务的wsdl,则可以生成一个C#类来使用它。它可以在visual studio命令提示符下使用。

https://msdn.microsoft.com/en-us/library/7h3ystb6(VS.80).aspx

wsdl.exe /out:theservice.cs http://whereever/service.wsdl

答案 1 :(得分:0)

我知道这不是一个好的解决方案,但我创建了从不同类创建SOAP的通用方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConsoleApplication1.ServiceReference1;
using System.Net;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    [Serializable]
    public class Foo
    {
        public Foo() { }
        public Foo(int id, string name)
        {
            Id = id;
            Name=name;
        }
        public int Id { get; set; }
        public string Name { get; set; }
    }

    [Serializable]
    public class Roman
    {
        public Roman() { }
        public Roman(int id, string bushuev, string somethingElse)
        {
            Id = id;
            Bushuev = bushuev;
            SomethingElse = somethingElse;
        }
        public int Id { get; set; }
        public string Bushuev { get; set; }
        public string SomethingElse { get; set; }
    }

    class Program
    {
        public static Stream GenerateStreamFromString(string s)
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            writer.Write(s);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }
        public static string GeneralSerilize<T>(T input)
        {
            string result=null;
            XmlSerializer xmlSerializer =
                new XmlSerializer(input.GetType());
            using (StringWriter textWriter = new StringWriter())
            {
                xmlSerializer.Serialize(textWriter, input);
                result = textWriter.ToString();
                string pattern = string.Format("(?<first><{0}(.|\r|\n)+{0}>)",input.GetType().Name);
                Match match = Regex.Match(result, pattern);
                result = match.Value;
                result = result.Replace(
                    @"xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""",
                    string.Empty);

                result = result.Replace(input.GetType().Name,
                                    input.GetType().Name.ToLower());
            }
            return result;
        }
        public static T GeneralDeserialize<T>(string input) where T:class
        {
            T result = null;
            XmlSerializer xml = new XmlSerializer(typeof(T));

            {
                string inptuResult = input;
                string pattern = string.Format("(?<first><{0}(.|\r|\n)+{0}>)", typeof(T).Name);
                Match match = Regex.Match(input, pattern);
                input = match.Value;
            }

            using (Stream stream = GenerateStreamFromString(input))
            {
                result = (T)xml.Deserialize(stream);
            }

            return result;
        }

        public static T UseWEbService<T>(T input, string nameMethod) where T:class
        {
            string xmlResult = GeneralSerilize<T>(input);

            using (WebClient client = new WebClient())
            {
                try
                {
                    string stringAction = string.Format("\"http://tempuri.org/{0}\"",nameMethod);
                    client.Headers.Add("SOAPAction", stringAction);

                    client.Headers.Add("Content-Type", "text/xml; charset=utf-8");
                    string payload= string.Empty;
                    string begin = @"<?xml version=""1.0"" encoding=""utf-8""?>
                                    <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
                                                    xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
                                                    xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
                                      <soap:Body>";

                    string end =@"</soap:Body>
                                    </soap:Envelope>";

                    string beginMethod = string.Empty;
                    beginMethod = string.Format(@"<{0} xmlns=""http://tempuri.org/"">",nameMethod);//"<" + nameMethod + ">";

                    string endMethod = string.Empty;
                    endMethod = "</" + nameMethod + ">";
                    payload = begin + 
                         beginMethod+
                         xmlResult+
                         endMethod
                         + end;

                    byte[] data = Encoding.UTF8.GetBytes(payload);
                    byte[] webServiceResponse = client.UploadData("http://localhost:22123/Service1.asmx", data);
                    string stringResponse = Encoding.Default.GetString(webServiceResponse);

                    try
                    {
                        string inputXML = stringResponse.Replace(nameMethod + "Result", input.GetType().Name);
                        T resultMethod = GeneralDeserialize<T>(inputXML);
                        return resultMethod;
                    }

                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }

                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            return null;
        }
        static void Main(string[] args)
        {
            Foo foo = UseWEbService < Foo>(new Foo(10, "roman"), "HelloWorld");
            Roman roman = new Roman(123,
                "roman ", "bushuev");
            Roman romanResult = UseWEbService<Roman>(roman, "HelloRoman");          
        }
    }
}

要找到最佳解决方案,您需要阅读Windows Communication Foundation中的Troelsen C#2010 .NET 4简介