我有一个客户端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;
}
答案 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)
假设:
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>
注意:FormData
是XMLHttpRequest Level 2
的一部分。检查xhr2 cross browser support here 。
如果您正在寻找IE,它会从IE10+
获得支持
要支持IE9-
,我们应该考虑后退方法(使用iframe
上传)。
后备解决方案(AJAX(XHR2)FormData功能和iframe)
您可以使用现有的开源jQuery插件jquery.form.js
还要在服务器端观察以下线程: