Beispiel #1
0
        public bool Execute(IBackloadContext context, IDeleteFilesRequestParam param)
        {
            // In this extension we delete the copies we've created within the _Backup and _Temp folder.
            // Backload has made the copies within the _Backup folder automatically, because it is configured to do so (config file) 
            // The copies within the _Temp folder were created for demo purposes in the StoreFileRequest extension.
            string dirBackup = string.Empty;
            string dirTemp = string.Empty;

            if (param.DeleteFiles == null) return false; // in the case something went wrong.
            if (param.DeleteFiles.Files.Count > 0)
            {
                dirTemp = Path.GetDirectoryName(Helper.GetLocalFilePath(context.Request, param.DeleteFiles.First().FileUrl).Replace("\\Uploads", "\\_Temp")); // Helper method in Backload.Contracts to get the full local file path
                dirBackup = Path.GetDirectoryName(Helper.GetLocalFilePath(context.Request, param.DeleteFiles.First().FileUrl).Replace("\\Uploads", "\\_Backup")); // Helper method in Backload.Contracts to get the full local file path
            }

            foreach (var file in param.DeleteFiles.Files)
            {
                // Synchronous deletion:
                // Delete the backup file Backload created (see config file)
                string pathBackupFile = Path.Combine(dirBackup, file.FileName);
                if (File.Exists(pathBackupFile)) File.Delete(pathBackupFile);

                // Asynchronous deletion with Tasks:
                // Demo 6: Running and awaiting a method asynchronously in a thread of the AppDomains thread pool.
                // Note: We do not use await here, because we have implemented the synchronous interface.
                // The Tasks will be awaited at the end of the extension point for the FilesDelete extension. If we do not await the 
                // result, the task may be aborted and does not finish file deletion.
                var t = Task.Run(() => DeleteTempFiles(dirTemp, file.FileName));
                context.PipelineControl.TaskManager.ExtensionPointTasks.Add(t);
            }
            return (param.DeleteFiles.Files.Count > 0);
        }
Beispiel #2
0
        public bool Execute(IBackloadContext context, IIncomingRequestParam param)
        {
            // Demo 2: Comment out the following line and rebuild the solution
            return(false);

            if (context.HttpMethod == "POST")
            {
                int    startIdx  = context.PipelineControl.Message.MessageCode;
                string subfolder = string.Empty;
                if (startIdx < 8)
                {
                    subfolder = DateTime.Now.ToString(datetime[startIdx]);
                }
                else
                {
                    subfolder = lorem[startIdx - 8];
                }

                if (string.IsNullOrEmpty(param.BackloadValues.UploadContext) == false)
                {
                    param.BackloadValues.UploadContext += ";";                                                                    // Seperate subfolders with a semicolon
                }
                param.BackloadValues.UploadContext += subfolder;

                // There are multiple ways sharing data between extensions. Here we use PipelineControl.Message to increase the index.
                // Note, that the ExtensionLogger logs the messages (subfolders) in PipelineControl.Message returned from the extension
                context.PipelineControl.Message.MessageText  = subfolder;
                context.PipelineControl.Message.MessageCode += 1;

                return(true); // Processed value is true, because the extension has changed properties.
            }

            return(false); // No properties have been changed, so false is returned.
        }
Beispiel #3
0
        public bool Execute(IBackloadContext context, IIncomingRequestParam param)
        {
            if (context.HttpMethod == "POST")
            {
                // This extension validate if the artist is in the database, and returns a Bad Request status (400) if not.

                // IMPORTANT: Don't forget to rebuild the extension when you changed code. Otherwise you may use the old extensions code.
                using (var artists = new ArtistsLibrary())
                {
                    var artist = artists.Artists.FirstOrDefault(a => a.ArtistId == param.BackloadValues.ObjectContext);

                    if (artist == null)  // Artist not in list
                    {
                        // Stop further processing of the pipeline but all extensions can do their work (maybe logging, etc.).
                        // The outgoing extension will also be called, so you have the chance to change the response to the client.
                        context.PipelineControl.ExecutePipeline = false;
                        // Because we prevented the execution of the core pipeline (where the core method for executing
                        // this request is) we do not generate a FileUploadStatus which holds the status of all files this request
                        // handles. IIncomingRequest is the first extension point and FileUploadStatus is generated later in the core pipeline.
                        // This taken into account, we cannot send a message with each FileUploadStatusItem, instead we send a general error.
                        // If you want to send messages with the FileUploadStatus, do this in an extension like GetFilesRequest, StoreFileRequest
                        // or in the OutgoingResponse extension.
                        context.Request.RequestContext.HttpContext.Response.StatusCode = 400;
                        return(true); // Return value is true, because the extension has changed properties.
                    }
                }
            }
            return(false); // No properties have been changed, so false is returned.
        }
