private static SavedFileDTO SaveFile(
                Stream stream,
                PortalSettings portalSettings,
                UserInfo userInfo,
                string folder,
                string filter,
                string fileName,
                bool overwrite,
                bool isHostMenu,
                bool extract,
                out bool alreadyExists,
                out string errorMessage)
        {
            alreadyExists = false;
            var savedFileDto = new SavedFileDTO();
            try
            {
                var extension = Path.GetExtension(fileName).TextOrEmpty().Replace(".", "");
                if (!string.IsNullOrEmpty(filter) && !filter.ToLower().Contains(extension.ToLower()))
                {
                    errorMessage = GetLocalizedString("ExtensionNotAllowed");
                    return savedFileDto;
                }

                if (!IsAllowedExtension(extension))
                {
                    errorMessage = GetLocalizedString("ExtensionNotAllowed");
                    return savedFileDto;
                }

                var folderManager = FolderManager.Instance;

                // Check if this is a User Folder
                var effectivePortalId = isHostMenu ? Null.NullInteger : PortalController.GetEffectivePortalId(portalSettings.PortalId);
                int userId;
                var folderInfo = folderManager.GetFolder(effectivePortalId, folder);
                if (IsUserFolder(folder, out userId))
                {
                    var user = UserController.GetUserById(effectivePortalId, userId);
                    if (user != null)
                    {
                        folderInfo = folderManager.GetUserFolder(user);
                    }
                }

                if (!PortalSecurity.IsInRoles(userInfo, portalSettings, folderInfo.FolderPermissions.ToString("WRITE")) 
                    && !PortalSecurity.IsInRoles(userInfo, portalSettings, folderInfo.FolderPermissions.ToString("ADD")))
                {
                    errorMessage = GetLocalizedString("NoPermission");
                    return savedFileDto;
                }

                if (!overwrite && FileManager.Instance.FileExists(folderInfo, fileName, true))
                {
                    errorMessage = GetLocalizedString("AlreadyExists");
                    alreadyExists = true;
                    savedFileDto.FilePath = Path.Combine(folderInfo.PhysicalPath, fileName);
                    return savedFileDto;
                }

                var file = FileManager.Instance.AddFile(folderInfo, fileName, stream, true, false, FileManager.Instance.GetContentType(Path.GetExtension(fileName)), userInfo.UserID);

                if (extract && extension.ToLower() == "zip")
                {
                    FileManager.Instance.UnzipFile(file);
                    FileManager.Instance.DeleteFile(file);
                }

                errorMessage = "";
                savedFileDto.FileId = file.FileId.ToString();
                savedFileDto.FilePath = Path.Combine(folderInfo.PhysicalPath, fileName);
                return savedFileDto;
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                errorMessage = ex.Message;
                return savedFileDto;
            }
        }
        private static SavedFileDTO SaveFile(
            Stream stream,
            PortalSettings portalSettings,
            UserInfo userInfo,
            string folder,
            string filter,
            string fileName,
            bool overwrite,
            bool isHostMenu,
            bool extract,
            out bool alreadyExists,
            out string errorMessage)
        {
            alreadyExists = false;
            var savedFileDto = new SavedFileDTO();

            try
            {
                var extension = Path.GetExtension(fileName).TextOrEmpty().Replace(".", "");
                if (!string.IsNullOrEmpty(filter) && !filter.ToLower().Contains(extension.ToLower()))
                {
                    errorMessage = GetLocalizedString("ExtensionNotAllowed");
                    return(savedFileDto);
                }

                if (!IsAllowedExtension(extension))
                {
                    errorMessage = GetLocalizedString("ExtensionNotAllowed");
                    return(savedFileDto);
                }

                var folderManager = FolderManager.Instance;

                // Check if this is a User Folder
                var effectivePortalId = isHostMenu ? Null.NullInteger : PortalController.GetEffectivePortalId(portalSettings.PortalId);
                int userId;
                var folderInfo = folderManager.GetFolder(effectivePortalId, folder);
                if (IsUserFolder(folder, out userId))
                {
                    var user = UserController.GetUserById(effectivePortalId, userId);
                    if (user != null)
                    {
                        folderInfo = folderManager.GetUserFolder(user);
                    }
                }

                if (!PortalSecurity.IsInRoles(userInfo, portalSettings, folderInfo.FolderPermissions.ToString("WRITE")) &&
                    !PortalSecurity.IsInRoles(userInfo, portalSettings, folderInfo.FolderPermissions.ToString("ADD")))
                {
                    errorMessage = GetLocalizedString("NoPermission");
                    return(savedFileDto);
                }

                // FIX DNN-5917
                fileName = SanitizeFileName(fileName);
                // END FIX

                if (!overwrite && FileManager.Instance.FileExists(folderInfo, fileName, true))
                {
                    errorMessage          = GetLocalizedString("AlreadyExists");
                    alreadyExists         = true;
                    savedFileDto.FilePath = Path.Combine(folderInfo.PhysicalPath, fileName);
                    return(savedFileDto);
                }

                var file = FileManager.Instance.AddFile(folderInfo, fileName, stream, true, false, FileManager.Instance.GetContentType(Path.GetExtension(fileName)), userInfo.UserID);

                if (extract && extension.ToLower() == "zip")
                {
                    FileManager.Instance.UnzipFile(file);
                    FileManager.Instance.DeleteFile(file);
                }

                errorMessage          = "";
                savedFileDto.FileId   = file.FileId.ToString(CultureInfo.InvariantCulture);
                savedFileDto.FilePath = FileManager.Instance.GetUrl(file);
                return(savedFileDto);
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                errorMessage = ex.Message;
                return(savedFileDto);
            }
        }
        public Task<HttpResponseMessage> PostFile()
        {
            HttpRequestMessage request = Request;

            if (!request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
            }

            var provider = new MultipartMemoryStreamProvider();

            // local references for use in closure
            var portalSettings = PortalSettings;
            var currentSynchronizationContext = SynchronizationContext.Current;
            var userInfo = UserInfo;
            var task = request.Content.ReadAsMultipartAsync(provider)
                .ContinueWith(o =>
                    {
                        string folder = string.Empty;
                        string filter = string.Empty;
                        string fileName = string.Empty;
                        bool overwrite = false;
                        bool isHostMenu = false;
                        bool extract = false;
                        Stream stream = null;
                        var returnFileDto = new SavedFileDTO();

                        foreach (var item in provider.Contents)
                        {
                            var name = item.Headers.ContentDisposition.Name;
                            switch (name.ToUpper())
                            {
                                case "\"FOLDER\"":
                                    folder = item.ReadAsStringAsync().Result ?? "";
                                    break;

                                case "\"FILTER\"":
                                    filter = item.ReadAsStringAsync().Result ?? "";
                                    break;

                                case "\"OVERWRITE\"":
                                    bool.TryParse(item.ReadAsStringAsync().Result, out overwrite);
                                    break;

                                case "\"ISHOSTMENU\"":
                                    bool.TryParse(item.ReadAsStringAsync().Result, out isHostMenu);
                                    break;

                                case "\"EXTRACT\"":
                                    bool.TryParse(item.ReadAsStringAsync().Result, out extract);
                                    break;

                                case "\"POSTFILE\"":
                                    fileName = item.Headers.ContentDisposition.FileName.Replace("\"", "");
                                    if (fileName.IndexOf("\\", StringComparison.Ordinal) != -1)
                                    {
                                        fileName = Path.GetFileName(fileName);
                                    }
                                    stream = item.ReadAsStreamAsync().Result;
                                    break;
                            }
                        }

                        var errorMessage = "";
                        var alreadyExists = false;
                        if (!string.IsNullOrEmpty(fileName) && stream != null)
                        {
                            // Everything ready
                            
                            // The SynchronizationContext keeps the main thread context. Send method is synchronous
                            currentSynchronizationContext.Send(
                                delegate
                                    {
                                        returnFileDto = SaveFile(stream, portalSettings, userInfo, folder, filter, fileName, overwrite, isHostMenu, extract, out alreadyExists, out errorMessage);
                                    },null
                                );
                            
                        }

                        /* Response Content Type cannot be application/json 
                         * because IE9 with iframe-transport manages the response 
                         * as a file download 
                         */
                        var mediaTypeFormatter = new JsonMediaTypeFormatter();
                        mediaTypeFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));

                        if (!string.IsNullOrEmpty(errorMessage))
                        {
                            return Request.CreateResponse(
                                HttpStatusCode.BadRequest,
                                new
                                {
                                    AlreadyExists = alreadyExists,
                                    Message = string.Format(GetLocalizedString("ErrorMessage"), fileName, errorMessage)
                                }, mediaTypeFormatter, "text/plain");
                        }

                        var root = AppDomain.CurrentDomain.BaseDirectory;
                        returnFileDto.FilePath = returnFileDto.FilePath.Replace(root, "~/");
                        returnFileDto.FilePath = VirtualPathUtility.ToAbsolute(returnFileDto.FilePath);

                        return Request.CreateResponse(HttpStatusCode.OK, returnFileDto, mediaTypeFormatter, "text/plain");
                    });

            return task; 
        }
        public Task <HttpResponseMessage> PostFile()
        {
            HttpRequestMessage request = Request;

            if (!request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            var provider = new MultipartMemoryStreamProvider();

            // local references for use in closure
            var portalSettings = PortalSettings;
            var currentSynchronizationContext = SynchronizationContext.Current;
            var userInfo = UserInfo;
            var task     = request.Content.ReadAsMultipartAsync(provider)
                           .ContinueWith(o =>
            {
                string folder     = string.Empty;
                string filter     = string.Empty;
                string fileName   = string.Empty;
                bool overwrite    = false;
                bool isHostMenu   = false;
                bool extract      = false;
                Stream stream     = null;
                var returnFileDto = new SavedFileDTO();

                foreach (var item in provider.Contents)
                {
                    var name = item.Headers.ContentDisposition.Name;
                    switch (name.ToUpper())
                    {
                    case "\"FOLDER\"":
                        folder = item.ReadAsStringAsync().Result ?? "";
                        break;

                    case "\"FILTER\"":
                        filter = item.ReadAsStringAsync().Result ?? "";
                        break;

                    case "\"OVERWRITE\"":
                        bool.TryParse(item.ReadAsStringAsync().Result, out overwrite);
                        break;

                    case "\"ISHOSTMENU\"":
                        bool.TryParse(item.ReadAsStringAsync().Result, out isHostMenu);
                        break;

                    case "\"EXTRACT\"":
                        bool.TryParse(item.ReadAsStringAsync().Result, out extract);
                        break;

                    case "\"POSTFILE\"":
                        fileName = item.Headers.ContentDisposition.FileName.Replace("\"", "");
                        if (fileName.IndexOf("\\", StringComparison.Ordinal) != -1)
                        {
                            fileName = Path.GetFileName(fileName);
                        }
                        stream = item.ReadAsStreamAsync().Result;
                        break;
                    }
                }

                var errorMessage  = "";
                var alreadyExists = false;
                if (!string.IsNullOrEmpty(fileName) && stream != null)
                {
                    // Everything ready

                    // The SynchronizationContext keeps the main thread context. Send method is synchronous
                    currentSynchronizationContext.Send(
                        delegate
                    {
                        returnFileDto = SaveFile(stream, portalSettings, userInfo, folder, filter, fileName, overwrite, isHostMenu, extract, out alreadyExists, out errorMessage);
                    }, null
                        );
                }

                /* Response Content Type cannot be application/json
                 * because IE9 with iframe-transport manages the response
                 * as a file download
                 */
                var mediaTypeFormatter = new JsonMediaTypeFormatter();
                mediaTypeFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));

                if (!string.IsNullOrEmpty(errorMessage))
                {
                    return(Request.CreateResponse(
                               HttpStatusCode.BadRequest,
                               new
                    {
                        AlreadyExists = alreadyExists,
                        Message = string.Format(GetLocalizedString("ErrorMessage"), fileName, errorMessage)
                    }, mediaTypeFormatter, "text/plain"));
                }

                return(Request.CreateResponse(HttpStatusCode.OK, returnFileDto, mediaTypeFormatter, "text/plain"));
            });

            return(task);
        }