使用vs2010创建、发布、部署、调用 WebService

时间:2023-11-24 22:19:02

一 使用vs2010创建 WebService

1 打开VS2010,菜单    文件->新建->项目
2 选择 其它语言--Visual C# --Web--ASP.net 空web应用程序,给个名称myWebApplication ,点确定。
3 右键点击解决方案下自己的项目myWebApplication,添加->新建项--Visual C#--Web--选择 web服务,起个服务名称为myWebSevice1
4 在自动打开的myWebSevice1.asmx文件中,继续加入自己的WebService方法。
5 方法写完后,右击解决方案下自己的项目myWebApplication->发布,选择【文件系统】发布,指定发布后的文件夹地址,点击【发布】即可;
6 打开IIS 建立网站,在控制面板中--管理工具--Internet 信息服务,逐级打开到默认网站,右键点击默认网站->新建->虚拟目录,网站名称,myWebService,内容文件地址是上面发布的文件夹地址
7 继续为网站设置,虚拟目录下,执行权限为“纯脚本”,目录安全性,勾选“匿名访问”, 勾选 “集成Windows身份验证”
  ASP.NET 下, ASP.NET 版本选择 4.0.30319

详细步骤参见2015-03-19《使用VS2010创建WebService 发布、测试 》
http://blog.sina.com.cn/s/blog_45eaa01a0102vopl.html

8 对于没有权限访问的,可以这样设置,方法如下:
开始--程序--Microsoft Visual Studio 2010 -- Visual Studio Tools -- Visual Studio 命令提示(2010)
进入文件夹
C:Program FilesMicrosoft Visual Studio 10.0VC

执行命令:aspnet_regiss.exe -i  即可

详细参见2011-04-15 《c#编写有关数据库网页的方法和步骤》 http://blog.sina.com.cn/s/blog_45eaa01a0100qg0g.html

