C# WebService的动态调用(二)

2021-01-31  乐帮网

c# webservice

上一篇文章通过使用.net提供的动态编译方式调用WebService,这种方式是我推荐的,同时适用于wcf和传统的webservice, 这次带来的通过http post调用只是通用于传统的webservice,因为wcf的消息格式我没有找到合适的类库。

此次使用了ChannelAdam.Soap类库来生成WebService的xml消息体。首先需要你在nuget中搜索 ChannelAdam.Soap然后引入 。
详细代码如下:

WsHttpHelper.cs类

public class WsHttpHelper
    {
        private string _url;

        private SoapVer _version;

        private static HttpClient client=new HttpClient();
        private WsHttpHelper(string url, SoapVer version)
        {
            _url = url;
            _version = version;
        }

        public enum SoapVer
        {
            SOAP11,
            SOAP12
        }

        public static WsHttpHelper GetInstance(string url, SoapVer version)
        {
            return new WsHttpHelper(url, version);
        }

        public string Invoke(object args)
        {
            string envelopeXml = string.Empty;
            var body = GetBody(args);
            if (this._version== SoapVer.SOAP12)
            {
                var builder = SoapBuilder.CreateSoap12Envelope();
                if (body != null)
                    builder.WithBody.AddEntry(body);

                envelopeXml = builder.Build().ToString();
            }else
            {
                var builder = SoapBuilder.CreateSoap11Envelope();
                if(body != null)
                    builder.WithBody.AddEntry(body);

                envelopeXml = builder.Build().ToString();
            }
            Dictionary<string, string> header = new Dictionary<string, string>();

            //header.Add("SOAPAction", args.GetType().Name);

            string result = HttpHelper.HttpPost(client, _url, envelopeXml, "text/xml", 30, header);
            return result;
        }

        public static XElement GetBody(object args)
        {
            var ns = XNamespace.Get("http://tempuri.org/");
            var bodyxml = XElement.Parse(ToXmlString(args));
            if(bodyxml.HasElements)
                return  new XElement(ns.GetName("GetUser"), bodyxml.Elements());
            else 
                return new XElement(ns.GetName("GetUser"));
        }

        /// <summary>
        /// Converts an object to its serialized XML format.
        /// </summary>
        /// <param name="value">The object we are operating on</param>
        /// <param name="removeDefaultXmlNamespaces">Whether or not to remove the default XML namespaces from the output</param>
        /// <param name="omitXmlDeclaration">Whether or not to omit the XML declaration from the output</param>
        /// <param name="encoding">The character encoding to use</param>
        /// <returns>The XML string representation of the object</returns>
        public static string ToXmlString(object value, bool removeDefaultXmlNamespaces = true, bool omitXmlDeclaration = true, Encoding encoding = null)
        {
            XmlSerializerNamespaces namespaces = removeDefaultXmlNamespaces ? new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }) : null;

            var settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.OmitXmlDeclaration = omitXmlDeclaration;
            settings.CheckCharacters = false;

            using (var stream = new StringWriterWithEncoding(encoding))
            using (var writer = XmlWriter.Create(stream, settings))
            {
                var serializer = new XmlSerializer(value.GetType());
                serializer.Serialize(writer, value, namespaces);
                return stream.ToString();
            }
        }


    }

 

xml序列化时用到自定义类:StringWriterWithEncoding.cs

 public class StringWriterWithEncoding : StringWriter
    {
        #region Properties

        /// <summary>
        /// Overrides the default encoding type (UTF-16).
        /// </summary>
        public override Encoding Encoding => _encoding ?? base.Encoding;

        #endregion

        #region Readonlys

        private readonly Encoding _encoding;

        #endregion

        #region Constructor

        /// <summary>
        /// Default constructor.
        /// </summary>
        public StringWriterWithEncoding() { }

        /// <summary>
        /// Constructor which accepts a character encoding type.
        /// </summary>
        /// <param name="encoding">The character encoding type</param>
        public StringWriterWithEncoding(Encoding encoding)
        {
            _encoding = encoding;
        }

        #endregion
    }

 

至于 HttpHelper.cs的代码就不贴了,使用的网上通用的,并无其他特殊处理。
调用方法挺简单的如下 :

 [TestMethod]
        public void TestMethod2()
        {
            string wsdlAddress ="http://localhost/wcftest2/WxTest.asmx";
            var webServic = WsHttpHelper.GetInstance (wsdlAddress, WsHttpHelper.SoapVer.SOAP11);

            var result = webServic.Invoke(new GetUser { openid= "9887445dfe" });

        }

以上就是lebang2020.cn带来的webservice动态调用。

可以下载我的示例代码链接:https://pan.baidu.com/s/1fyQzqQtZMfb00zCT9Ak-WQ 

提取码请点击下方的捐赠按钮获取。

包含两种调用方式的示例代码,以及webservice 和 wcf接口示例。

 

公众号二维码

关注我的微信公众号
在公众号里留言交流
投稿邮箱:1052839972@qq.com

庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。

欧阳修

付款二维码

如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力