Beispiel #4
0
        public bool Execute(IBackloadContext context, IOutgoingResponseParam param)
        {
            // Note: We use convention based plugin handling (see Example 09).
            // Backload v1.9 and above can handle this internally. Just send plugin=plupload in the querystring or in the config file.
            //
            // In our example we have a PlUpload Plugin client side, so we transform the output to a PlUpload friendly format.
            // Important Note: Since Version 1.9 PlUpload can be handled internally (Plugin attribute in the configuration).
            //
            // Remarks: Don't forget to rebuild your solution if you made changes to your extension, otherwise you may use the old extension assembly.

            if (param.FileStatus == null)
            {
                return(false);                          // in the case something went wrong.
            }
            var result = new PlUploadFiles();

            foreach (var file in param.FileStatus.Files)
            {
                if (context.HttpMethod != "DELETE")
                {
                    result.files.Add(new PlUploadFile(file.Success, file.FileName, file.FileSize, file.ContentType, file.DeleteUrl, file.ThumbnailUrl, file.FileUrl, file.ErrorMessage));
                }
                else
                {
                    result.files.Add(new PlUploadFileCore(file.Success, file.FileName, file.ErrorMessage)); //We only return values we need on client side, so we instatiate a PlFileCore object
                }
            }
            param.Result = Helper.Json(result);
            return(true); // We've processed the response
        }
Beispiel #5
0
        public bool Execute(IBackloadContext context, IIncomingRequestParam param)
        {
            if (context.HttpMethod == "POST")
            {
                // This extension validate if the artist is in the database, and returns a Bad Request status (400) if not.
                
                // IMPORTANT: Don't forget to rebuild the extension when you changed code. Otherwise you may use the old extensions code.
                using (var artists = new ArtistsLibrary())
                {
                    var artist = artists.Artists.FirstOrDefault(a => a.ArtistId == param.BackloadValues.ObjectContext);

                    if (artist == null)  // Artist not in list
                    {   
                        // Stop further processing of the pipeline but all extensions can do their work (maybe logging, etc.).
                        // The outgoing extension will also be called, so you have the chance to change the response to the client.
                        context.PipelineControl.ExecutePipeline = false;
                        // Because we prevented the execution of the core pipeline (where the core method for executing
                        // this request is) we do not generate a FileUploadStatus which holds the status of all files this request 
                        // handles. IIncomingRequest is the first extension point and FileUploadStatus is generated later in the core pipeline.
                        // This taken into account, we cannot send a message with each FileUploadStatusItem, instead we send a general error.
                        // If you want to send messages with the FileUploadStatus, do this in an extension like GetFilesRequest, StoreFileRequest 
                        // or in the OutgoingResponse extension.
                        context.Request.RequestContext.HttpContext.Response.StatusCode = 400; 
                        return true; // Return value is true, because the extension has changed properties.
                    }
                }
            }
            return false; // No properties have been changed, so false is returned.
        }
