///<summary></summary> public static void ProcessGetVoid(DtoGetVoid dto) { string result = SendAndReceive(dto); //this might throw an exception if server unavailable if (result != "0") { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw new Exception(exception.Message); } }
///<summary>Optionally set hasConnectionLost true to keep the calling thread here until a connection to the Middle Tier connection can be established ///in the event of a web connection failure. Set hasConnectionLost to false if a throw is desired when a connection cannot be made.</summary> public static void ProcessGetVoid(DtoGetVoid dto, bool hasConnectionLost = true) { string result = SendAndReceive(dto, hasConnectionLost); if (result != "0") { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw ThrowExceptionForDto(exception); } }
///<summary></summary> public static int ProcessGetInt(DtoGetInt dto) { string result = SendAndReceive(dto); //this might throw an exception if server unavailable try { return(PIn.Int(result)); } catch { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw new Exception(exception.Message); } }
///<summary></summary> public static double ProcessGetDouble(DtoGetDouble dto) { string result = SendAndReceive(dto); //this might throw an exception if server unavailable try { return(PIn.Double(result)); } catch { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw ThrowExceptionForDto(exception); } }
public static SerializableDictionary <K, V> ProcessGetSerializableDictionary <K, V>(DtoGetSerializableDictionary dto) { string result = SendAndReceive(dto); try { return(XmlConverter.Deserialize <SerializableDictionary <K, V> >(result)); } catch { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw ThrowExceptionForDto(exception); } }
public static DataTable ProcessGetTableLow(DtoGetTableLow dto) { string result = SendAndReceive(dto); try { return(XmlConverter.XmlToTable(result)); } catch { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw new Exception(exception.Message); } }
private static DtoException GetDtoException(Exception e) { DtoException dtoException = new DtoException(); //The typical outter exception will be a TargetInvocationException due to how we process known DTO payloads. //Therefore, we need to get the InnerException which will be the actual exception that the method that was invoked threw. //E.g. we need to preserve the fact that an S class method threw an ODException and pass that along to the client workstation. dtoException.ExceptionType = e.GetType().Name; if (e.GetType() == typeof(ODException)) { dtoException.ErrorCode = ((ODException)e).ErrorCode; } dtoException.Message = e.Message; return(dtoException); }
///<summary></summary> public static bool ProcessGetBool(DtoGetBool dto) { string result = SendAndReceive(dto); if (result == "True") { return(true); } if (result == "False") { return(false); } DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw new Exception(exception.Message); }
///<summary>Optionally set hasConnectionLost true to keep the calling thread here until a connection to the Middle Tier connection can be established ///in the event of a web connection failure. Set hasConnectionLost to false if a throw is desired when a connection cannot be made.</summary> public static DataSet ProcessGetDS(DtoGetDS dto, bool hasConnectionLost = true) { string result = SendAndReceive(dto, hasConnectionLost); if (Regex.IsMatch(result, "<DtoException xmlns:xsi=")) { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw new Exception(exception.Message); } try { return(XmlConverter.XmlToDs(result)); } catch (Exception ex) { throw ProcessExceptionDeserialize(result, ex); } }
///<summary>Optionally set hasConnectionLost true to keep the calling thread here until a connection to the Middle Tier connection can be established ///in the event of a web connection failure. Set hasConnectionLost to false if a throw is desired when a connection cannot be made.</summary> public static bool ProcessGetBool(DtoGetBool dto, bool hasConnectionLost = true) { string result = SendAndReceive(dto, hasConnectionLost); if (result == "True") { return(true); } if (result == "False") { return(false); } DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw ThrowExceptionForDto(exception); }
///<summary></summary> public static DataSet ProcessGetDS(DtoGetDS dto) { string result = SendAndReceive(dto); if (Regex.IsMatch(result, "<DtoException xmlns:xsi=")) { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw new Exception(exception.Message); } try { return(XmlConverter.XmlToDs(result)); } catch { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw ThrowExceptionForDto(exception); } }
///<summary>This is the new way. It will be replacing the many different types of DTOs that we currently have.</summary> public static DataSet ProcessGetDS(DtoGetDS dto) { byte[] buffer = SendAndReceive(dto);//this might throw an exception if server unavailable MemoryStream memStream = new MemoryStream(buffer); XmlSerializer serializer; try { serializer = new XmlSerializer(typeof(DataSet)); DataSet retVal = (DataSet)serializer.Deserialize(memStream); memStream.Close(); return(retVal); } catch { memStream = new MemoryStream(buffer); //just in case stream is in wrong position. serializer = new XmlSerializer(typeof(DtoException)); DtoException exception = (DtoException)serializer.Deserialize(memStream); memStream.Close(); throw new Exception(exception.Message); } }
///<summary>InsertID will be returned for Insert commands. Other commands return the number of rows affected which is usually just ignored.</summary> public static int ProcessCommand(DtoCommandBase dto) { byte[] buffer = SendAndReceive(dto);//this might throw an exception if server unavailable MemoryStream memStream = new MemoryStream(buffer); XmlSerializer serializer; try{ serializer = new XmlSerializer(typeof(DtoServerAck)); DtoServerAck ack = (DtoServerAck)serializer.Deserialize(memStream); memStream.Close(); return(ack.IDorRows); } catch { memStream = new MemoryStream(buffer); //just in case stream is in wrong position. serializer = new XmlSerializer(typeof(DtoException)); DtoException exception = (DtoException)serializer.Deserialize(memStream); memStream.Close(); throw new Exception(exception.Message); } }
///<summary>Open Dental can require specific exceptions to be thrown. This is a helper method that throws the correct exception type. ///Add this function directly into a throw statement, so that the calling code knows that the code path will not need to return a value.</summary> private static Exception ThrowExceptionForDto(DtoException exception) { switch (exception.ExceptionType) { case "ApplicationException": throw new ApplicationException(exception.Message); case "InvalidProgramException": throw new InvalidProgramException(exception.Message); case "NotSupportedException": throw new NotSupportedException(exception.Message); case "ODException": throw new ODException(exception.Message, exception.ErrorCode); default: //Throw a generic exception which follows the old functionality for any other Exception type that we weren't explicitly expecting. throw new Exception(exception.Message); } }
///<summary></summary> public static T ProcessGetObject <T>(DtoGetObject dto) { string result = SendAndReceive(dto); //this might throw an exception if server unavailable try { return(XmlConverter.Deserialize <T>(result)); /* * XmlSerializer serializer=new XmlSerializer(typeof(T)); * //Type.GetType("OpenDentBusiness."+dto.ObjectType)); * StringReader strReader=new StringReader(result); * XmlReader xmlReader=XmlReader.Create(strReader); * object obj=serializer.Deserialize(xmlReader); * strReader.Close(); * xmlReader.Close(); * return (T)obj;*/ } catch { DtoException exception = (DtoException)DataTransferObject.Deserialize(result); throw new Exception(exception.Message); } }
public string ProcessRequest(string dtoString) { //The web service (xml) serializer/deserializer is removing the '\r' portion of our newlines during the data transfer. //Replacing the string is not the best solution but it works for now. The replacing happens here (server side) and after result is returned on the client side. //It's done server side for usage purposes within the methods being called (exampe: inserting into db) and then on the client side for displaying purposes. dtoString=dtoString.Replace("\n","\r\n"); #if DEBUG //System.Threading.Thread.Sleep(100);//to test slowness issues with web service. #endif DataTransferObject dto=DataTransferObject.Deserialize(dtoString); //XmlSerializer serializer; try { Type type = dto.GetType(); if(type == typeof(DtoGetTable)) { DtoGetTable dtoGetTable=(DtoGetTable)dto; Userods.CheckCredentials(dtoGetTable.Credentials);//will throw exception if fails. string className=dtoGetTable.MethodName.Split('.')[0]; string methodName=dtoGetTable.MethodName.Split('.')[1]; string assemb=Assembly.GetAssembly(typeof(Db)).FullName;//any OpenDentBusiness class will do. Type classType=Type.GetType("OpenDentBusiness."+className+","+assemb); DtoObject[] parameters=dtoGetTable.Params; Type[] paramTypes=DtoObject.GenerateTypes(parameters,assemb); MethodInfo methodInfo=classType.GetMethod(methodName,paramTypes); if(methodInfo==null) { throw new ApplicationException("Method not found with "+parameters.Length.ToString()+" parameters: "+dtoGetTable.MethodName); } object[] paramObjs=DtoObject.GenerateObjects(parameters); DataTable dt=(DataTable)methodInfo.Invoke(null,paramObjs); String response=XmlConverter.TableToXml(dt); return response; } else if(type == typeof(DtoGetTableLow)) { DtoGetTableLow dtoGetTableLow=(DtoGetTableLow)dto; Userods.CheckCredentials(dtoGetTableLow.Credentials);//will throw exception if fails. DtoObject[] parameters=dtoGetTableLow.Params; object[] paramObjs=DtoObject.GenerateObjects(parameters); DataTable dt=Reports.GetTable((string)paramObjs[0]); String response=XmlConverter.TableToXml(dt); return response; } else if(type == typeof(DtoGetDS)) { DtoGetDS dtoGetDS=(DtoGetDS)dto; Userods.CheckCredentials(dtoGetDS.Credentials);//will throw exception if fails. string className=dtoGetDS.MethodName.Split('.')[0]; string methodName=dtoGetDS.MethodName.Split('.')[1]; string assemb=Assembly.GetAssembly(typeof(Db)).FullName;//any OpenDentBusiness class will do. Type classType=Type.GetType("OpenDentBusiness."+className+","+assemb); DtoObject[] parameters=dtoGetDS.Params; Type[] paramTypes=DtoObject.GenerateTypes(parameters,assemb); MethodInfo methodInfo=classType.GetMethod(methodName,paramTypes); if(methodInfo==null) { throw new ApplicationException("Method not found with "+parameters.Length.ToString()+" parameters: "+dtoGetDS.MethodName); } object[] paramObjs=DtoObject.GenerateObjects(parameters); DataSet ds=(DataSet)methodInfo.Invoke(null,paramObjs); String response=XmlConverter.DsToXml(ds); return response; } else if(type == typeof(DtoGetLong)) { DtoGetLong dtoGetLong=(DtoGetLong)dto; Userods.CheckCredentials(dtoGetLong.Credentials);//will throw exception if fails. string className=dtoGetLong.MethodName.Split('.')[0]; string methodName=dtoGetLong.MethodName.Split('.')[1]; string assemb=Assembly.GetAssembly(typeof(Db)).FullName;//any OpenDentBusiness class will do. Type classType=Type.GetType("OpenDentBusiness."+className+","+assemb); DtoObject[] parameters=dtoGetLong.Params; Type[] paramTypes=DtoObject.GenerateTypes(parameters,assemb); MethodInfo methodInfo=classType.GetMethod(methodName,paramTypes); if(methodInfo==null) { throw new ApplicationException("Method not found with "+parameters.Length.ToString()+" parameters: "+dtoGetLong.MethodName); } object[] paramObjs=DtoObject.GenerateObjects(parameters); long longResult=(long)methodInfo.Invoke(null,paramObjs); return longResult.ToString(); } else if(type == typeof(DtoGetInt)) { DtoGetInt dtoGetInt=(DtoGetInt)dto; Userods.CheckCredentials(dtoGetInt.Credentials);//will throw exception if fails. string className=dtoGetInt.MethodName.Split('.')[0]; string methodName=dtoGetInt.MethodName.Split('.')[1]; string assemb=Assembly.GetAssembly(typeof(Db)).FullName;//any OpenDentBusiness class will do. Type classType=Type.GetType("OpenDentBusiness."+className+","+assemb); DtoObject[] parameters=dtoGetInt.Params; Type[] paramTypes=DtoObject.GenerateTypes(parameters,assemb); MethodInfo methodInfo=classType.GetMethod(methodName,paramTypes); if(methodInfo==null) { throw new ApplicationException("Method not found with "+parameters.Length.ToString()+" parameters: "+dtoGetInt.MethodName); } object[] paramObjs=DtoObject.GenerateObjects(parameters); int intResult=(int)methodInfo.Invoke(null,paramObjs); return intResult.ToString(); } else if(type == typeof(DtoGetVoid)) { DtoGetVoid dtoGetVoid=(DtoGetVoid)dto; Userods.CheckCredentials(dtoGetVoid.Credentials);//will throw exception if fails. string className=dtoGetVoid.MethodName.Split('.')[0]; string methodName=dtoGetVoid.MethodName.Split('.')[1]; string assemb=Assembly.GetAssembly(typeof(Db)).FullName;//any OpenDentBusiness class will do. Type classType=Type.GetType("OpenDentBusiness."+className+","+assemb); DtoObject[] parameters=dtoGetVoid.Params; Type[] paramTypes=DtoObject.GenerateTypes(parameters,assemb); MethodInfo methodInfo=classType.GetMethod(methodName,paramTypes); if(methodInfo==null) { throw new ApplicationException("Method not found with "+parameters.Length.ToString()+" parameters: "+dtoGetVoid.MethodName); } object[] paramObjs=DtoObject.GenerateObjects(parameters); methodInfo.Invoke(null,paramObjs); return "0"; } else if(type == typeof(DtoGetObject)) { DtoGetObject dtoGetObject=(DtoGetObject)dto; string className=dtoGetObject.MethodName.Split('.')[0]; string methodName=dtoGetObject.MethodName.Split('.')[1]; if(className != "Security" || methodName != "LogInWeb") {//because credentials will be checked inside that method Userods.CheckCredentials(dtoGetObject.Credentials);//will throw exception if fails. } string assemb=Assembly.GetAssembly(typeof(Db)).FullName;//any OpenDentBusiness class will do. Type classType=Type.GetType("OpenDentBusiness."+className+","+assemb); DtoObject[] parameters=dtoGetObject.Params; Type[] paramTypes=DtoObject.GenerateTypes(parameters,assemb); MethodInfo methodInfo=classType.GetMethod(methodName,paramTypes); if(methodInfo==null) { throw new ApplicationException("Method not found with "+parameters.Length.ToString()+" parameters: "+dtoGetObject.MethodName); } if(className=="Security" && methodName=="LogInWeb") { string mappedPath=Server.MapPath("."); parameters[2]=new DtoObject(mappedPath,typeof(string));//because we can't access this variable from within OpenDentBusiness. RemotingClient.RemotingRole=RemotingRole.ServerWeb; } object[] paramObjs=DtoObject.GenerateObjects(parameters); Object objResult=methodInfo.Invoke(null,paramObjs); Type returnType=methodInfo.ReturnType; return XmlConverter.Serialize(returnType,objResult); } else if(type == typeof(DtoGetString)) { DtoGetString dtoGetString=(DtoGetString)dto; Userods.CheckCredentials(dtoGetString.Credentials);//will throw exception if fails. string className=dtoGetString.MethodName.Split('.')[0]; string methodName=dtoGetString.MethodName.Split('.')[1]; string assemb=Assembly.GetAssembly(typeof(Db)).FullName;//any OpenDentBusiness class will do. Type classType=Type.GetType("OpenDentBusiness."+className+","+assemb); DtoObject[] parameters=dtoGetString.Params; Type[] paramTypes=DtoObject.GenerateTypes(parameters,assemb); MethodInfo methodInfo=classType.GetMethod(methodName,paramTypes); if(methodInfo==null) { throw new ApplicationException("Method not found with "+parameters.Length.ToString()+" parameters: "+dtoGetString.MethodName); } object[] paramObjs=DtoObject.GenerateObjects(parameters); string strResult=(string)methodInfo.Invoke(null,paramObjs); //strResult=strResult.Replace("\r","\\r"); //return XmlConverter.Serialize(typeof(string),strResult); return strResult; } else if(type == typeof(DtoGetBool)) { DtoGetBool dtoGetBool=(DtoGetBool)dto; Userods.CheckCredentials(dtoGetBool.Credentials);//will throw exception if fails. string className=dtoGetBool.MethodName.Split('.')[0]; string methodName=dtoGetBool.MethodName.Split('.')[1]; string assemb=Assembly.GetAssembly(typeof(Db)).FullName;//any OpenDentBusiness class will do. Type classType=Type.GetType("OpenDentBusiness."+className+","+assemb); DtoObject[] parameters=dtoGetBool.Params; Type[] paramTypes=DtoObject.GenerateTypes(parameters,assemb); MethodInfo methodInfo=classType.GetMethod(methodName,paramTypes); if(methodInfo==null) { throw new ApplicationException("Method not found with "+parameters.Length.ToString()+" parameters: "+dtoGetBool.MethodName); } object[] paramObjs=DtoObject.GenerateObjects(parameters); bool boolResult=(bool)methodInfo.Invoke(null,paramObjs); return boolResult.ToString(); } else { throw new NotSupportedException("Dto type not supported: "+type.FullName); } } catch(Exception e) { DtoException exception = new DtoException(); if(e.InnerException==null) { exception.Message = e.Message; } else { exception.Message = e.InnerException.Message; } return exception.Serialize(); } }
///<summary>Pass in a serialized dto. It returns a dto which must be deserialized by the client. ///Set serverMapPath to the root directory of the OpenDentalServerConfig.xml. Typically Server.MapPath(".") from a web service. ///Optional parameter because it is not necessary for Unit Tests (mock server).</summary> public static string ProcessDto(string dtoString, string serverMapPath = "") { #if DEBUG //System.Threading.Thread.Sleep(100);//to test slowness issues with web service. #endif DataTransferObject dto = DataTransferObject.Deserialize(dtoString); try { string[] methNameComps = GetComponentsFromDtoMeth(dto.MethodName); if (methNameComps.Length == 3 && methNameComps[2].ToLower() == "hashpassword") { return(GetHashPassword(dto)); } //Always attempt to set the database connection settings from the config file if they haven't been set yet. //We use to ONLY load in database settings when Security.LogInWeb was called but that is not good enough now that we have more services. //E.g. We do not want to manually call "Security.LogInWeb" from the CEMT when all we want is a single preference value. if (string.IsNullOrEmpty(DataConnection.GetServerName()) && string.IsNullOrEmpty(DataConnection.GetConnectionString())) { RemotingClient.RemotingRole = RemotingRole.ServerWeb; //the application virtual path is usually /OpenDentalServer, but may be different if hosting multiple databases on one IIS server string configFilePath = ""; if (!string.IsNullOrWhiteSpace(HostingEnvironment.ApplicationVirtualPath) && HostingEnvironment.ApplicationVirtualPath.Length > 1) { //There can be multiple config files within a physical path that is shared by multiple IIS ASP.NET applications. //In order for the same physical path to host multiple applications, they each need a unique config file for db connection settings. //Each application will have a unique ApplicationVirtualPath which we will use to identify the corresponding config.xml. configFilePath = ODFileUtils.CombinePaths(serverMapPath, HostingEnvironment.ApplicationVirtualPath.Trim('/') + "Config.xml"); } if (string.IsNullOrWhiteSpace(configFilePath) || !File.Exists(configFilePath)) //returns false if the file doesn't exist, user doesn't have permission for file, path is blank or null { //either configFilePath not set or file doesn't exist, default to OpenDentalServerConfig.xml configFilePath = ODFileUtils.CombinePaths(serverMapPath, "OpenDentalServerConfig.xml"); } Userods.LoadDatabaseInfoFromFile(configFilePath); } //Set Security.CurUser so that queries can be run against the db as if it were this user. Security.CurUser = Userods.CheckUserAndPassword(dto.Credentials.Username , dto.Credentials.Password , Programs.IsEnabled(ProgramName.eClinicalWorks)); Security.PasswordTyped = dto.Credentials.Password; Type type = dto.GetType(); #region DtoGetTable if (type == typeof(DtoGetTable)) { DtoGetTable dtoGetTable = (DtoGetTable)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetTable.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetTable.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetTable.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); DataTable dt = (DataTable)methodInfo.Invoke(null, paramObjs); String response = XmlConverter.TableToXml(dt); return(response); } #endregion #region DtoGetTableLow else if (type == typeof(DtoGetTableLow)) { DtoGetTableLow dtoGetTableLow = (DtoGetTableLow)dto; DtoObject[] parameters = dtoGetTableLow.Params; object[] paramObjs = DtoObject.GenerateObjects(parameters); DataTable dt = Reports.GetTable((string)paramObjs[0]); String response = XmlConverter.TableToXml(dt); return(response); } #endregion #region DtoGetDS else if (type == typeof(DtoGetDS)) { DtoGetDS dtoGetDS = (DtoGetDS)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetDS.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetDS.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetDS.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); DataSet ds = (DataSet)methodInfo.Invoke(null, paramObjs); String response = XmlConverter.DsToXml(ds); return(response); } #endregion #region DtoGetSerializableDictionary else if (type == typeof(DtoGetSerializableDictionary)) { DtoGetSerializableDictionary dtoGetSD = (DtoGetSerializableDictionary)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetSD.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetSD.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetSD.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); Object objResult = methodInfo.Invoke(null, paramObjs); Type returnType = methodInfo.ReturnType; return(XmlConverter.Serialize(returnType, objResult)); } #endregion #region DtoGetLong else if (type == typeof(DtoGetLong)) { DtoGetLong dtoGetLong = (DtoGetLong)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetLong.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetLong.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetLong.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); long longResult = (long)methodInfo.Invoke(null, paramObjs); return(longResult.ToString()); } #endregion #region DtoGetInt else if (type == typeof(DtoGetInt)) { DtoGetInt dtoGetInt = (DtoGetInt)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetInt.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetInt.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetInt.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); int intResult = (int)methodInfo.Invoke(null, paramObjs); return(intResult.ToString()); } #endregion #region DtoGetDouble else if (type == typeof(DtoGetDouble)) { DtoGetDouble dtoGetDouble = (DtoGetDouble)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetDouble.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetDouble.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetDouble.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); double doubleResult = (double)methodInfo.Invoke(null, paramObjs); return(doubleResult.ToString()); } #endregion #region DtoGetVoid else if (type == typeof(DtoGetVoid)) { DtoGetVoid dtoGetVoid = (DtoGetVoid)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetVoid.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetVoid.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetVoid.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); methodInfo.Invoke(null, paramObjs); return("0"); } #endregion #region DtoGetObject else if (type == typeof(DtoGetObject)) { DtoGetObject dtoGetObject = (DtoGetObject)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetObject.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; //if(className != "Security" || methodName != "LogInWeb") {//because credentials will be checked inside that method // Userods.CheckCredentials(dtoGetObject.Credentials);//will throw exception if fails. //} Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); //if(className!="Security" || methodName!="LogInWeb") {//Do this for everything except Security.LogInWeb, because Plugins.GetAssembly will fail in that case. // ass=Plugins.GetAssembly(assemblyName); //} if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetObject.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetObject.MethodName); } if (className == "Security" && methodName == "LogInWeb") { parameters[2] = new DtoObject(serverMapPath, typeof(string)); //because we can't access this variable from within OpenDentBusiness. RemotingClient.RemotingRole = RemotingRole.ServerWeb; } object[] paramObjs = DtoObject.GenerateObjects(parameters); Object objResult = methodInfo.Invoke(null, paramObjs); Type returnType = methodInfo.ReturnType; if (returnType.IsInterface) { objResult = new DtoObject(objResult, objResult?.GetType() ?? returnType); returnType = typeof(DtoObject); } return(XmlConverter.Serialize(returnType, objResult)); } #endregion #region DtoGetString else if (type == typeof(DtoGetString)) { DtoGetString dtoGetString = (DtoGetString)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetString.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetString.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetString.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); string strResult = (string)methodInfo.Invoke(null, paramObjs); strResult = XmlConverter.XmlEscape(strResult); return(strResult); } #endregion #region DtoGetBool else if (type == typeof(DtoGetBool)) { DtoGetBool dtoGetBool = (DtoGetBool)dto; string[] fullNameComponents = GetComponentsFromDtoMeth(dtoGetBool.MethodName); string assemblyName = fullNameComponents[0]; //OpenDentBusiness or else a plugin name string className = fullNameComponents[1]; string methodName = fullNameComponents[2]; Type classType = null; Assembly ass = Plugins.GetAssembly(assemblyName); if (ass == null) { classType = Type.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className + "," + assemblyName); } else //plugin was found { classType = ass.GetType(assemblyName //actually, the namespace which we require to be same as assembly by convention + "." + className); } DtoObject[] parameters = dtoGetBool.Params; Type[] paramTypes = DtoObject.GenerateTypes(parameters, assemblyName); MethodInfo methodInfo = classType.GetMethod(methodName, paramTypes); if (methodInfo == null) { throw new ApplicationException("Method not found with " + parameters.Length.ToString() + " parameters: " + dtoGetBool.MethodName); } object[] paramObjs = DtoObject.GenerateObjects(parameters); bool boolResult = (bool)methodInfo.Invoke(null, paramObjs); return(boolResult.ToString()); } #endregion else { throw new NotSupportedException("Dto type not supported: " + type.FullName); } } catch (Exception e) { DtoException exception = new DtoException(); exception.ExceptionType = e.GetType().BaseType.Name; //Since the exception was down converted to a regular exception, we need the BaseType. if (e.InnerException == null) { exception.Message = e.Message; } else { exception.Message = e.InnerException.Message; } return(exception.Serialize()); } }
///<summary>Pass in a serialized dto. It returns a dto which must be deserialized by the client. ///Set serverMapPath to the root directory of the OpenDentalServerConfig.xml. Typically Server.MapPath(".") from a web service. ///Optional parameter because it is not necessary for Unit Tests (mock server).</summary> public static string ProcessDto(string dtoString, string serverMapPath = "") { try { #region Normalize DateTime if (!_isMiddleTierInitialized) { //If this fails, the exception will throw and be serialized and sent to the client. ODInitialize.Initialize(); //Because Security._curUserT is a thread static field, we need to make sure that any new threads that are spawned have that field set. ODThread.AddInitializeHandler <Userod>(() => Security.CurUser.Copy(), user => Security.CurUser = user); //Same thing for PasswordTyped. ODThread.AddInitializeHandler <string>(() => Security.PasswordTyped, password => Security.PasswordTyped = password); //Ditto for CurComputerName ODThread.AddInitializeHandler <string>(() => Security.CurComputerName, computerName => Security.CurComputerName = computerName); //Calling CDT.Class1.Decrypt will cause CDT to verify the assembly and then save the encryption key. This needs to be done here because //if we later call CDT.Class1.Decrypt inside a thread, we won't we able to find OpenDentalServer.dll in the call stack. ODException.SwallowAnyException(() => CDT.Class1.Decrypt("odv2e$fakeciphertext", out _)); _isMiddleTierInitialized = true; } #endregion #region Initialize Database Connection //Always attempt to set the database connection settings from the config file if they haven't been set yet. //We use to ONLY load in database settings when Security.LogInWeb was called but that is not good enough now that we have more services. //E.g. We do not want to manually call "Security.LogInWeb" from the CEMT when all we want is a single preference value. if (string.IsNullOrEmpty(DataConnection.GetServerName()) && string.IsNullOrEmpty(DataConnection.GetConnectionString())) { RemotingClient.RemotingRole = RemotingRole.ServerWeb; //the application virtual path is usually /OpenDentalServer, but may be different if hosting multiple databases on one IIS server string configFilePath = ""; if (!string.IsNullOrWhiteSpace(HostingEnvironment.ApplicationVirtualPath) && HostingEnvironment.ApplicationVirtualPath.Length > 1) { //There can be multiple config files within a physical path that is shared by multiple IIS ASP.NET applications. //In order for the same physical path to host multiple applications, they each need a unique config file for db connection settings. //Each application will have a unique ApplicationVirtualPath which we will use to identify the corresponding config.xml. configFilePath = ODFileUtils.CombinePaths(serverMapPath, HostingEnvironment.ApplicationVirtualPath.Trim('/') + "Config.xml"); } if (string.IsNullOrWhiteSpace(configFilePath) || !File.Exists(configFilePath)) //returns false if the file doesn't exist, user doesn't have permission for file, path is blank or null { //either configFilePath not set or file doesn't exist, default to OpenDentalServerConfig.xml configFilePath = ODFileUtils.CombinePaths(serverMapPath, "OpenDentalServerConfig.xml"); } Userods.LoadDatabaseInfoFromFile(configFilePath); } #endregion DataTransferObject dto = DataTransferObject.Deserialize(dtoString); DtoInformation dtoInformation = new DtoInformation(dto); if (dtoInformation.FullNameComponents.Length == 3 && dtoInformation.FullNameComponents[2].ToLower() == "hashpassword") { return(dtoInformation.GetHashPassword()); } //Set Security.CurUser so that queries can be run against the db as if it were this user. Security.CurUser = Userods.CheckUserAndPassword(dto.Credentials.Username, dto.Credentials.Password , Programs.UsingEcwTightOrFullMode()); Security.PasswordTyped = dto.Credentials.Password; //Set the computer name so securitylog entries use the client's computer name instead of the middle tier server name //Older clients might not include ComputerName in the dto, so we need to make sure it's not null. Security.CurComputerName = dto.ComputerName ?? ""; Type type = dto.GetType(); #region DtoGetTable if (type == typeof(DtoGetTable)) { DataTable dt = (DataTable)dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); return(XmlConverter.TableToXml(dt)); } #endregion #region DtoGetTableLow else if (type == typeof(DtoGetTableLow)) { DataTable dt = Reports.GetTable((string)dtoInformation.ParamObjs[0]); return(XmlConverter.TableToXml(dt)); } #endregion #region DtoGetDS else if (type == typeof(DtoGetDS)) { DataSet ds = (DataSet)dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); return(XmlConverter.DsToXml(ds)); } #endregion #region DtoGetSerializableDictionary else if (type == typeof(DtoGetSerializableDictionary)) { Object objResult = dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); Type returnType = dtoInformation.MethodInfo.ReturnType; return(XmlConverterSerializer.Serialize(returnType, objResult)); } #endregion #region DtoGetLong else if (type == typeof(DtoGetLong)) { long longResult = (long)dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); return(longResult.ToString()); } #endregion #region DtoGetInt else if (type == typeof(DtoGetInt)) { int intResult = (int)dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); return(intResult.ToString()); } #endregion #region DtoGetDouble else if (type == typeof(DtoGetDouble)) { double doubleResult = (double)dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); return(doubleResult.ToString()); } #endregion #region DtoGetVoid else if (type == typeof(DtoGetVoid)) { dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); return("0"); } #endregion #region DtoGetObject else if (type == typeof(DtoGetObject)) { if (dtoInformation.ClassName == "Security" && dtoInformation.MethodName == "LogInWeb") { dtoInformation.Parameters[2] = new DtoObject(serverMapPath, typeof(string)); //because we can't access this variable from within OpenDentBusiness. RemotingClient.RemotingRole = RemotingRole.ServerWeb; //We just changed the number of parameters so we need to regenerate ParamObjs. dtoInformation.ParamObjs = DtoObject.GenerateObjects(dtoInformation.Parameters); } Object objResult = dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); Type returnType = dtoInformation.MethodInfo.ReturnType; if (returnType.IsInterface) { objResult = new DtoObject(objResult, objResult?.GetType() ?? returnType); returnType = typeof(DtoObject); } return(XmlConverterSerializer.Serialize(returnType, objResult)); } #endregion #region DtoGetString else if (type == typeof(DtoGetString)) { string strResult = (string)dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); return(XmlConverter.XmlEscape(strResult)); } #endregion #region DtoGetBool else if (type == typeof(DtoGetBool)) { bool boolResult = (bool)dtoInformation.MethodInfo.Invoke(null, dtoInformation.ParamObjs); return(boolResult.ToString()); } #endregion else { throw new NotSupportedException("Dto type not supported: " + type.FullName); } } catch (Exception e) { DtoException exception = new DtoException(); if (e.InnerException == null) { exception = GetDtoException(e); } else { exception = GetDtoException(e.InnerException); } return(exception.Serialize()); } }