57977

How to get a Response status while we submit a form to Web API

Question:

I am having a client HTML application and an Asp.net WebAPI as the server application. I am having a scenario that I have to make a form submission and as part of Form Submit I need to post the form data to database. This is working for me, but how can the client app knows about the success or Failure status of the DB operation which is happening in a different domain. I have tried to return HttpResponseMessage object to the client but my entire HTML page got rewrite with the status which I am returning from the server. Is there any ways there for this to check a particular status alone rather than rewriting the entire HTML with the response getting from the server API application so that I will have lot more control in the client app?

Client Code for Submitting the Form:

function ValidateFileAndSubmit() { var myForm = $("#form1"); //UploadFiles(); var rootServicePath = config.rootURL; var path = rootServicePath + 'api/Upload/UploadFile'; myForm.attr('action', path); myForm.submit(); }

Web Api code where I am access the POST call:

[HttpPost] public HttpResponseMessage UploadFile() { HttpResponseMessage response = null; if (HttpContext.Current.Request.Files.AllKeys.Any()) { HttpContext.Current.Response.ContentType = "text/HTML"; var httpPostedFile = HttpContext.Current.Request.Files["UploadedImage"]; if (httpPostedFile != null) { // Validate the uploaded image(optional) // Get the complete file path var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/UploadedFiles"), httpPostedFile.FileName); // Save the uploaded file to "UploadedFiles" folder httpPostedFile.SaveAs(fileSavePath); response = new HttpResponseMessage(HttpStatusCode.Created) { Content = new StringContent("Uploaded Successfully") }; } } return response; }

Answer1:

<blockquote>

Here is the full upload test case:

</blockquote>

<strong>Layout</strong><br /><em>For brevity I'm putting only required piece of Markup</em>

<!DOCTYPE html> <html> <head> <!-- Here you'll have all head child tags(meta, title, CSS related links ref tags and some other like modernizer scripts and other tags that required for app)--> </head> <body> <!--navbar with Page heading title--> <div class="container body-content"> @RenderBody() <!--footer--> </div> <script src="~/Scripts/jquery-1.10.2.min.js"></script> <!--embed other global scripts here--> @RenderSection("scripts", false) </body> </html>

<strong>UploadFilePage.css</strong>

body { padding: 30px; } form { display: block; margin: 20px auto; background: #eee; border-radius: 10px; padding: 15px; } .progress { position: relative; width: 400px; border: 1px solid #ddd; padding: 1px; border-radius: 3px; } .bar { background-color: #B4F5B4; width: 0%; height: 20px; border-radius: 3px; } .percent { position: absolute; display: inline-block; top: 3px; left: 48%; }

<strong>UploadFile View Markup</strong>

@{ ViewBag.Title = "Upload Demo"; } <link href="~/Content/UploadFilePage.css" rel="stylesheet" type="text/css" /> <h2>Upload DEMO</h2> <form action="/api/upload/UploadFile" method="post" enctype="multipart/form-data"> <input type="file" name="UploadedFile" /><br /> <input type="submit" value="Upload File to Server" /> </form> <div class="progress"> <div class="bar"></div> <div class="percent">0%</div> </div> <div id="status"></div> @section scripts { <script src="http://malsup.github.com/jquery.form.js"></script> <script> (function () { var bar = $('.bar'), percent = $('.percent'), status = $('#status'); $('form').ajaxForm({ beforeSend: function () { status.empty(); var percentVal = '0%'; bar.width(percentVal) percent.html(percentVal); }, uploadProgress: function (event, position, total, percentComplete) { var percentVal = percentComplete + '%'; bar.width(percentVal) percent.html(percentVal); }, success: function (response) { var percentVal = '100%'; bar.width(percentVal) percent.html(percentVal); alert(response);//its just for unit testing, pleae remove after your testing. This alert is not required as we are showing status on the page. }, error: function (xhr) { status.html(xhr.responseText || 'Error - File upload failed.'); }, complete: function (xhr) { status.html(xhr.responseText); } }); })(); </script> }

<strong>API Controller</strong><br /><em>To avoid confustion, I applied similar logic you have in the api-controller-action</em>

using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Web; using System.Web.Http; namespace TestCases.MVC.Controllers { public class UploadController : ApiController { [HttpPost] public HttpResponseMessage UploadFile() { HttpResponseMessage response = null; if (HttpContext.Current.Request.Files.AllKeys.Any()) { HttpContext.Current.Response.ContentType = "text/HTML"; var httpPostedFile = HttpContext.Current.Request.Files["UploadedFile"]; if (httpPostedFile != null) { // Validate the uploaded image(optional) // Get the complete file path var uploadFilesDir = HttpContext.Current.Server.MapPath("~/UploadedFiles"); if (!Directory.Exists(uploadFilesDir)) { Directory.CreateDirectory(uploadFilesDir); } var fileSavePath = Path.Combine(uploadFilesDir, httpPostedFile.FileName); // Save the uploaded file to "UploadedFiles" folder httpPostedFile.SaveAs(fileSavePath); response = new HttpResponseMessage(HttpStatusCode.Created) { Content = new StringContent("Uploaded Successfully") }; } } return response; } } }

Answer2:

<strong>FOR YOUR CASE YOU CAN MANAGE WITH AJAX using jQuery</strong>

<blockquote>

<strong>Solution with AJAX(XHR2) FormData feature</strong> (<a href="http://caniuse.com/#feat=xhr2" rel="nofollow"><em>Check browser support here</em></a>)

</blockquote>

Assumptions:

<ol><li><em>btnUpload</em> : id of upload button </li> <li><em>fileInputField</em> : id of your file input element</li> </ol>

JavaScript:

<script type="text/javascript"> $(function() { $('#btnUpload').click(function() { if (window.FormData !== undefined) { var formData = new FormData(), yourFileObj = $('#fileInputField').get(0), rootServicePath = config.rootURL, urlPath = rootServicePath + 'api/Upload/UploadFile'; formData.append("UploadedImage", yourFileObj.files[0]); $.ajax({ url: urlPath, type: 'POST', data: formData, cache: false, success: function(response) { //do something with response } }); } else { alert("your browser sucks!"); } }); }); </script>

Note: FormData is part of XMLHttpRequest Level 2. Check <a href="http://caniuse.com/#feat=xhr2" rel="nofollow">xhr2 cross browser support here </a>.<br /> If you looking for IE, it support from IE10+.<br /> To support IE9- we should think about fall back approach(upload with iframe).

<blockquote>

<strong>Solution with fallback (AJAX(XHR2) FormData feature and iframe)</strong><br /> You can use existing open source jQuery plug-in <a href="http://malsup.com/jquery/form/#file-upload" rel="nofollow">jquery.form.js</a>

</blockquote>

Also observe below threads to get idea on server-side:

<ul><li><a href="http://www.asp.net/web-api/overview/advanced/sending-html-form-data,-part-2" rel="nofollow">ASP.Net Article</a>. to get idea on code-behind(server side)</li> <li><a href="https://stackoverflow.com/questions/10320232/how-to-accept-a-file-post-asp-net-mvc-4-webapi/" rel="nofollow">How To Accept a File POST</a></li> <li><a href="https://stackoverflow.com/questions/13577799/asp-net-webapi-file-upload-issues-with-ie9" rel="nofollow">ASP.NET WEBAPI file upload, issues with IE9</a></li> </ul>

Recommend

  • Check string content of response before retrying with Polly
  • httpmessagehandler - reading content
  • How to upload a file - NO image - and comment it at the same time to Slack via SlackAPI using c#
  • .Net Web Api - Override AuthorizationFilter
  • How to send a custom object from OnException method?
  • Cannot get the uploaded file name while using ajax
  • VBA Excel Save Copy as txt File
  • save as dialog excel code
  • Uploading to S3 on Heroku with Paperclip (delayed_job question)
  • JAR file: Could not find main class
  • Yii: any way to save the images in compressed form?
  • ImportError: cannot import name COMError in python
  • Valums Ajax file Upload handle the up. file?
  • Save website uploads in a subdomain
  • How to implement Deep Linking in Roku SG application?
  • Android changing fragment order inside FragmentPagerAdapter
  • how does System.Web.HttpRequest::PathInfo work?
  • Low TTL with Leveled Compaction, should I reduce gc_grace_seconds to improve read performance withou
  • Invalid object name 'dbo.Item'
  • cygwin cannot exec 'git-add--interactive' permission denied
  • Jenkins: FATAL: Could not initialize class hudson.util.ProcessTree$UnixReflection
  • TextToSpeech.setEngineByPackageName() triggers NullPointerException
  • Not able to aggregate on nested fields in elasticsearch
  • Abort upload large uploads after reading headers
  • print() is showing quotation marks in results
  • Make VS2015 use angular-cli ng at build time in a .NET project
  • Android fill_parent issue
  • Change Inet root folder for iis 7
  • Paperclip, set path outside of rails root folder
  • Align navbar back button on right side
  • DotNetZip - Calculate final zip size before calling Save(stream)
  • Apache 2.4 and php-fpm does not trigger apache http basic auth for php pages
  • Get object from AWS S3 as a stream
  • Incrementing object id automatically JS constructor (static method and variable)
  • Warning: Can't call setState (or forceUpdate) on an unmounted component
  • Proper folder structure for lots of source files
  • Load html files in TinyMce
  • Free memory of cv::Mat loaded using FileStorage API
  • unknown Exception android
  • Append folder name and increment by 1 using batch script