Beispiel #6
0
        public bool Execute(IBackloadContext context, IOutgoingResponseParam param)
        {
            // Important Note: Since Version 1.9 PlUpload can be handled internally (Plugin attribute in the configuration).

            // Don't forget to rebuid the extension if you made changes to your extension, otherwise you may use the old extension assembly.
            if (context.RequestType == RequestType.Default)
            {
                var result = new PlUploadFiles();
                foreach (var file in param.FileStatus.Files)
                {
                    if (context.HttpMethod != "DELETE")
                    {
                        result.files.Add(new PlUploadFile(file.Success, file.FileName, file.FileSize, file.ContentType, file.DeleteUrl, file.ThumbnailUrl, file.FileUrl, file.ErrorMessage));
                    }
                    else
                    {
                        result.files.Add(new PlUploadFileCore(file.Success, file.FileName, file.ErrorMessage)); //We only return values we need on client side, so we return a PlFileCode object
                    }
                }
                param.Result = Helper.Json(result);

                return(param.FileStatus.Files.Count > 0);  // we have processed the response, so we notify the pipeline
            }
            return(false);
        }
        public bool Execute(IBackloadContext context, IIncomingRequestParam param)
        {
            // Demo 2: Comment out the following line and rebuild the solution
             return false;

            if (context.HttpMethod == "POST")
            {
                int startIdx = context.PipelineControl.Message.MessageCode;
                string subfolder = string.Empty;
                if (startIdx < 8) subfolder = DateTime.Now.ToString(datetime[startIdx]);
                else subfolder = lorem[startIdx - 8];

                if (string.IsNullOrEmpty(param.BackloadValues.UploadContext) == false) param.BackloadValues.UploadContext += ";"; // Seperate subfolders with a semicolon
                param.BackloadValues.UploadContext += subfolder;

                // There are multiple ways sharing data between extensions. Here we use PipelineControl.Message to increase the index.
                // Note, that the ExtensionLogger logs the messages (subfolders) in PipelineControl.Message returned from the extension
                context.PipelineControl.Message.MessageText = subfolder;
                context.PipelineControl.Message.MessageCode += 1;

                return true; // Processed value is true, because the extension has changed properties.
            }

            return false; // No properties have been changed, so false is returned.
        }
        public bool Execute(IBackloadContext context, IProcessPipelineExceptionParam param)
        {
            //
            // Example 1: Graceful exception. We send an error message in our response
            // Extensions responsible for the outgoing response (IOutgoingResponse) are executed as usual.
            // Note: In this case the error is not handled in our client side error handler as we do not
            // send a HTTP status error code (see examples 2 and 3). Instead the response was send to our
            // client side FilesAdded handler, so we need an if statement reading the file.success property there.
            // This could lead to a lot of messy code, because you have to notify the client uploader yourself that something
            // went wrong. PlUpload isn't very good in changing the state from your code. Example 2 provides a cleaner solution.
            //
            // Don't forget to rebuild your extension if you have not set a project dependency in your MVC app
            context.Request.RequestContext.HttpContext.Response.StatusCode = 200; // Backload has set 500 Internal Server Error, we revert this for demo purposes
            if ((param.FileStatus != null) && (param.FileStatus.Files.Count > 0))
            {
                foreach (var file in param.FileStatus.Files)
                {
                    file.ErrorMessage = param.Exception.Message; // for simplicity we set the error to all FileUploadStatusItems
                    file.Success      = false;                   // for simplicity we set the error to all FileUploadStatusItems
                }
            }
            else
            {   // For demo only. We build our own FileStatus. FileStatusSimple has no logic implemented, its only a property bag.
                FileStatusSimple status = new FileStatusSimple();
                for (int i = 0; i < context.Request.Files.Count; i++)
                {
                    var file = context.Request.Files[i];
                    status.Files.Add(new FileStatusSimpleItem(file.FileName, file.ContentType, file.ContentLength, "", param.Exception.Message, false));
                }
                // Now that we have a simple IFileUploadStatus object it can be transformed in our outgoing extension
                // into a PlUpload friendly Json format.
                param.FileStatus = status;
            }



            //
            // Example 2: Set Response code to a valid http status code (e.g. 500 Internal server error.
            // Extensions responsible for the outgoing response (IOutgoingResponse) are executed as usual and can build a custom Json response
            // which will be sent with the HTTP status code. The client error handler can use the Json object.
            // Comment in the following line (Don't forget to rebuild your extension if you have not set a project dependency in your MVC app):
            //
            // request.RequestContext.HttpContext.Response.StatusCode = 500; // Note since v1.9 Backload sets this status code automatically on exceptions



            //
            // Example 3: We throw an exception, so ASP.MVC sends out an http status code.
            // Extensions responsible for the outgoing response (IOutgoingResponse) are not executed anymore.
            // The response body is null in this case, because no JsonResult has been created.
            // Comment in the following line (Don't forget to rebuild your extension if you have not set a project dependency in your MVC app):
            //
            // throw new HttpException(500, param.Exception.Message, Exception);


            return(true);  // Set to true, if the extension has manipulated the result.
        }
        public bool Execute(IBackloadContext context, IProcessPipelineExceptionParam param)
        {
            //
            // Example 1: Graceful exception. We send an error message in our response
            // Extensions responsible for the outgoing response (IOutgoingResponse) are executed as usual.
            // Note: In this case the error is not handled in our client side error handler as we do not 
            // send a HTTP status error code (see examples 2 and 3). Instead the response was send to our 
            // client side FilesAdded handler, so we need an if statement reading the file.success property there.
            // This could lead to a lot of messy code, because you have to notify the client uploader yourself that something 
            // went wrong. PlUpload isn't very good in changing the state from your code. Example 2 provides a cleaner solution.
            //
            // Don't forget to rebuild your extension if you have not set a project dependency in your MVC app
            context.Request.RequestContext.HttpContext.Response.StatusCode = 200; // Backload has set 500 Internal Server Error, we revert this for demo purposes
            if ((param.FileStatus != null) && (param.FileStatus.Files.Count > 0))
            {
                foreach (var file in param.FileStatus.Files)
                {
                    file.ErrorMessage = param.Exception.Message; // for simplicity we set the error to all FileUploadStatusItems
                    file.Success = false; // for simplicity we set the error to all FileUploadStatusItems
                }
            }
            else
            {   // For demo only. We build our own FileStatus. FileStatusSimple has no logic implemented, its only a property bag.
                FileStatusSimple status = new FileStatusSimple();
                for (int i = 0; i < context.Request.Files.Count; i++)
                {
                    var file = context.Request.Files[i];
                    status.Files.Add(new FileStatusSimpleItem(file.FileName, file.ContentType, file.ContentLength, "", param.Exception.Message, false));
                }
                // Now that we have a simple IFileUploadStatus object it can be transformed in our outgoing extension 
                // into a PlUpload friendly Json format. 
                param.FileStatus = status;
            }



            //
            // Example 2: Set Response code to a valid http status code (e.g. 500 Internal server error.
            // Extensions responsible for the outgoing response (IOutgoingResponse) are executed as usual and can build a custom Json response
            // which will be sent with the HTTP status code. The client error handler can use the Json object.
            // Comment in the following line (Don't forget to rebuild your extension if you have not set a project dependency in your MVC app):
            //
            // request.RequestContext.HttpContext.Response.StatusCode = 500; // Note since v1.9 Backload sets this status code automatically on exceptions



            //
            // Example 3: We throw an exception, so ASP.MVC sends out an http status code.
            // Extensions responsible for the outgoing response (IOutgoingResponse) are not executed anymore.
            // The response body is null in this case, because no JsonResult has been created.
            // Comment in the following line (Don't forget to rebuild your extension if you have not set a project dependency in your MVC app):
            //
            // throw new HttpException(500, param.Exception.Message, Exception);


            return true;  // Set to true, if the extension has manipulated the result.
        }
