求助 ASP.NET中webservice的使用
以前用webservice的时候是只直接在项目中添加webservice的引用就可以了
但是现在碰到一个问题。我现在不知道webservice的地址,
或者知道地址,但是地址是别人内网的服务器的,我这边访问不了。
我只知道里面的有哪些方法方法
这个时候该如何去调用使用webservice的方法?
求助。
今天公司来省厅的领导,要我去要接口,但是不知道如何下手,如何要,要些什么东西。要到地址,也是内网的。
如何去实现引用接口?
求助!!!
[解决办法]
简单的方式是:你可以修改app.config文件的属性,改为 Content, Copy if newer,这样就发布为程序以外的一个文件,客户就可以自己随时修改url配置信息了。
除此以外,每一个web service客户端对象其实也可以在初始化时指定url的。不过你用上面的那个方法就可以了。
[解决办法]
关于你说“我只知道里面的有哪些方法方法”,这个通常的做法是:别人访问web service,取得wsdl文本,把这个文本传给你,然后你就可以在vs中导入这个wsdl文件(而不需要连接对方的web service),这就能生成本地客户端代理。
不过最好还是要求对方对外开放一个供测试用的web service,这样你才能保证开发顺利,并且一旦接口和实现上有争议也好说明是谁的责任。
[解决办法]
- C# code
using System.CodeDom.Compiler;using System;using System.Net;using System.CodeDom;using Microsoft.CSharp;using System.IO;using System.Web.Services.Description;using System.Collections.Generic;using System.Reflection;namespace cjl.WebServices{ public class DynamicWebServices { static SortedList<string, Type> _typeList = new SortedList<string, Type>(); #region InvokeWebService static string GetCacheKey(string url, string className) { return url.ToLower() + className; } static Type GetTypeFromCache(string url, string className) { string key = GetCacheKey(url, className); foreach (KeyValuePair<string, Type> pair in _typeList) { if (key == pair.Key) { return pair.Value; } } return null; } static Type GetTypeFromWebService(string url, string className) { string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling"; if ((className == null) || (className == "")) { className = GetWsClassName(url); } //获取WSDL WebClient wc = new WebClient(); Stream stream = wc.OpenRead(url + "?WSDL"); ServiceDescription sd = ServiceDescription.Read(stream); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(@namespace); //生成客户端代理类代码 CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); CSharpCodeProvider csc = new CSharpCodeProvider(); ICodeCompiler icc = csc.CreateCompiler(); //设定编译参数 CompilerParameters cplist = new CompilerParameters(); cplist.GenerateExecutable = false; cplist.GenerateInMemory = true; cplist.ReferencedAssemblies.Add("System.dll"); cplist.ReferencedAssemblies.Add("System.XML.dll"); cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); cplist.ReferencedAssemblies.Add("System.Data.dll"); //编译代理类 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu); if (true == cr.Errors.HasErrors) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors) { sb.Append(ce.ToString()); sb.Append(System.Environment.NewLine); } throw new Exception(sb.ToString()); } //生成代理实例,并调用方法 System.Reflection.Assembly assembly = cr.CompiledAssembly; Type t = assembly.GetType(@namespace + "." + className, true, true); return t; } //动态调用web服务 public static object InvokeWebService(string url, string methodName, object[] args) { return InvokeWebService(url, null, methodName, args); } public static object InvokeWebService(string url, string className, string methodName, object[] args) { try { Type t = GetTypeFromCache(url, className); if (t == null) { t = GetTypeFromWebService(url, className); //添加到缓冲中 string key = GetCacheKey(url, className); _typeList.Add(key, t); } object obj = Activator.CreateInstance(t); MethodInfo mi = t.GetMethod(methodName); return mi.Invoke(obj, args); } catch (Exception ex) { throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace)); } } private static string GetWsClassName(string wsUrl) { string[] parts = wsUrl.Split('/'); string[] pps = parts[parts.Length - 1].Split('.'); return pps[0]; } #endregion }}
[解决办法]
1.借助IIS的安全机制
2.利用SOAP消息自带用户名密码,进行身份验证。
- C# code
public class MyHeader : SoapHeader { public string userName; public string password; public string ip; } public MyHeader header; public iusers() { } [WebMethod] [SoapHeader("header")] public Business.Model.Member GetByUserId(int uid) { this.CheckHeader(header); return Business.Model.Member.GetByUserId(uid); }private void CheckHeader(MyHeader header) { if (header != null) { string UserName = header.userName; string PassWord = header.password; if ("admin".Equals(UserName) && "000000".Equals(PassWord)) { return; } else { throw new Exception(String.Format("用户名{0}对应的密码不是{1}", UserName, PassWord)); } } else { throw new ApplicationException("请提交包含用户名和密码信息的消息头"); } }