简要代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Collections.ObjectModel;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace myWebApplication
{
    ///
    /// myWebService1 的摘要说明
    ///
    [WebService(Namespace = "http://myTempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
    // [System.Web.Script.Services.ScriptService]
   
    public class myWebService1 : System.Web.Services.WebService
    {
 
        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }
        [WebMethod]
        public int Add(int a, int b)
        {
            return (a + b);
        }

[WebMethod]
        public string Sub(int a, int b)
        {
            return (a - b).ToString();
        }

[WebMethod]
        public string class_one(string str)
        {

fuzaModel mm2 = serverFun.Deserialize(typeof(fuzaModel), str) as fuzaModel;
            mm2.a=mm2.a*3;
            mm2.b=mm2.b+"web";

return serverFun.Serialize(mm2);
        }
 
         [WebMethod]
        public string class_set(string str)
        {
            List newList = serverFun.Deserialize(typeof(List), str) as List;
            foreach (var info in newList)
            {
                info.a = info.a *  3;
                info.b = info.b + " web";
            }

return serverFun.Serialize>(newList);
        }

}

[XmlInclude(typeof(fuzaModel))]
    [Serializable]
    public class fuzaModel
    {
        private int m_UserId;

[XmlElement("userId")]
        public int UserId
        {
            get { return m_UserId; }
            set { m_UserId = value; }
        }

public int a;
            public string b;

//  [WebMethod]
        public fuzaModel aModel(fuzaModel m)
        {
           
            m.a = 2;
            m.b = "b";
           return  m;
        }
    }

[Serializable]
    public class serverFun : System.Web.Services.WebService
    {
        [WebMethod]
        public static string Serialize(T t)
        {
            using (StringWriter sw = new StringWriter())
            {
                XmlSerializer xz = new XmlSerializer(t.GetType());
                xz.Serialize(sw, t);
                return sw.ToString();
            }
        }

[WebMethod]
        public static object Deserialize(Type type, string s)
        {
            using (StringReader sr = new StringReader(s))
            {
                XmlSerializer xz = new XmlSerializer(type);
                return xz.Deserialize(sr);
            }
        }

//       在调用端序列化实体对象(实体对象须是可序列化的类): 
        [WebMethod]
        public static byte[] SerializeObject(object pObj)
        {
            if (pObj == null)            return null;
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(memoryStream, pObj);
            memoryStream.Position = 0;
            byte[] read = new byte[memoryStream.Length];
            memoryStream.Read(read, 0, read.Length);
            memoryStream.Close();
            return read;
        }
        //在service的调用方法中,接受一个byte[] 参数即可,然后反序列化:
        //然后将object强制转换成相应的实体类型,就可以直接使用此对象了。
        [WebMethod]
        public static object DeserializeObject(byte[] pBytes)
        {
            object newOjb = null;
            if (pBytes == null)return newOjb;
            System.IO.MemoryStream memoryStream = new
            System.IO.MemoryStream(pBytes);
            memoryStream.Position = 0;
            BinaryFormatter formatter = new BinaryFormatter();
            newOjb = formatter.Deserialize(memoryStream);
            memoryStream.Close();
            return newOjb;
        }

[WebMethod]
        public static string newObject(byte[] pBytes)
        {
            fuzaModel nn = new fuzaModel();

fuzaModel m_temp = DeserializeObject(pBytes) as fuzaModel;
            return Serialize(m_temp);

}

}

}

二 本地调用,要添加对 WebService 动态库的引用,也不用建立网站,当然这样调用意义不大

1 创建项目 WindowsFormsApplication9
2 添加引用  右击项目下的引用--添加引用,从“浏览”选项页,找到myWebApplication.dll,添加上
3 添加引用  右击项目下的引用--添加引用  从“.NET”选项页,找到System.Web.Services,添加上
 否则,生成解决方案时,将有以下错误
 错误 CS0012: 类型“System.Web.Services.WebService”在未被引用的程序集中定义。
4 更改应用程序的目标框架

右击项目名称 -- 属性,在“应用程序” 选项页下,将“目标框架”从.NET Framework 4 Client Profile 改为 .NET Framework 4

否则,生成解决方案时,将有以下错误
警告 CS1684: 对类型“System.Web.Services.WebService”的引用声称该类型是在“ System.Web.Services.dll”中定义的,但未能找到
错误 CS0011: 未能解析程序集“System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”中由类型“myWebApplication.myWebService1”引用的基类或接口“System.Web.Services.WebService

简要代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using myWebApplication;
namespace WindowsFormsApplication9
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

private void button1_Click(object sender, EventArgs e)
        {
            //1
            myWebApplication.myWebService1  ws =new myWebApplication.myWebService1();
            //简但类型调用
            int a=3,b=5,c=0;
            c = ws.Add(a, b);//加法,返回整型
            //MessageBox.Show(c.ToString());
            string str = ws.Sub(a, b);//减法,返回字符型
            c = int.Parse(str);
            //MessageBox.Show(c.ToString());

//2  传递 类
            fuzaModel mm = new fuzaModel();
            mm.a = 1;            mm.b = "bb";
            //2.1 序列化 以便传递
            string str2=serverFun.Serialize(mm);
            str2 = ws.class_one(str2);//调用类的运算

//2.2 反序列化,以便得到类
            fuzaModel mm2 = serverFun.Deserialize(typeof(fuzaModel), str2) as fuzaModel;

//3  传递 类的集合
            List list = new List();
            list.Add(new fuzaModel() { a = 1, b = "b1" });
            list.Add(new fuzaModel() { a = 2, b = "b2" });
            //3.1 序列化 以便传递
            string s = serverFun.Serialize>(list);
            s = ws.class_set(s);//调用类集合的运算

//3.2 反序列化,以便得到集合中的各个类
            List newList = serverFun.Deserialize(typeof(List), s) as List;
            foreach (var info in newList)
            {
                MessageBox.Show(info.a.ToString() + ", " + info.b);
            }
 
            //4

byte[] bytes = serverFun.SerializeObject(mm2);
            fuzaModel mm3 = serverFun.DeserializeObject(bytes) as fuzaModel;

string gg = serverFun.newObject(bytes);
            fuzaModel mm4 = serverFun.Deserialize(typeof(fuzaModel), gg) as fuzaModel;
 
        }

}
}