Beispiel #10
0
        public async Task <bool> ExecuteAsync(IBackloadContext context, IGetFilesRequestParam param)
        {
            if (param.FileStatus == null)
            {
                return(false);                          // in the case something went wrong.
            }
            // In this example we want the user to work with a backup file we created on file upload.
            // Note: We do not need to use async/await or Tasks in this simple example. We only simulate a long running task.
            // Important notes: In order to test these demos set breakpoints in all extensions at the beginning of the
            // ProcessStep/ProcessStepAsync method. After changing the code always rebuild this extension or set a project dependency
            // for the extension (context menu or Project menu) in your MVC project as we did, so the extension class is automatically
            // rebuilded. The output build path of the extension is set to the main MVC project in this solution (folder ~/bin/extensions/).
            // If you do not rebuild the extension, the main MVC application may uses the old extension.

            // Demo 1: The following line simulates a long running task. We do not care about (await) the results of this task, so it
            // does not block. The task runs as a background thread within the AppDomains thread pool. You should not use this technique
            // with file IO, because the thread may be aborted when Backload returns. (If you do not want to await the results of a long
            // running File I/O operation take a look in the StoreFile extension were we're using a separate thread).
            var t = Task.Run(() => Task.Delay(System.TimeSpan.FromSeconds(10)));

            // Demo 2: Uncomment the line below, set breakpoints (also in the GetFilesRequest2 extension) and rebuild the extension.
            // You'll notice that debugging stops and awaits the result of the task.
            // The subsequent code and extensions are not executed until the task is finished. But, the ui thread is not blocked and tied up.
            // You can see this, because the web page comes back. Usually, when ececuting and debug synchronous code, the web page
            // doesn't come back in long running tasks.
            // await t;

            // Demo 3: Comment out the await line above, uncomment the following line, set breakpoints and rebuild the extension.
            // The debugging now doesn't stop here and the rest of this extensions code (and the extension handling code in the extension manager)
            // are executed. Before calling the next extension whithin this extension point, the extension manager awaits the result. Note that
            // the second extension below isn't called until the task is finished.
            // context.PipelineControl.TaskManager.ExtensionTasks.Add(t);

            // Demo 4: Comment out the ExtensionTasks.Add line above, uncomment the following line, set breakpoints and rebuild the extension.
            // When debugging the application you'll see, that the second extension also can execute and finish its code, before the
            // extension manager awaits at the end of the extension point (before code execution returns to the pipeline) the result.
            // context.PipelineControl.TaskManager.ExtensionPointTasks.Add(t);

            // Demo 5: Comment out the ExtensionPointTasks.Add line above, uncomment the following line, set breakpoints and rebuild the extension.
            // Make sure you have set a breakpoint in the OutgoingResponse extension were the response for the PlUpload plugin is generated.
            // The difference to the code above is, that the OutgoingResponse was called before the Pipeline waits for the result of the task.
            // PipelineExtendedTasks is ultimately the last point in the processing pipeline before the Pipeline returns the results to the client.
            // context.PipelineControl.TaskManager.PipelineExtendedTasks.Add(t);

            // Note: we do not have mentioned PipelineCoreTasks so far. This point is reached when pipeline core ends. The core methods responsible
            // for doing the GET/POST/PUT/DELETE request have done their job, but before the output was generated and the OutgoingResponse extensions
            // were called. In this demo there would be no difference to Demo 4. If you're using the early extension points (e.g. IncomingRequest)
            // multiple extension points are between this extension point and the end of pipeline core and may better see the difference.
            return(false);
        }
Beispiel #11
0
        public bool Execute(IBackloadContext context, IStoreFileRequestParam param)
        {
            // In this example we make 50 copies of the uploaded file manually.
            //
            // Note: You do not need to make copies manually. Backload supports auto copies of uploaded files.
            // You find the setting for auto copies in the config file (fileSystem: copiesPath).
            // In this demo Backload is configured to make additional copies within the ~/Files/_Backup folder.
            string localBackupPath = Helper.GetLocalFilePath(context.Request, param.FileStatusItem.FileUrl); // Helper method in Backload.Contracts to get the full local file path

            localBackupPath = localBackupPath.Replace("\\Uploads", "\\_Temp");                               // Make sure ~/Files/_Temp folder exists

            // Because we want to post back the new path to the browser, we set the FileUrl property to the new path.
            // File status item halods the data send back to the client. You can change FileStatusItem.FileData which is the
            // bayte array to be stored immediately after the extensions finish.
            param.FileStatusItem.FileUrl = localBackupPath;

            // There are 5 locations within the processing pipeline to wait for the async operation to be finished:
            // 1. Use await:
            //      Example: await fileStream.WriteAsync(...);
            //      Info: Waits for the operation to be finished, but does not block the thread. The operating system can do other things.
            // 2. Use a Task and wait at the end of the extensions handler code (before other extensions are called, if any):
            //      Example: var task = fileStream.WriteAsync(...);
            //               PipelineControl.TaskManager.ExtensionTask.Add(task);
            //      Info: Finishes the execution of this extension and then waits for the task to be finished (Multiple tasks are supported).
            //            Other extensions whithin this extension point are not executed until this task finishes.
            // 3. Use a Task and wait at the end of this extension point (all extensions of this extension point are finished):
            //      Example: var task = fileStream.WriteAsync(...);
            //               PipelineControl.TaskManager.ExtensionPointTasks.Add(task);
            //      Info: Finishes the execution of all extensions within this extension point and then waits for all tasks to be finished.
            // 4. Use a Task and wait at the end the core pipeline:
            //      Example: var task = fileStream.WriteAsync(...);
            //               PipelineControl.TaskManager.PipelineCoreTasks.Add(task);
            //      Info: Waits at the end of pipeline core for the task to be finished. This is a point, when the core GET, POST/PUT, DELETE
            //            method has done its job (e.g. saved a file) but before the final output was generated.
            // 5. Use a Task and wait at the end of the processing pipeline:
            //      Example: var task = fileStream.WriteAsync(...);
            //               PipelineControl.TaskManager.PipelineExtendedTasks.Add(task);
            //      Info: Waits at the ultimative end of the handler for the task to be finished. This is a point immediately before
            //            the return statement of the processing pipeline (Output for the client browser has been generated already).


            // Demo 7: In this demo we do our work in a separate thread and do not care about the result (fire&forget strategy).
            // Because we cannot be sure that the thread finished the work successfully be careful with this approach.
            // If you rely on the results, use async/await or the task based approach or check if the files exist in another
            // extension, a subsequent request, a different code or application (e.g.: if (!File.Exits(...)) File.Copy(...));
            // Comment out the following line:
            new System.Threading.Thread(new System.Threading.ThreadStart(new MuchToDo(param.FileStatusItem.FileData, localBackupPath).WriteFiles)).Start();

            return(true); // We changed a property, so we set this.Processed to true
        }
