在向Web API提交表单时如何获取响应状态

时间:2014-10-14 07:24:57

标签: c# jquery asp.net asp.net-web-api

我有一个客户端HTML应用程序和一个Asp.net WebAPI作为服务器应用程序。 我有一个场景,我必须提交表单,作为表单提交的一部分,我需要将表单数据发布到数据库。这对我有用,但客户端应用程序如何知道在不同域中发生的数据库操作的成功或失败状态。我试图将HttpResponseMessage对象返回给客户端,但我的整个HTML页面都重写了我从服务器返回的状态。 有没有什么方法可以单独检查特定状态,而不是使用从服务器API应用程序获取的响应重写整个HTML,以便我在客户端应用程序中有更多的控制权?

提交表格的客户代码:

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

        myForm.attr('action', path);
        myForm.submit();

    }

我访问POST调用的Web Api代码:

[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;
    }

2 个答案:

答案 0 :(得分:1)

  

以下是完整上传测试用例:

<强>布局
为简洁起见,我只需要一部分Markup

<!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>

<强> UploadFilePage.css

    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%;
    }

UploadFile查看标记

@{
    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>
}

API控制器
为了避免混淆,我在api-controller-action中应用了类似的逻辑

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;
        }

    }
}

答案 1 :(得分:0)

根据您的情况,您可以使用jQuery管理AJAX

  

使用AJAX(XHR2)FormData功能的解决方案Check browser support here

假设:

  1. btnUpload :上传按钮的ID
  2. fileInputField :文件输入元素的ID
  3. 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>
    

    注意:FormDataXMLHttpRequest Level 2的一部分。检查xhr2 cross browser support here
    如果您正在寻找IE,它会从IE10+获得支持 要支持IE9-,我们应该考虑后退方法(使用iframe上传)。

      

    后备解决方案(AJAX(XHR2)FormData功能和iframe)
          您可以使用现有的开源jQuery插件jquery.form.js

    还要在服务器端观察以下线程: