一 使用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 classmyWebService1 : 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) asfuzaModel;
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) asList;
foreach (var info in newList)
{
info.a = info.a * 3;
info.b = info.b + " web";
}
return serverFun.Serialize>(newList);
}
}
[XmlInclude(typeof(fuzaModel))]
[Serializable]
public classfuzaModel
{
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 classserverFun : 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 = newSystem.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 ClientProfile 改为 .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
{
publicpartial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//1
myWebApplication.myWebService1 ws =newmyWebApplication.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) asfuzaModel;
//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) asList;
foreach (var info in newList)
{
MessageBox.Show(info.a.ToString() + ", " + info.b);
}
//4
byte[] bytes = serverFun.SerializeObject(mm2);
fuzaModel mm3 = serverFun.DeserializeObject(bytes) asfuzaModel;
string gg = serverFun.newObject(bytes);
fuzaModel mm4 = serverFun.Deserialize(typeof(fuzaModel), gg) asfuzaModel;
}
}
}
三远程调用,调用来自外部网站的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
{
publicpartial 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) asfuzaModel;
//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) asList;
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
{
classclientFun
{
//1获取字符中指定标签的值
///
/// 获取字符中指定标签的值
///
/// 字符串
/// 标签
/// 值
public static string GetTitleContent(string str, stringtitle)
{
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 = newXmlSerializer(objToXml.GetType());
serializer.Serialize(writer, objToXml);
return writer.GetStringBuilder().ToString();
}
}
//DeserializerCollection方法代码如下:
///
///
///
///
///
public static Collection DeSerializerCollection(string sXml, Typetype)
{
using (StringReader reader = new StringReader(sXml))
{
System.Xml.Serialization.XmlSerializer serializer = newSystem.Xml.Serialization.XmlSerializer(type);
object obj = serializer.Deserialize(reader);
return (Collection)obj;
}
}
//3 web 调用
///
/// 需要WebService支持Post调用
///
public static XmlDocument QueryPostWebService(String URL, StringMethodName, 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, StringMethodName, 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, StringMethodName, 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, StringMethodName, 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 = newXmlDocument();
doc = ReadXmlResponse(request.GetResponse());
XmlNamespaceManager mgr = newXmlNamespaceManager(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();
returndoc.SelectSingleNode("//@targetNamespace").Value;
}
private static byte[] EncodeParsToSoap(Hashtable Pars, StringXmlNs, 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(WebResponseresponse)
{
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 = newHashtable();//缓存xmlNamespace,避免重复调用GetNamespace
}
}