Beispiel #12
0
        public bool Execute(IBackloadContext context, IOutgoingResponseParam param)
        {
            // IMPORTANT NOTE:
            // Backload v1.9 and above can handle PlUpload internally now. Just send plugin=plupload. You do not need an extension anymore.
            //
            // In our example we have a PlUpload Plugin client side, so we transform the output to a PlUpload friendly format.
            // Important Note: Since Version 1.9 PlUpload can be handled internally (Plugin attribute in the configuration).

            // We have two upload plugins in our form, but this extension is only for PlUpload. We have two options to ensure that our
            // extension only handles PlUpload requests: Convention based handling or conditional handling.
            // In our example we use handling based on convention, where the convention is:
            //    1. In our request we set a "plugin" querystring to plupload (plugin=plupload)
            //    2. The namespace of our extension contains Plugin.PlUpload (not case sensitive)
            // If you do not want to use convention based handling, just do not send a "plugin" querystring or leave it empty (plugin=)
            //
            // You may use conditional handling instead. The extension code is called, and you make the decision based on a condition
            // if to handle the request or not in your code. Typically you parse the request (Querystring or body) for a condition:
            // Example:
            //    string control = context.Request.QueryString["control"];
            //    if ((string.IsNullOrEmpty(control)) || (control != "plupload")) return false;

            //
            // Remarks: Don't forget to rebuild your solution if you made changes to your extension, otherwise you may use the old extension assembly.
            if (param.FileStatus == null)
            {
                return(false);                          // In case something went wrong
            }
            if (context.HttpMethod != "DELETE")
            {
                var result = new PlUploadFiles();

                for (int i = 0; i < param.FileStatus.Files.Count; i++)
                {
                    var file = param.FileStatus.Files[i];
                    result.files.Add(new PlUploadFile(file.Success, file.OriginalName, file.FileSize, file.ContentType, file.DeleteUrl, file.ThumbnailUrl, file.FileUrl, file.ErrorMessage));
                }
                param.Result = Helper.Json(result);
            }
            else
            {
                // Here we use an anonymous type to return some data. PlUpload does not handle server side file deletion, but we made the
                // ajax request and so we can return whatever we want.
                var file   = param.FileStatus.Files[0];
                var result = new { success = file.Success, message = file.ErrorMessage, name = file.FileName };
                param.Result = Helper.Json(result);
            }

            return(param.FileStatus.Files.Count > 0);  // if > 0 we've changed properties.
        }