三远程调用,调用来自外部网站的WebService,这才是它的真正意义
 需要第一项《使用vs2010创建 WebService》中的6,7,8 建立运行网站,然后,通过指定地址和端口上的WebService的方法,参数即可调用

为简单起见,发布到自己的机器上,地址为 http://localhost/mywebservice/mywebservice1.asmx

以下工程选择Visual C# --Windows--window窗体应用程序,当然也可以基于Visual C# --Web-ASP.NET Web应用程序,两者调用的方法完全一致。
1 简要代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Xml;

//这里正则表达式的引用,加入就不能发表,请自行加入

namespace myWindowsFormsApplication8
{
    public partial class Form1 : Form
    {

string URL = "http://localhost/mywebservice/mywebservice1.asmx";//WebService 地址

public Form1()
        {
            InitializeComponent();
        }

private void button1_Click(object sender, EventArgs e)
        {
            //1 简单调用
            Hashtable ht = new Hashtable();  //Hashtable 为webservice所需要的参数集
            XmlDocument xx = clientFun.QuerySoapWebService(URL, "HelloWorld", ht);
            // MessageBox.Show(xx.OuterXml);//xx.OuterXml    //xx.InnerXml
            //参数
            int x=0, a=3, b=5;
            ht.Clear();
            ht.Add("a", a);
            ht.Add("b", b);
            //加法
            xx = clientFun.QuerySoapWebService(URL, "Add", ht);
            x = int.Parse(xx.InnerText);
            //减法
            xx = clientFun.QuerySoapWebService(URL, "Sub", ht);
            x = int.Parse(xx.InnerText);
            //按标签 截取返回多个中的某个
            string str = "";

//str = WebServiceCaller.GetTitleContent(str, "a","href");//返回root的值
            str=xx.InnerXml.ToString();
            str = clientFun.GetTitleContent(str, "root");//返回root的值
            //MessageBox.Show(str);

//2 传递 类
            fuzaModel mm = new fuzaModel();
            mm.a = 1;
            mm.b = "b1";
            //2.1 序列化文本 以便传递
            string str1 = clientFun.Serialize(mm);
            ht.Clear();
            ht.Add("str", str1);
            //调用类的运算
            xx = clientFun.QuerySoapWebService(URL, "class_one", ht);
            string str2 = xx.InnerText;
            //2.2 反序列化,以便得到类
            fuzaModel mm5 = clientFun.Deserialize(typeof(fuzaModel), str2) as fuzaModel;

//3 传递 类的集合
            List list = new List();
            list.Add(new fuzaModel() { a = 1, b = "b1" });
            list.Add(new fuzaModel() { a = 2, b = "b2" });
            str1 = clientFun.Serialize>(list);
            ht.Clear();
            ht.Add("str", str1);
            //调用类集合的运算
            xx = clientFun.QuerySoapWebService(URL, "class_set", ht);
            str2 = xx.InnerText;

//3.2 反序列化,以便得到集合中的各个类
            List newList = clientFun.Deserialize(typeof(List), str2) as List;
            foreach (var info in newList)
            {
                MessageBox.Show(info.a.ToString() + ", " + info.b);
            }
        }

public class fuzaModel
        {
            private int m_UserId;

public int UserId
            {
                get { return m_UserId; }
                set { m_UserId = value; }
            }

public int a;
            public string b;

//  [WebMethod]
            public fuzaModel aModel(fuzaModel m)
            {
                m.a = 2;
                m.b = "b";
                return m;
            }
        }
 
    }
}

2 为了调用外网的WebService方便,整理一些公用方法,专门形成一个类,大部分内容来自网上,并作适当的修改:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Net;
using System.Collections;
using System.IO;
using System.Xml.Serialization;
 using System.Collections.ObjectModel;

