/// <summary> /// 带服务地址构造函数 /// </summary> /// <param name="serviceUrl">服务地址</param> public CoreClient(string serviceUrl) { ServiceUrl = serviceUrl.TrimEnd('/'); try { //获取WSDL var wc = new WebClient(); var stream = wc.OpenRead(ServiceUrl + "?WSDL"); wc.Dispose(); if (stream == null) { _type = null; return; } var sd = ServiceDescription.Read(stream); var classname = sd.Services[0].Name; var sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); var cn = new CodeNamespace(); //生成客户端代理类代码 var ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); var csc = new CSharpCodeProvider(); //设定编译参数 var cplist = new CompilerParameters { GenerateExecutable = false, 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"); //编译代理类 var cr = csc.CompileAssemblyFromDom(cplist, ccu); if (cr.Errors.HasErrors) { var sb = new StringBuilder(); foreach (CompilerError ce in cr.Errors) { sb.Append(ce); sb.Append(Environment.NewLine); } throw new Exception(sb.ToString()); } //生成代理实例,并调用方法 var assembly = cr.CompiledAssembly; _type = assembly.GetType(classname, true, true); } catch (Exception e) { CoreLog.Error(e); } }
/// <summary> /// XML反序列化 /// </summary> public static object XmlToObj(string xmlStr, Type t) { try { using (var sr = new StringReader(xmlStr)) { var serializer = new XmlSerializer(t); return(serializer.Deserialize(sr)); } } catch (Exception e) { CoreLog.Error(e); return(null); } }
/// <summary> /// XML反序列化 /// </summary> public static T XmlToObj <T>(string xmlStr) where T : new() { try { using (var sr = new StringReader(xmlStr)) { var serializer = new XmlSerializer(typeof(T)); return((T)serializer.Deserialize(sr)); } } catch (Exception e) { CoreLog.Error(e); return(default(T)); } }
/// <summary> /// 将JSON字符串转化为对应类型的对象 /// </summary> /// <param name="json">json字符串</param> /// <param name="type"></param> /// <returns>转换后的对象</returns> public static object JsonDataToObj(string json, Type type) { try { using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json))) { var deseralizer = new DataContractJsonSerializer(type); return(deseralizer.ReadObject(ms)); } } catch (Exception e) { CoreLog.Error(e); return(null); } }
/// <summary> /// 接收请求的委托 /// </summary> /// <param name="ar"></param> private void Result(IAsyncResult ar) { //当接收到请求后程序流会走到这里 //获得context对象 var context = _httpobj.EndGetContext(ar); //继续异步监听 _httpobj.BeginGetContext(Result, _httpobj); var request = context.Request; //将发送到客户端的请求响应中的客户端的对象 var response = context.Response; //后台跨域请求,通常设置为配置文件 如果是js的ajax请求,还可以设置跨域的ip地址与参数 context.Response.AppendHeader("Access-Control-Allow-Origin", "*"); //后台跨域参数设置,通常设置为配置文件 //context.Response.AppendHeader("Access-Control-Allow-Headers", "ID,PW"); //后台跨域请求设置,通常设置为配置文件 //context.Response.AppendHeader("Access-Control-Allow-Method", "post"); //告诉客户端返回的ContentType类型为JSON格式,编码为UTF-8 context.Response.ContentType = "application/json;charset=UTF-8"; //添加响应头信息 context.Response.AddHeader("Content-type", "application/json"); //设置响应的编码格式 context.Response.ContentEncoding = Encoding.UTF8; //处理客户端发送的请求并返回处理信息 var retData = HandleRequest(request, response) ?? string.Empty; //设置客户端返回信息的编码 var retByteArr = Encoding.UTF8.GetBytes(retData); try { using (var stream = response.OutputStream) { //把处理信息返回到客户端 stream.Write(retByteArr, 0, retByteArr.Length); } } catch (Exception ex) { CoreLog.Error("网络异常:" + ex); } }
/// <summary> /// 执行服务器方法 /// </summary> /// <param name="mi">方法</param> /// <param name="pos">参数</param> /// <returns></returns> private string Fun(MethodBase mi, object[] pos) { try { //创建实例 var o = Activator.CreateInstance(_serviceClass); //调用方法 if (mi != null) { return(CoreConvert.ObjToJsonData(mi.Invoke(o, pos))); } CoreLog.Error("方法不能为空"); return(null); } catch (Exception ex) { CoreLog.Error("方法:" + mi?.Name + "执行错误:" + ex); throw new Exception(ex.Message); } }
/// <summary> /// 将任意类型对象转化为数据JSON字符串 /// </summary> /// <param name="obj">要转换的对象</param> /// <returns>json字符串</returns> public static string ObjToJsonData(object obj) { try { var js = new DataContractJsonSerializer(obj.GetType()); var msObj = new MemoryStream(); //将序列化之后的Json格式数据写入流中 js.WriteObject(msObj, obj); msObj.Position = 0; //从0这个位置开始读取流中的数据 var sr = new StreamReader(msObj, Encoding.UTF8); var json = sr.ReadToEnd(); sr.Close(); msObj.Close(); return(json); } catch (Exception e) { CoreLog.Error(e); return(null); } }
/// <summary> /// 处理请求 /// </summary> /// <param name="request"></param> /// <param name="response"></param> /// <returns></returns> private string HandleRequest(HttpListenerRequest request, HttpListenerResponse response) { if (request.HttpMethod.ToUpper() != "POST") { CoreLog.Error("只支持POST提交"); return(null); } if (request.InputStream != null) { string funName = null; //具体要执行的方法 MethodInfo mi = null; //参数 //这里是有客户端发送的正文本数据流的请求 try { var byteList = new List <byte>(); var byteArr = new byte[2048]; int readLen; var len = 0; //接收客户端传过来的数据并转成字符串类型 do { readLen = request.InputStream.Read(byteArr, 0, byteArr.Length); len += readLen; byteList.AddRange(byteArr); } while (readLen != 0); //获取得到数据data var data = Encoding.UTF8.GetString(byteList.ToArray(), 0, len); //判断是否是WebService模式调用 object[] objArr; //url路径 var postSegments = request.Url.Segments; //根据url路径确定方法名 if (postSegments.Length < 2) { response.StatusDescription = "404"; response.StatusCode = 404; CoreLog.Error("找不到服务方法"); return(null); } funName = postSegments[1].TrimEnd('/'); //判断是否是WebSrviceSoap模式调用 if (funName == "WebSrviceSoap") { if (string.IsNullOrEmpty(data)) { response.StatusDescription = "404"; response.StatusCode = 404; CoreLog.Error("找不到服务方法"); return(null); } var sendDatas = (SendData)CoreConvert.JsonDataToObj(data, typeof(SendData)); //获取方法名相同的所有方法 var mis = _serviceFunArr.Where(f => string.Equals(f.Name, sendDatas.Method, StringComparison.CurrentCultureIgnoreCase)).ToList(); if (mis.Count == 0) { response.StatusDescription = "404"; response.StatusCode = 404; CoreLog.Error("找不到服务方法"); return(null); } //获取参数 var dataList = (List <string>)CoreConvert.JsonDataToObj(sendDatas.Datas, typeof(List <string>)); //这里为空则没有参数 if (dataList == null) { foreach (var m in mis) { var ps = m.GetParameters(); if (ps.Length != 0) { continue; } //找到没有参数的方法 mi = m; break; } //参数默认值null objArr = null; } else { //这里是参数数组 objArr = new object[dataList.Count]; foreach (var m in mis) { var ps = m.GetParameters(); if (ps.Length != dataList.Count) { continue; } //找到参数数量对应的方法 mi = m; for (var i = 0; i < ps.Length; i++) { objArr[i] = CoreConvert.JsonDataToObj(dataList[i], ps[i].ParameterType); } } } } else { //获取方法名相同的所有方法 var mis = _serviceFunArr.Where(f => string.Equals(f.Name, funName, StringComparison.CurrentCultureIgnoreCase)).ToList(); if (mis.Count == 0) { response.StatusDescription = "404"; response.StatusCode = 404; CoreLog.Error("找不到服务方法"); return(null); } //这里为空则没有参数 if (string.IsNullOrEmpty(data)) { foreach (var m in mis) { var ps = m.GetParameters(); if (ps.Length != 0) { continue; } //找到没有参数的方法 mi = m; break; } //参数默认值null objArr = null; } else { //获取参数 var dataArr = data.Split('&'); //这里是参数数组 objArr = new object[dataArr.Length]; foreach (var m in mis) { var ps = m.GetParameters(); if (ps.Length != dataArr.Length) { continue; } //找到参数数量对应的方法 mi = m; for (var i = 0; i < ps.Length; i++) { foreach (var d in dataArr) { //拆分参数字符串 获得方法名和值 try { var dArr = d.Split('='); if (ps[i].Name != dArr[0]) { continue; } objArr[i] = dArr[1]; break; } catch (Exception e) { CoreLog.Error("参数错误:" + e); response.StatusDescription = "404"; response.StatusCode = 404; return(null); } } } } } } return(Fun(mi, objArr)); } catch (Exception ex) { response.StatusDescription = "404"; response.StatusCode = 404; CoreLog.Error($"接收数据时发生错误 Url:{request.Url} Method:{funName} err:{ex}"); return(null); } } response.StatusDescription = "404"; response.StatusCode = 404; CoreLog.Error("不允许空提交"); return(null); }