Beispiel #13
0
        public bool Execute(IBackloadContext context, IStoreFileRequestParam param)
        {
            // In this example we make 50 copies of the uploaded file manually. 
            //
            // Note: You do not need to make copies manually. Backload supports auto copies of uploaded files. 
            // You find the setting for auto copies in the config file (fileSystem: copiesPath).
            // In this demo Backload is configured to make additional copies within the ~/Files/_Backup folder.
            string localBackupPath = Helper.GetLocalFilePath(context.Request, param.FileStatusItem.FileUrl); // Helper method in Backload.Contracts to get the full local file path
            localBackupPath = localBackupPath.Replace("\\Uploads", "\\_Temp"); // Make sure ~/Files/_Temp folder exists

            // Because we want to post back the new path to the browser, we set the FileUrl property to the new path.
            // File status item halods the data send back to the client. You can change FileStatusItem.FileData which is the 
            // bayte array to be stored immediately after the extensions finish.
            param.FileStatusItem.FileUrl = localBackupPath; 
            
            // There are 5 locations within the processing pipeline to wait for the async operation to be finished:
            // 1. Use await:
            //      Example: await fileStream.WriteAsync(...);
            //      Info: Waits for the operation to be finished, but does not block the thread. The operating system can do other things.
            // 2. Use a Task and wait at the end of the extensions handler code (before other extensions are called, if any):
            //      Example: var task = fileStream.WriteAsync(...);
            //               PipelineControl.TaskManager.ExtensionTask.Add(task);
            //      Info: Finishes the execution of this extension and then waits for the task to be finished (Multiple tasks are supported).
            //            Other extensions whithin this extension point are not executed until this task finishes.
            // 3. Use a Task and wait at the end of this extension point (all extensions of this extension point are finished):
            //      Example: var task = fileStream.WriteAsync(...);
            //               PipelineControl.TaskManager.ExtensionPointTasks.Add(task);
            //      Info: Finishes the execution of all extensions within this extension point and then waits for all tasks to be finished.
            // 4. Use a Task and wait at the end the core pipeline:
            //      Example: var task = fileStream.WriteAsync(...);
            //               PipelineControl.TaskManager.PipelineCoreTasks.Add(task);
            //      Info: Waits at the end of pipeline core for the task to be finished. This is a point, when the core GET, POST/PUT, DELETE 
            //            method has done its job (e.g. saved a file) but before the final output was generated.    
            // 5. Use a Task and wait at the end of the processing pipeline:
            //      Example: var task = fileStream.WriteAsync(...);
            //               PipelineControl.TaskManager.PipelineExtendedTasks.Add(task);
            //      Info: Waits at the ultimative end of the handler for the task to be finished. This is a point immediately before 
            //            the return statement of the processing pipeline (Output for the client browser has been generated already).


            // Demo 7: In this demo we do our work in a separate thread and do not care about the result (fire&forget strategy). 
            // Because we cannot be sure that the thread finished the work successfully be careful with this approach.
            // If you rely on the results, use async/await or the task based approach or check if the files exist in another 
            // extension, a subsequent request, a different code or application (e.g.: if (!File.Exits(...)) File.Copy(...));
            // Comment out the following line:
            new System.Threading.Thread(new System.Threading.ThreadStart(new MuchToDo(param.FileStatusItem.FileData, localBackupPath).WriteFiles)).Start();

            return true; // We changed a property, so we set this.Processed to true
        }
Beispiel #14
0
        public bool Execute(IBackloadContext context, IOutgoingResponseParam param)
        {
            // IMPORTANT NOTE:
            // Backload v1.9 and above can handle PlUpload internally now. Just send plugin=plupload. You do not need an extension anymore.
            //
            // In our example we have a PlUpload Plugin client side, so we transform the output to a PlUpload friendly format.
            // Important Note: Since Version 1.9 PlUpload can be handled internally (Plugin attribute in the configuration).

            // We have two upload plugins in our form, but this extension is only for PlUpload. We have two options to ensure that our
            // extension only handles PlUpload requests: Convention based handling or conditional handling.
            // In our example we use handling based on convention, where the convention is: 
            //    1. In our request we set a "plugin" querystring to plupload (plugin=plupload)
            //    2. The namespace of our extension contains Plugin.PlUpload (not case sensitive)
            // If you do not want to use convention based handling, just do not send a "plugin" querystring or leave it empty (plugin=)
            //
            // You may use conditional handling instead. The extension code is called, and you make the decision based on a condition 
            // if to handle the request or not in your code. Typically you parse the request (Querystring or body) for a condition:
            // Example:
            //    string control = context.Request.QueryString["control"];
            //    if ((string.IsNullOrEmpty(control)) || (control != "plupload")) return false;

            //
            // Remarks: Don't forget to rebuild your solution if you made changes to your extension, otherwise you may use the old extension assembly.
            if (param.FileStatus == null) return false; // In case something went wrong

            if (context.HttpMethod != "DELETE")
            {
                var result = new PlUploadFiles();

                for (int i = 0; i < param.FileStatus.Files.Count; i++)
                {
                    var file = param.FileStatus.Files[i];
                    result.files.Add(new PlUploadFile(file.Success, file.OriginalName, file.FileSize, file.ContentType, file.DeleteUrl, file.ThumbnailUrl, file.FileUrl, file.ErrorMessage));
                    
                }
                param.Result = Helper.Json(result);
            }
            else
            {
                // Here we use an anonymous type to return some data. PlUpload does not handle server side file deletion, but we made the 
                // ajax request and so we can return whatever we want.
                var file = param.FileStatus.Files[0];
                var result = new { success = file.Success, message = file.ErrorMessage, name = file.FileName };
                param.Result = Helper.Json(result);
            }
            
            return (param.FileStatus.Files.Count > 0); // if > 0 we've changed properties.
        }
Beispiel #15
0
        public async Task<bool> ExecuteAsync(IBackloadContext context, IGetFilesRequestParam param)
        {
            if (param.FileStatus == null) return false; // in the case something went wrong.

            // In this example we want the user to work with a backup file we created on file upload.
            // Note: We do not need to use async/await or Tasks in this simple example. We only simulate a long running task.
            // Important notes: In order to test these demos set breakpoints in all extensions at the beginning of the 
            // ProcessStep/ProcessStepAsync method. After changing the code always rebuild this extension or set a project dependency 
            // for the extension (context menu or Project menu) in your MVC project as we did, so the extension class is automatically 
            // rebuilded. The output build path of the extension is set to the main MVC project in this solution (folder ~/bin/extensions/). 
            // If you do not rebuild the extension, the main MVC application may uses the old extension.

            // Demo 1: The following line simulates a long running task. We do not care about (await) the results of this task, so it 
            // does not block. The task runs as a background thread within the AppDomains thread pool. You should not use this technique 
            // with file IO, because the thread may be aborted when Backload returns. (If you do not want to await the results of a long 
            // running File I/O operation take a look in the StoreFile extension were we're using a separate thread).
            var t = Task.Run(() => Task.Delay(System.TimeSpan.FromSeconds(10)));
            
            // Demo 2: Uncomment the line below, set breakpoints (also in the GetFilesRequest2 extension) and rebuild the extension. 
            // You'll notice that debugging stops and awaits the result of the task.
            // The subsequent code and extensions are not executed until the task is finished. But, the ui thread is not blocked and tied up.
            // You can see this, because the web page comes back. Usually, when ececuting and debug synchronous code, the web page 
            // doesn't come back in long running tasks.
            // await t;

            // Demo 3: Comment out the await line above, uncomment the following line, set breakpoints and rebuild the extension. 
            // The debugging now doesn't stop here and the rest of this extensions code (and the extension handling code in the extension manager) 
            // are executed. Before calling the next extension whithin this extension point, the extension manager awaits the result. Note that 
            // the second extension below isn't called until the task is finished.
            // context.PipelineControl.TaskManager.ExtensionTasks.Add(t);

            // Demo 4: Comment out the ExtensionTasks.Add line above, uncomment the following line, set breakpoints and rebuild the extension. 
            // When debugging the application you'll see, that the second extension also can execute and finish its code, before the 
            // extension manager awaits at the end of the extension point (before code execution returns to the pipeline) the result.
            // context.PipelineControl.TaskManager.ExtensionPointTasks.Add(t);

            // Demo 5: Comment out the ExtensionPointTasks.Add line above, uncomment the following line, set breakpoints and rebuild the extension. 
            // Make sure you have set a breakpoint in the OutgoingResponse extension were the response for the PlUpload plugin is generated. 
            // The difference to the code above is, that the OutgoingResponse was called before the Pipeline waits for the result of the task. 
            // PipelineExtendedTasks is ultimately the last point in the processing pipeline before the Pipeline returns the results to the client.
            // context.PipelineControl.TaskManager.PipelineExtendedTasks.Add(t);

            // Note: we do not have mentioned PipelineCoreTasks so far. This point is reached when pipeline core ends. The core methods responsible
            // for doing the GET/POST/PUT/DELETE request have done their job, but before the output was generated and the OutgoingResponse extensions 
            // were called. In this demo there would be no difference to Demo 4. If you're using the early extension points (e.g. IncomingRequest) 
            // multiple extension points are between this extension point and the end of pipeline core and may better see the difference.
            return false;
        }
Beispiel #16
0
 // This extension is only for demo purposes, as we throw an exception here
 // Don't forget to rebuid your solution if you made changes to your extension, otherwise you may use the old extension assembly.
 public bool Execute(IBackloadContext context, IIncomingRequestParam param)
 {
     if (context.HttpMethod == "POST")
     {
         for (int i = 0; i < context.Request.Files.Count; i++)
         {
             var file = context.Request.Files[i];
             if (file.FileName.ToLower().Contains("badfile"))
             {
                 context.PipelineControl.Message.MessageText = "Bad file name.";
                 throw new Exception(context.PipelineControl.Message.MessageText);
             }
         }
     }
     return false; // No properties have been changed, so we set return false.
 }
Beispiel #17
0
 // This extension is only for demo purposes, as we throw an exception here
 // Don't forget to rebuid your solution if you made changes to your extension, otherwise you may use the old extension assembly.
 public bool Execute(IBackloadContext context, IIncomingRequestParam param)
 {
     if (context.HttpMethod == "POST")
     {
         for (int i = 0; i < context.Request.Files.Count; i++)
         {
             var file = context.Request.Files[i];
             if (file.FileName.ToLower().Contains("badfile"))
             {
                 context.PipelineControl.Message.MessageText = "Bad file name.";
                 throw new Exception(context.PipelineControl.Message.MessageText);
             }
         }
     }
     return(false); // No properties have been changed, so we set return false.
 }
Beispiel #18
0
        public async Task<bool> ExecuteAsync(IBackloadContext context, IGetFilesRequestParam param)
        {
            if (param.FileStatus == null) return false; // if cace something went wrongt.

            // We use this extension only to demonstrate you different examples of blocked and parallel requests.

            // IMPORTANT NOTE: The FileStatusSimple here is only to show, that you can create your FileStatus from scratch.
            // You may use FileStatusSimple as we did here or implement your own iFileUploadStatus class if you need it.
            // In this example it'll be sufficient to simply set the file.FileUrl of the FileStatus property, no need to use FileStatusSimple.
            FileStatusSimple status = new FileStatusSimple();
            foreach (var file in param.FileStatus.Files)
            {
                file.FileUrl = file.FileUrl.Replace("/Uploads", "/_Backup");
                status.Files.Add(file);
            }
            param.FileStatus = status;

            return (param.FileStatus.Files.Count > 0); // if FileStatus.files.Count > 0 we've processed the response, so we need notify the pipeline
        }
Beispiel #19
0
        public bool Execute(IBackloadContext context, IOutgoingResponseParam param)
        {
            // Important Note: Since Version 1.9 PlUpload can be handled internally (Plugin attribute in the configuration).

            // Don't forget to rebuid the extension if you made changes to your extension, otherwise you may use the old extension assembly.
            if (context.RequestType == RequestType.Default)
            {
                var result = new PlUploadFiles();
                foreach (var file in param.FileStatus.Files)
                {
                    if (context.HttpMethod != "DELETE")
                        result.files.Add(new PlUploadFile(file.Success, file.FileName, file.FileSize, file.ContentType, file.DeleteUrl, file.ThumbnailUrl, file.FileUrl, file.ErrorMessage));
                    else
                        result.files.Add(new PlUploadFileCore(file.Success, file.FileName, file.ErrorMessage)); //We only return values we need on client side, so we return a PlFileCode object
                }
                param.Result = Helper.Json(result);

                return (param.FileStatus.Files.Count > 0); // we have processed the response, so we notify the pipeline
            }
            return false;
        }
Beispiel #20
0
        public async Task <bool> ExecuteAsync(IBackloadContext context, IGetFilesRequestParam param)
        {
            if (param.FileStatus == null)
            {
                return(false);                          // if cace something went wrongt.
            }
            // We use this extension only to demonstrate you different examples of blocked and parallel requests.

            // IMPORTANT NOTE: The FileStatusSimple here is only to show, that you can create your FileStatus from scratch.
            // You may use FileStatusSimple as we did here or implement your own iFileUploadStatus class if you need it.
            // In this example it'll be sufficient to simply set the file.FileUrl of the FileStatus property, no need to use FileStatusSimple.
            FileStatusSimple status = new FileStatusSimple();

            foreach (var file in param.FileStatus.Files)
            {
                file.FileUrl = file.FileUrl.Replace("/Uploads", "/_Backup");
                status.Files.Add(file);
            }
            param.FileStatus = status;

            return(param.FileStatus.Files.Count > 0);  // if FileStatus.files.Count > 0 we've processed the response, so we need notify the pipeline
        }
Beispiel #21
0
        public bool Execute(IBackloadContext context, IOutgoingResponseParam param)
        {
            // Note: We use convention based plugin handling (see Example 09). 
			// Backload v1.9 and above can handle this internally. Just send plugin=plupload in the querystring or in the config file.
            //
            // In our example we have a PlUpload Plugin client side, so we transform the output to a PlUpload friendly format.
            // Important Note: Since Version 1.9 PlUpload can be handled internally (Plugin attribute in the configuration).
            //
            // Remarks: Don't forget to rebuild your solution if you made changes to your extension, otherwise you may use the old extension assembly.

            if (param.FileStatus == null) return false; // in the case something went wrong.
            var result = new PlUploadFiles();
            foreach (var file in param.FileStatus.Files)
            {
                if (context.HttpMethod != "DELETE")
                    result.files.Add(new PlUploadFile(file.Success, file.FileName, file.FileSize, file.ContentType, file.DeleteUrl, file.ThumbnailUrl, file.FileUrl, file.ErrorMessage));
                else
                    result.files.Add(new PlUploadFileCore(file.Success, file.FileName, file.ErrorMessage)); //We only return values we need on client side, so we instatiate a PlFileCore object
            }
            param.Result = Helper.Json(result);
            return true; // We've processed the response
        }
Beispiel #22
0
        public bool Execute(IBackloadContext context, IDeleteFilesRequestParam param)
        {
            // In this extension we delete the copies we've created within the _Backup and _Temp folder.
            // Backload has made the copies within the _Backup folder automatically, because it is configured to do so (config file)
            // The copies within the _Temp folder were created for demo purposes in the StoreFileRequest extension.
            string dirBackup = string.Empty;
            string dirTemp   = string.Empty;

            if (param.DeleteFiles == null)
            {
                return(false);                           // in the case something went wrong.
            }
            if (param.DeleteFiles.Files.Count > 0)
            {
                dirTemp   = Path.GetDirectoryName(Helper.GetLocalFilePath(context.Request, param.DeleteFiles.First().FileUrl).Replace("\\Uploads", "\\_Temp"));   // Helper method in Backload.Contracts to get the full local file path
                dirBackup = Path.GetDirectoryName(Helper.GetLocalFilePath(context.Request, param.DeleteFiles.First().FileUrl).Replace("\\Uploads", "\\_Backup")); // Helper method in Backload.Contracts to get the full local file path
            }

            foreach (var file in param.DeleteFiles.Files)
            {
                // Synchronous deletion:
                // Delete the backup file Backload created (see config file)
                string pathBackupFile = Path.Combine(dirBackup, file.FileName);
                if (File.Exists(pathBackupFile))
                {
                    File.Delete(pathBackupFile);
                }

                // Asynchronous deletion with Tasks:
                // Demo 6: Running and awaiting a method asynchronously in a thread of the AppDomains thread pool.
                // Note: We do not use await here, because we have implemented the synchronous interface.
                // The Tasks will be awaited at the end of the extension point for the FilesDelete extension. If we do not await the
                // result, the task may be aborted and does not finish file deletion.
                var t = Task.Run(() => DeleteTempFiles(dirTemp, file.FileName));
                context.PipelineControl.TaskManager.ExtensionPointTasks.Add(t);
            }
            return(param.DeleteFiles.Files.Count > 0);
        }