//这里正则表达式的引用,加入就不能发表,请自行加入

namespace myWindowsFormsApplication8
{
    class clientFun
    {

//1获取字符中指定标签的值
        ///
        /// 获取字符中指定标签的值
        ///
        /// 字符串
        /// 标签
        /// 值
        public static string GetTitleContent(string str, string title)
        {
            string tmpStr = string.Format("<{0}[^>]*?>(?[^<]*)</{1}>", title, title); //获取
            Match TitleMatch = Regex.Match(str, tmpStr, RegexOptions.IgnoreCase);
            string result = TitleMatch.Groups["Text"].Value;
            return result;
        }

///  
        /// 获取字符中指定标签的值 
        ///  
        /// 字符串 
        /// 标签 
        /// 属性名 
        /// 属性 
        public static string GetTitleContent(string str, string title, string attrib)
        {
            string tmpStr = string.Format("<{0}[^>]*?{1}=(['""]?)(?[^'""\s>]+)\1[^>]*>", title, attrib); //获取
            Match TitleMatch = Regex.Match(str, tmpStr, RegexOptions.IgnoreCase);
            string result = TitleMatch.Groups["url"].Value;
            return result;
        }
//2 序列化 反序列化

///
        /// 序列化对象
        ///
        /// 对象类型
        /// 对象
        ///
 
        public static string Serialize(T t)
        {
            using (StringWriter sw = new StringWriter())
            {
                XmlSerializer xz = new XmlSerializer(t.GetType());
                xz.Serialize(sw, t);
                return sw.ToString();
            }
        }

///
        /// 反序列化为对象
        ///
        /// 对象类型
        /// 对象序列化后的Xml字符串
        ///
        ///
        public static object Deserialize(Type type, string s)
        {
            using (StringReader sr = new StringReader(s))
            {
                XmlSerializer xz = new XmlSerializer(type);
                return xz.Deserialize(sr);
            }
        }

//Serialize方法代码如下:
        ///
        /// 实体类集合序列化为字符串
        ///
        ///
        ///
        ///
        public static string Serializer2(T objToXml)
        {
            using (StringWriter writer = new StringWriter())
            {
                XmlSerializer serializer = new XmlSerializer(objToXml.GetType());
                serializer.Serialize(writer, objToXml);
                return writer.GetStringBuilder().ToString();
            }
        }

//DeserializerCollection方法代码如下:
        ///
        ///
        ///
        ///
        ///
        public static Collection DeSerializerCollection(string sXml, Type type)
        {
            using (StringReader reader = new StringReader(sXml))
            {
                System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(type);

object obj = serializer.Deserialize(reader);
                return (Collection)obj;
            }
        }

//3 web 调用

///
        /// 需要WebService支持Post调用
        ///
        public static XmlDocument QueryPostWebService(String URL, String MethodName, Hashtable Pars)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            SetWebRequest(request);
            byte[] data = EncodePars(Pars);
            WriteRequestData(request, data);
            return ReadXmlResponse(request.GetResponse());
        }

///
        /// 需要WebService支持Get调用
        ///
        public static XmlDocument QueryGetWebService(String URL, String MethodName, Hashtable Pars)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName + "?" + ParsToString(Pars));
            request.Method = "GET";
            request.ContentType = "application/x-www-form-urlencoded";
            SetWebRequest(request);
            return ReadXmlResponse(request.GetResponse());
        }

///
        /// 通用WebService调用(Soap),参数Pars为String类型的参数名、参数值
        ///
        public static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars)
        {
            if (_xmlNamespaces.ContainsKey(URL))
            {
                return QuerySoapWebService(URL, MethodName, Pars, _xmlNamespaces[URL].ToString());
            }
            else
            {
                return QuerySoapWebService(URL, MethodName, Pars, GetNamespace(URL));
            }
        }

