简体   繁体   中英

How to deserialize xmlResult from WebService or use webService without SOAP?

I have a web service with method and console application where I used the web service

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

and application where I used this web method:

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));
    }
}

The result is:

<?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>

My problems:

  1. how to replace a lot of code lines on a small line?
  2. how to deserialize webResult by using Linq to XML or there is other way to do it?

If you have acces to the wsdl of the service, you can generate a C# class to use it. It can be used from the visual studio command prompt.

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

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

I know this is not a good solution, but i create general methods for creating SOAP from different classes

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");          
        }
    }
}

To find the best solution, you need to read Troelsen C#2010 .NET 4 Introduction in Windows Communication Foundation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM