Exemplo n.º 1
0
 ///<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());
     }
 }