private static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars, string XmlNs)
        {
            _xmlNamespaces[URL] = XmlNs;//加入缓存,提高效率
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
            request.Method = "POST";
            request.ContentType = "text/xml; charset=utf-8";
            request.Headers.Add("SOAPAction", """ + XmlNs + (XmlNs.EndsWith("/") ? "" : "/") + MethodName + """);
            SetWebRequest(request);
            byte[] data = EncodeParsToSoap(Pars, XmlNs, MethodName);
            WriteRequestData(request, data);
            XmlDocument doc = new XmlDocument(), doc2 = new XmlDocument();
            doc = ReadXmlResponse(request.GetResponse());

XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
            mgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
            String RetXml = doc.SelectSingleNode("//soap:Body/*/*", mgr).InnerXml;
            doc2.LoadXml("" + RetXml + "");
            AddDelaration(doc2);
            return doc2;
        }
        private static string GetNamespace(String URL)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "?WSDL");
            SetWebRequest(request);
            WebResponse response = request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(sr.ReadToEnd());
            sr.Close();
            return doc.SelectSingleNode("//@targetNamespace").Value;
        }

private static byte[] EncodeParsToSoap(Hashtable Pars, String XmlNs, String MethodName)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml("http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/

">");
            AddDelaration(doc);
            //XmlElement soapBody = doc.createElement_x_x_x_x("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");
            XmlElement soapBody = doc.createElement_x_x("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");
            //XmlElement soapMethod = doc.createElement_x_x_x_x(MethodName);
            XmlElement soapMethod = doc.createElement_x_x(MethodName);
            soapMethod.SetAttribute("xmlns", XmlNs);
            foreach (string k in Pars.Keys)
            {
                //XmlElement soapPar = doc.createElement_x_x_x_x(k);
                XmlElement soapPar = doc.createElement_x_x(k);
                soapPar.InnerXml = ObjectToSoapXml(Pars[k]);
                soapMethod.A(soapPar);
            }
            soapBody.A(soapMethod);
            doc.DocumentElement.A(soapBody);
            return Encoding.UTF8.GetBytes(doc.OuterXml);
        }
        private static string ObjectToSoapXml(object o)
        {
            XmlSerializer mySerializer = new XmlSerializer(o.GetType());
            MemoryStream ms = new MemoryStream();
            mySerializer.Serialize(ms, o);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(Encoding.UTF8.GetString(ms.ToArray()));
            if (doc.DocumentElement != null)
            {
                return doc.DocumentElement.InnerXml;
            }
            else
            {
                return o.ToString();
            }
        }

///
        /// 设置凭证与超时时间
        ///
        ///
        private static void SetWebRequest(HttpWebRequest request)
        {
            request.Credentials = CredentialCache.DefaultCredentials;
            request.Timeout = 10000;
        }

private static void WriteRequestData(HttpWebRequest request, byte[] data)
        {
            request.ContentLength = data.Length;
            Stream writer = request.GetRequestStream();
            writer.Write(data, 0, data.Length);
            writer.Close();
        }

private static byte[] EncodePars(Hashtable Pars)
        {
            return Encoding.UTF8.GetBytes(ParsToString(Pars));
        }

private static String ParsToString(Hashtable Pars)
        {
            StringBuilder sb = new StringBuilder();
            foreach (string k in Pars.Keys)
            {
                if (sb.Length > 0)
                {
                    sb.Append("&");
                }
                //sb.Append(HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(Pars[k].ToString()));
            }
            return sb.ToString();
        }

private static XmlDocument ReadXmlResponse(WebResponse response)
        {
            StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
            String retXml = sr.ReadToEnd();
            sr.Close();
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(retXml);
            return doc;
        }

private static void AddDelaration(XmlDocument doc)
        {
            XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null);
            doc.InsertBefore(decl, doc.DocumentElement);
        }

private static Hashtable _xmlNamespaces = new Hashtable();//缓存xmlNamespace,避免重复调用GetNamespace

}
}