/// <summary> /// 根据接口类型的配置,返回wcf的访问信息和安全信息 /// </summary> /// <param name="wcfClientCfgInfo">wcf类型的配置信息</param> /// <returns>wcf的访问信息和安全信息</returns> private static MB.Util.Model.WcfCredentialInfo createWcfCredentialByCfgAttribute(WcfClientInvokeCfgInfo wcfClientCfgInfo) { if (wcfClientCfgInfo.CredentialFileNameOrServerName.IndexOf(':') >= 0) { MB.Util.Model.WcfCredentialInfo newInfo = new MB.Util.Model.WcfCredentialInfo(); newInfo.BaseAddress = wcfClientCfgInfo.CredentialFileNameOrServerName; newInfo.HostType = MB.Util.Model.WcfServiceHostType.DEVELOPER; return(newInfo); } else { string appPath = MB.Util.General.GeApplicationDirectory(); string fileFullName = appPath + wcfClientCfgInfo.CredentialFileNameOrServerName; if (!System.IO.File.Exists(fileFullName)) { MB.Util.TraceEx.Write(string.Format("证书文件{0} 找不到", fileFullName)); throw new MB.Util.APPException("对应选择的服务器还没有注册相应的安全访问证书,请联系系统管理员", APPMessageType.DisplayToUser); } try { System.IO.StreamReader r = new System.IO.StreamReader(fileFullName); string txt = r.ReadToEnd(); r.Close(); r.Dispose(); string dStr = MB.Util.DESDataEncrypt.DecryptString(txt); MB.Util.Serializer.EntityXmlSerializer <MB.Util.Model.WcfCredentialInfo> ser = new MB.Util.Serializer.EntityXmlSerializer <MB.Util.Model.WcfCredentialInfo>(); return(ser.SingleDeSerializer(dStr, string.Empty)); } catch (Exception ex) { throw new MB.Util.APPException(string.Format("证书文件{0} 不是有效的证书!", fileFullName), APPMessageType.DisplayToUser, ex); } } }
//得到服务配置信息 private static MB.Util.Model.WcfCredentialInfo createClientConfigInfo(MB.Util.Model.ServerConfigInfo serverInfo) { if (serverInfo.Credential.IndexOf(':') >= 0) { MB.Util.Model.WcfCredentialInfo newInfo = new MB.Util.Model.WcfCredentialInfo(); newInfo.BaseAddress = serverInfo.Credential; newInfo.HostType = MB.Util.Model.WcfServiceHostType.DEVELOPER; return(newInfo); } else { string creName = serverInfo.Credential; string fileFullName = AppDomain.CurrentDomain.BaseDirectory + serverInfo.Credential; if (!System.IO.File.Exists(fileFullName)) { MB.Util.TraceEx.Write(string.Format("证书文件{0} 找不到", fileFullName)); throw new MB.Util.APPException("对应选择的服务器还没有注册相应的安全访问证书,请联系系统管理员", APPMessageType.DisplayToUser); } try { System.IO.StreamReader r = new System.IO.StreamReader(fileFullName); string txt = r.ReadToEnd(); r.Close(); r.Dispose(); string dStr = MB.Util.DESDataEncrypt.DecryptString(txt); MB.Util.Serializer.EntityXmlSerializer <MB.Util.Model.WcfCredentialInfo> ser = new MB.Util.Serializer.EntityXmlSerializer <MB.Util.Model.WcfCredentialInfo>(); return(ser.SingleDeSerializer(dStr, string.Empty)); } catch (Exception ex) { throw new MB.Util.APPException(string.Format("证书文件{0} 不是有效的证书!", fileFullName), APPMessageType.DisplayToUser, ex); } } }
private static System.ServiceModel.Channels.Binding createBinding(MB.Util.Model.WcfCredentialInfo credentialInfo, bool isGZipCustomBinding, string usedbindingCfgName) { System.ServiceModel.Channels.Binding binding = null; var cfgInfo = credentialInfo; WcfServiceBindingType bindingType = getBindingType(credentialInfo); if (bindingType == WcfServiceBindingType.wsHttp) { string bindingCfgName; if (string.IsNullOrEmpty(usedbindingCfgName)) { bindingCfgName = System.Configuration.ConfigurationManager.AppSettings[HTTP_BINDING_NAME]; } else { bindingCfgName = usedbindingCfgName; } if (string.IsNullOrEmpty(bindingCfgName)) { throw new MB.Util.APPException(string.Format("wsHttp绑定需要配置{0}", HTTP_BINDING_NAME), MB.Util.APPMessageType.SysErrInfo); } //string gzip = System.Configuration.ConfigurationManager.AppSettings[ENABLE_GZIP_MESSAGE]; if (!isGZipCustomBinding) { binding = new WSHttpBinding(bindingCfgName); } else { binding = new CustomBinding(bindingCfgName); } } else if (bindingType == WcfServiceBindingType.netTcp) { string cfgName = System.Configuration.ConfigurationManager.AppSettings[TCP_BINDING_NAME]; if (string.IsNullOrEmpty(cfgName)) { throw new MB.Util.APPException(string.Format("netTcp 绑定需要配置{0}", TCP_BINDING_NAME), MB.Util.APPMessageType.SysErrInfo); } binding = new System.ServiceModel.NetTcpBinding(cfgName); } else { throw new MB.Util.APPException(string.Format("Wcf 客户端绑定目前不支持{0}", bindingType.ToString()), MB.Util.APPMessageType.SysErrInfo); } return(binding); }
/// <summary> /// 根据指定的系统编号,直接寻找WCF客户端地址 /// </summary> /// <typeparam name="T">客户端代理实例</typeparam> /// <param name="code">系统编码</param> /// <param name="bindingCfgName">自己指定绑定的名称,如果绑定为空,则根据绑定类型和配置项来决定绑定配置</param> /// <returns>WCF接口调用类型</returns> public static WcfClientProxyScope <T> CreateWcfClientProxy <T>(string bindingCfgName) { try { Type type = typeof(T); RegisterTypeIfMissing(type); WcfClientInvokeCfgInfo wcfClientCfgInfo = _WcfInvokeContainer[type]; if (string.IsNullOrEmpty(wcfClientCfgInfo.CredentialFileNameOrServerName)) { if (MB.Util.MyNetworkCredential.CurrentSelectedServerInfo == null) { throw new MB.Util.APPException("没有设置服务的配置信息,请检查节点AppSetting/WcfServers!"); } wcfClientCfgInfo.CredentialFileNameOrServerName = MB.Util.MyNetworkCredential.CurrentSelectedServerInfo.Credential; } MB.Util.Model.WcfCredentialInfo wcfCredentialInfo = createWcfCredentialByCfgAttribute(wcfClientCfgInfo); string gzip = System.Configuration.ConfigurationManager.AppSettings[ENABLE_GZIP_MESSAGE]; bool isGZipCustomBinding = !string.IsNullOrEmpty(gzip) && string.Compare(gzip, "True", true) == 0; System.ServiceModel.Channels.Binding binding = createBinding(wcfCredentialInfo, isGZipCustomBinding, string.Empty); string uri = buildEndpointAddress(wcfCredentialInfo, wcfClientCfgInfo); System.ServiceModel.EndpointAddress address = new EndpointAddress(uri); NetworkCredential credentialInfo = null; if (!string.IsNullOrEmpty(wcfCredentialInfo.UserName) && !string.IsNullOrEmpty(wcfCredentialInfo.Password)) { credentialInfo = new NetworkCredential(wcfCredentialInfo.UserName, wcfCredentialInfo.Password, wcfCredentialInfo.Domain); } T proxy = (T)createProxyInstance <T>(binding, address, credentialInfo); //如果每个调用都需要记录的话为产生很多日志,这里特处理一下。 if (!_MyInvokeCache.ContainsKey(uri)) { _MyInvokeCache.Add(uri, uri); MB.Util.TraceEx.Write(string.Format("开始根据地址{0} 创建WCF 客户端Channel Proxy{1}", uri, typeof(T).FullName)); } WcfClientProxyScope <T> proxyScope = new WcfClientProxyScope <T>(proxy); return(proxyScope); } catch (MB.Util.APPException aex) { throw aex; } catch (Exception ex) { throw new MB.Util.APPException("创建WCF 客户端代理出错!", APPMessageType.SysErrInfo, ex); } }
//根据配置的信息获取绑定的类型。 private static WcfServiceBindingType getBindingType(MB.Util.Model.WcfCredentialInfo credentialInfo) { WcfServiceBindingType bindingType = (credentialInfo.HostType == MB.Util.Model.WcfServiceHostType.IIS || credentialInfo.HostType == MB.Util.Model.WcfServiceHostType.DEVELOPER) ? WcfServiceBindingType.wsHttp : WcfServiceBindingType.netTcp; //如果是开发环境下的话,那么根据用户配置的基地址来决定 if (credentialInfo.HostType == MB.Util.Model.WcfServiceHostType.DEVELOPER) { if (credentialInfo.BaseAddress.Length > NET_TCP_HEADER.Length) { if (string.Compare(credentialInfo.BaseAddress.Substring(0, NET_TCP_HEADER.Length), NET_TCP_HEADER, true) == 0) { bindingType = WcfServiceBindingType.netTcp; } } } return(bindingType); }
//拼接对应的终结点的地址 private static string buildEndpointAddress(MB.Util.Model.WcfCredentialInfo credentialInfo, WcfClientInvokeCfgInfo wcfClientCfgInfo) { string relativePath = wcfClientCfgInfo.RelativePath; string replaceDot = System.Configuration.ConfigurationManager.AppSettings[REPLACE_PATH_LAST_DOT]; //判断是否修改相对路径的地址 if ((!string.IsNullOrEmpty(replaceDot) && string.Compare(replaceDot, "True", true) == 0) || credentialInfo.ReplaceRelativePathLastDot) { relativePath = replaceRelativePath(relativePath); } if (!string.IsNullOrEmpty(credentialInfo.EndpointFormatString)) { var v = System.Text.RegularExpressions.Regex.Matches(credentialInfo.EndpointFormatString, @"\{\d\}"); if (v.Count != 1) { throw new MB.Util.APPException(string.Format(@"证书 的 EndpointFormatString:{0} 设置有误,只能设置一个参数", credentialInfo.EndpointFormatString), APPMessageType.SysErrInfo); } return(string.Format(credentialInfo.EndpointFormatString, relativePath)); } else { string formateString = System.Configuration.ConfigurationManager.AppSettings[END_POINT_ADD_FORMATE_STRING]; if (!string.IsNullOrEmpty(formateString)) { return(string.Format(formateString, getAbsoluteBassAddress(credentialInfo.BaseAddress), relativePath)); } else { WcfServiceBindingType bindingType = getBindingType(credentialInfo); string header = bindingType == WcfServiceBindingType.wsHttp ? HTTP_HEADER : NET_TCP_HEADER; string path = System.Configuration.ConfigurationManager.AppSettings[SERVICE_DOMAIN_NAME]; if (string.IsNullOrEmpty(path)) { throw new MB.Util.APPException(string.Format("app.config 需要配置程序域名称 {0}", SERVICE_DOMAIN_NAME), MB.Util.APPMessageType.SysErrInfo); } return(string.Format("{0}{1}/{2}/{3}", header, getAbsoluteBassAddress(credentialInfo.BaseAddress), path, relativePath)); } } }
//创建指定的Wcf 绑定类型。 private static System.ServiceModel.Channels.Binding createBinding(MB.Util.Model.WcfCredentialInfo credentialInfo, bool isGZipCustomBinding) { return(createBinding(credentialInfo, isGZipCustomBinding, string.Empty)); }
/// <summary> /// 根据指定的系统编号,直接寻找WCF客户端地址 /// </summary> /// <typeparam name="T">客户端代理实例</typeparam> /// <param name="relativePath">相对地址</param> /// <param name="code">系统编码</param> /// <param name="bindingCfgName">自己指定绑定的名称</param> /// <returns></returns> public static T CreateWcfClient <T>(string relativePath, SystemCode code, string bindingCfgName) where T : class { try { if (MB.Util.MyNetworkCredential.CurrentSelectedServerInfo == null) { throw new MB.Util.APPException("没有设置服务的配置信息!"); } WcfClientInvokeAttribute cfgAtt = new WcfClientInvokeAttribute(typeof(T), relativePath, code); string gzip = System.Configuration.ConfigurationManager.AppSettings[ENABLE_GZIP_MESSAGE]; bool isGZipCustomBinding = !string.IsNullOrEmpty(gzip) && string.Compare(gzip, "True", true) == 0; MB.Util.Model.WcfCredentialInfo cfgInfo = createClientConfigInfo(MB.Util.MyNetworkCredential.CurrentSelectedServerInfo); if (code != SystemCode.Main) { string appendDetail = cfgInfo.AppendDetails; //从主服务的credetial转化到关联系统的credential MB.Util.Model.WcfCredentialInfo cfgSubSystemInfo = resolveSubSystemCredentialInfo(code, appendDetail, cfgInfo); if (cfgSubSystemInfo != null) { cfgInfo = cfgSubSystemInfo; } else { code = SystemCode.Main; } } System.ServiceModel.Channels.Binding binding = createBinding(cfgInfo, isGZipCustomBinding, bindingCfgName); string uri = buildEndpointAddress(cfgInfo, cfgAtt); //如果每个调用都需要记录的话为产生很多日志,这里特处理一下。 if (!_MyInvokeCache.ContainsKey(uri)) { _MyInvokeCache.Add(uri, uri); MB.Util.TraceEx.Write(string.Format("开始根据地址{0} 创建WCF 客户端Proxy{1}", uri, typeof(T).FullName)); } System.ServiceModel.EndpointAddress address = new EndpointAddress(uri); T proxy = (T)createProxyInstance <T>(binding, address); System.ServiceModel.Description.ServiceEndpoint endPoint = (System.ServiceModel.Description.ServiceEndpoint)MB.Util.MyReflection.Instance.InvokePropertyForGet(proxy, "Endpoint"); object obj = typeof(System.ServiceModel.ServiceHost).Assembly.CreateInstance("System.ServiceModel.Dispatcher.DataContractSerializerServiceBehavior", true, BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { false, Int32.MaxValue }, null, null); IEndpointBehavior dataSerializerBehavior = obj as IEndpointBehavior; endPoint.Behaviors.Add(dataSerializerBehavior); if (!isGZipCustomBinding) { if (cfgInfo.StartWindowsCredential && !string.IsNullOrEmpty(cfgInfo.UserName)) { System.Net.NetworkCredential credential = MB.Util.MyNetworkCredential.CreateNetworkCredential(cfgInfo); System.ServiceModel.Description.ClientCredentials clientCredentials = (System.ServiceModel.Description.ClientCredentials)MB.Util.MyReflection.Instance.InvokePropertyForGet(proxy, "ClientCredentials"); clientCredentials.Windows.ClientCredential = credential; } } return(proxy); } catch (MB.Util.APPException aex) { throw aex; } catch (Exception ex) { throw new MB.Util.APPException("创建WCF 客户端代理出错!", APPMessageType.SysErrInfo, ex); } }
/// <summary> /// 创建带有Windows 安全访问Wcf 客户端代理。 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="clientRule"></param> /// <param name="credentialInfo"></param> /// <returns></returns> public static T CreateWcfClient <T>(object clientRule, MB.Util.Model.WcfCredentialInfo credentialInfo) where T : class { try { if (MB.Util.MyNetworkCredential.CurrentSelectedServerInfo == null) { throw new MB.Util.APPException("没有设置服务的配置信息!"); } WcfClientInvokeAttribute cfgAtt = getWcfInvokeAtt(clientRule.GetType(), typeof(T)); if (cfgAtt == null) { //特殊说明: 从兼容性考虑,暂时先这里处理,以后需要去掉,要独立调用 return(MB.Util.MyNetworkCredential.CreateWcfClientWithCredential <T>()); } string gzip = System.Configuration.ConfigurationManager.AppSettings[ENABLE_GZIP_MESSAGE]; bool isGZipCustomBinding = !string.IsNullOrEmpty(gzip) && string.Compare(gzip, "True", true) == 0; MB.Util.Model.WcfCredentialInfo cfgInfo = null; if (credentialInfo == null) { cfgInfo = createClientConfigInfo(MB.Util.MyNetworkCredential.CurrentSelectedServerInfo); } else { cfgInfo = credentialInfo; } if (cfgAtt.SystemCode != SystemCode.Main) { string appendDetail = cfgInfo.AppendDetails; //从主服务的credetial转化到关联系统的credential MB.Util.Model.WcfCredentialInfo cfgSubSystemInfo = resolveSubSystemCredentialInfo(cfgAtt.SystemCode, appendDetail, cfgInfo); if (cfgSubSystemInfo != null) { cfgInfo = cfgSubSystemInfo; } else { cfgAtt.SystemCode = SystemCode.Main; } } System.ServiceModel.Channels.Binding binding = createBinding(cfgInfo, isGZipCustomBinding); string uri = buildEndpointAddress(cfgInfo, cfgAtt); //如果每个调用都需要记录的话为产生很多日志,这里特处理一下。 if (!_MyInvokeCache.ContainsKey(uri)) { _MyInvokeCache.Add(uri, uri); MB.Util.TraceEx.Write(string.Format("开始根据地址{0} 创建WCF 客户端Proxy{1}", uri, typeof(T).FullName)); } System.ServiceModel.EndpointAddress address = new EndpointAddress(uri); T proxy = (T)createProxyInstance <T>(binding, address); System.ServiceModel.Description.ServiceEndpoint endPoint = (System.ServiceModel.Description.ServiceEndpoint)MB.Util.MyReflection.Instance.InvokePropertyForGet(proxy, "Endpoint"); object obj = typeof(System.ServiceModel.ServiceHost).Assembly.CreateInstance("System.ServiceModel.Dispatcher.DataContractSerializerServiceBehavior", true, BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { false, Int32.MaxValue }, null, null); IEndpointBehavior dataSerializerBehavior = obj as IEndpointBehavior; endPoint.Behaviors.Add(dataSerializerBehavior); //增加分页消息头 endPoint.Behaviors.Add(new WcfDataQueryBehavior()); //增加性能指标检测行为 string wcfMonitorEnable = System.Configuration.ConfigurationManager.AppSettings[ENABLE_WCF_PERFORMANCE_MONITOR]; bool isWcfMonitorEnable = string.IsNullOrEmpty(wcfMonitorEnable) || string.Compare(gzip, "True", true) == 0; if (isWcfMonitorEnable) { endPoint.Behaviors.Add(new MB.Util.Monitors.WcfPerformanceMonitorBehavior()); } #region 加载应用程序自定义的behavior //增加扩展的Behavior,从配置文件中读取配置的扩展Behavior //在APPSetting中每个扩展由分号隔开,类型和Assmbly之间由逗号隔开 string customerBehaviorSrc = System.Configuration.ConfigurationManager.AppSettings[CUSTOM_ENDPOINT_BEHAVIORS]; if (!string.IsNullOrEmpty(customerBehaviorSrc)) { string[] customerBehaviors = customerBehaviorSrc.Split(';'); foreach (string customerBehavior in customerBehaviors) { try { string[] beTypes = customerBehavior.Split(','); object extBehavior = DllFactory.Instance.LoadObject(beTypes[0], beTypes[1]); if (extBehavior != typeof(WcfDataQueryBehavior) && extBehavior != typeof(MB.Util.Monitors.WcfPerformanceMonitorBehavior)) { IEndpointBehavior extEndPointBehavior = extBehavior as IEndpointBehavior; endPoint.Behaviors.Add(extEndPointBehavior); } } catch (Exception ex) { MB.Util.TraceEx.Write(string.Format("加载自定义behvaior出错:{0};错误:{1}", customerBehavior, ex.ToString())); } } } #endregion if (!isGZipCustomBinding) { if (cfgInfo.StartWindowsCredential && !string.IsNullOrEmpty(cfgInfo.UserName)) { System.Net.NetworkCredential credential = MB.Util.MyNetworkCredential.CreateNetworkCredential(cfgInfo); System.ServiceModel.Description.ClientCredentials clientCredentials = (System.ServiceModel.Description.ClientCredentials)MB.Util.MyReflection.Instance.InvokePropertyForGet(proxy, "ClientCredentials"); clientCredentials.Windows.ClientCredential = credential; } } return(proxy); } catch (MB.Util.APPException aex) { throw aex; } catch (Exception ex) { throw new MB.Util.APPException("创建WCF 客户端代理出错!", APPMessageType.SysErrInfo, ex); } }