private void WcfClient(object param) { // オレオレ証明書に対する処置 ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback); ThreadContext thc = param as ThreadContext; thc.isRunnig = true; string dataname = thc.commdata.GetMessageName(); this.appLog.Debug("<DA> DataAccessThread ({0})", dataname); object[] reqparams = thc.commdata.GetParameters(); string fmt = string.Empty; for (int i = 0; i < reqparams.Length; i++) { fmt += (string.IsNullOrEmpty(fmt) ? "" : ", ") + string.Format("p{1}={0}{1}{2}", '{', i, '}'); } if (!string.IsNullOrEmpty(fmt)) { this.appLog.Debug("<DA> parameter:" + fmt, reqparams); } try { if (string.IsNullOrWhiteSpace(dataname)) { throw new FWThreadCoreDataException(ConstDataAccess.ErrDataTypeUnknown); } string kind; if (thc.commdata.mType == MessageType.RequestLicense) { kind = "common"; } else { kind = "user"; } string cstr = thc.commdata.connection; List <string> types = new List <string>(); var values = new List <object>(); foreach (var item in thc.commdata.GetParameters()) { if (item == null) { types.Add(string.Empty); values.Add(null); } else { types.Add(item.GetType().FullName); values.Add(GetSerializedArray(item)); } } // ターゲットのメソッドを呼び出す var result = GetClient().CallFunction(dataname, kind, cstr, types.ToArray(), values.ToArray()); //var tp = GetClient().GetType(); //MethodInfo mi = tp.GetMethod("CallFunction"); //var result = mi.Invoke(null, new object[] { dataname, kind, cstr, types.ToArray(), values.ToArray(), }); if (result != null) { byte[] binret = result as byte[]; if (binret != null) { // バイナリで返ってきた応答はDataTableまたはDataSetである。 byte id = binret[0]; if (id == 0x01) { XmlSerializer serializer = new XmlSerializer(typeof(DataTable)); var strm = new System.IO.MemoryStream(binret, 1, binret.Length - 1); DataTable value = (DataTable)serializer.Deserialize(strm); strm.Close(); result = value; } else { XmlSerializer serializer = new XmlSerializer(typeof(DataSet)); var strm = new System.IO.MemoryStream(binret, 1, binret.Length - 1); DataSet value = (DataSet)serializer.Deserialize(strm); strm.Close(); result = value; } } } this.appLog.Debug("<DA> Method: {0}.{1}, return: {2}", dataname, "" , (result == null) ? "null" : result.GetType().FullName ); // 結果セットを送信 MessageType mtp; if (thc.commdata.mType == MessageType.RequestDataWithBusy) { mtp = MessageType.ResponseWithFree; } else { mtp = MessageType.ResponseData; } this.OnReceived.Invoke(new CommunicationObject(mtp, dataname, result)); } catch (Exception ex) { // エラーを通知 string msg; MessageErrorType errtype = MessageErrorType.SystemError; if (ex.InnerException != null) { msg = ex.InnerException.Message; if (ex.InnerException is DBOpenException) { errtype = MessageErrorType.DBConnectError; } else if (ex.InnerException is DBGetException) { errtype = MessageErrorType.DBGetError; } else if (ex.InnerException is DBPutException) { errtype = MessageErrorType.DBUpdateError; } else if (ex.InnerException is DBUpdateConflictException) { errtype = MessageErrorType.UpdateConflict; } else { switch (thc.commdata.mType) { case MessageType.RequestData: errtype = MessageErrorType.DBGetError; break; case MessageType.UpdateData: errtype = MessageErrorType.DBUpdateError; break; case MessageType.CallStoredProcedure: errtype = MessageErrorType.DataError; break; default: errtype = MessageErrorType.SystemError; break; } } } else { msg = ex.Message; } this.appLog.Error(string.Format("<DataAccess> 例外発生:REQ={0}, message={1}", dataname, msg), ex); MessageType mtp; if (thc.commdata.mType == MessageType.RequestDataWithBusy) { mtp = MessageType.ErrorWithFree; } else { mtp = MessageType.Error; } this.OnReceived.Invoke(new CommunicationObject(mtp, errtype, dataname, string.Format("{0} [{1}]", ConstDataAccess.Error, msg))); } thc.isRunnig = false; }
/// <summary> /// データアクセスメソッドの実行 /// </summary> /// <param name="param">スレッド起動時に渡されるパラメータ(ThreadContext)</param> private void DataAccessLocal(object param) { ThreadContext thc = param as ThreadContext; thc.isRunnig = true; string dataname = thc.commdata.GetMessageName(); this.appLog.Debug("<DA> DataAccessThread ({0})", dataname); object[] reqparams = thc.commdata.GetParameters(); string fmt = string.Empty; for (int i = 0; i < reqparams.Length; i++) { fmt += (string.IsNullOrEmpty(fmt) ? "" : ", ") + string.Format("p{1}={0}{1}{2}", '{', i, '}'); } if (!string.IsNullOrEmpty(fmt)) { this.appLog.Debug("<DA> parameter:" + fmt, reqparams); } try { if (string.IsNullOrWhiteSpace(dataname)) { throw new FWThreadCoreDataException(ConstDataAccess.ErrDataTypeUnknown); } List <object> reqdata = new List <object>(); reqdata.AddRange(thc.commdata.GetParameters().ToList()); Assembly sAssembly = Assembly.LoadFrom(DataAccessConst.APLWCFDLL); Type stype = sAssembly.GetType(DataAccessConst.DACCLASSNAME); MethodInfo miSE = stype.GetMethod(DataAccessConst.GETCONFIGMETHODNAME); var cfg = miSE.Invoke(null, new object[] { dataname, }) as KyoeiSystem.Framework.Common.WCFDataAccessConfig; if (cfg == null) { throw new FWThreadCoreDataException(string.Format("{0} : {1}", dataname, ConstDataAccess.ErrUnknownMethod)); } Assembly oAssembly = Assembly.LoadFrom(cfg.Dll); // 接続情報をセット setupConnectString(oAssembly, thc.commdata); // データサービスのクラスを取得 string svcname = cfg.Namespace + "." + cfg.ServiceClass; Type svctype = oAssembly.GetType(svcname); var da = Activator.CreateInstance(svctype); // データ登録メソッドを取得 MethodInfo svcMethodInfo = null; ParameterInfo[] plist = null; svcMethodInfo = svctype.GetMethod(cfg.MethodName); if (svcMethodInfo == null) { this.appLog.Debug("<DA> Method: {0}.{1}", cfg.ServiceClass, cfg.MethodName); throw new FWThreadCoreDataException(ConstDataAccess.ErrUnknownMethod); } plist = svcMethodInfo.GetParameters(); // 引数を準備 int idx = 0; List <object> parameters = new List <object>(); foreach (object prm in reqdata) { try { // 引数がDataTableの場合は配列のインスタンスに変換 parameters.Add(ConvertFromDataTable(plist[idx++].ParameterType, prm)); } catch (Exception ex) { string msg = ex.Message; } } // ターゲットのメソッドを呼び出す var dat = svcMethodInfo.Invoke(da, parameters.ToArray()); this.appLog.Debug("<DA> Method: {0}.{1}, return: {2}", cfg.ServiceClass, cfg.MethodName , (dat == null) ? "null" : (dat.GetType().IsGenericType) ? "List<" + (dat.GetType().GetGenericArguments()[0].Name) + ">" : (dat) ); object result = null; // 戻り値を処理する if (dat != null) { if (thc.commdata.mType == MessageType.RequestDataNoManage) { result = dat; } else { // データメンバーからデータテーブルのカラムを作成 if (dat.GetType().IsGenericType) { var openType = dat.GetType().GetGenericTypeDefinition(); if (openType == typeof(Dictionary <,>)) { // ディクショナリはそのまま返す result = dat; } else { Type[] ts = dat.GetType().GetGenericArguments(); DataTable table = new DataTable(dataname); setupColumnsByProperties(ts[0], table); convertToDataTable(dat, table); result = table; } } else { if (dat.GetType().IsNested) { DataSet ds = new DataSet(dataname); foreach (var fld in dat.GetType().GetFields()) { var datN = fld.GetValue(dat); Type[] ts2 = datN.GetType().GetGenericArguments(); DataTable table = ds.Tables.Add(fld.Name); setupColumnsByProperties(ts2[0], table); convertToDataTable(datN, table); //result = table; } result = ds; } else { result = dat; } } } } else { result = null; } // 結果セットを送信 MessageType mtp; if (thc.commdata.mType == MessageType.RequestDataWithBusy) { mtp = MessageType.ResponseWithFree; } else { mtp = MessageType.ResponseData; } this.OnReceived.Invoke(new CommunicationObject(mtp, dataname, result)); } catch (Exception ex) { // エラーを通知 string msg; MessageErrorType errtype = MessageErrorType.SystemError; if (ex.InnerException != null) { msg = ex.InnerException.Message; if (ex.InnerException is DBOpenException) { errtype = MessageErrorType.DBConnectError; } else if (ex.InnerException is DBGetException) { errtype = MessageErrorType.DBGetError; } else if (ex.InnerException is DBPutException) { errtype = MessageErrorType.DBUpdateError; } else if (ex.InnerException is DBUpdateConflictException) { errtype = MessageErrorType.UpdateConflict; } else { switch (thc.commdata.mType) { case MessageType.RequestData: errtype = MessageErrorType.DBGetError; break; case MessageType.UpdateData: errtype = MessageErrorType.DBUpdateError; break; case MessageType.CallStoredProcedure: errtype = MessageErrorType.DataError; break; default: errtype = MessageErrorType.SystemError; break; } } } else { msg = ex.Message; } this.appLog.Error(string.Format("<DataAccess> 例外発生:REQ={0}, message={1}", dataname, msg), ex); MessageType mtp; if (thc.commdata.mType == MessageType.RequestDataWithBusy) { mtp = MessageType.ErrorWithFree; } else { mtp = MessageType.Error; } this.OnReceived.Invoke(new CommunicationObject(mtp, errtype, dataname, string.Format("{0} [{1}]", ConstDataAccess.Error, msg))); } thc.isRunnig = false; }