如何在 ASP.NET MVC 中不刷新页面或重定向进行文件上传
How to do File Upload Without Page Refresh or redirect in ASP.NET MVC
我正在通过链接到控制器的视图上传文件,但是在上传上传后,应用程序正在尝试刷新或重定向,我需要阻止这种情况。能否请您指出正确的方向以避免重定向和刷新?我读了一些书,我怀疑这一行 action="/api/BulkUpload">
可能是导致问题的原因。
我的控制器
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using Repositories.BulkUpload;
using Repositories.Interfaces.BulkUpload;
namespace SimSentinel.Controllers
{
//[Authorize]
public class BulkUploadController : ApiController
{
private readonly IBulkUploadRepository _bulkUploadRepository;
public async Task<HttpResponseMessage> PostFile()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/Files");
var provider = new FormDataStreamer(root);
try
{
StringBuilder sb = new StringBuilder(); // Holds the response body
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
sb.Append(string.Format("{0}: {1}\n", key, val));
}
}
// This illustrates how to get the file names for uploaded files.
foreach (var file in provider.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
sb.Append(string.Format("Uploaded file: {0} ({1} bytes)\n", fileInfo.Name, fileInfo.Length));
}
return new HttpResponseMessage()
{
Content = new StringContent(sb.ToString())
};
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
public class FormDataStreamer : MultipartFormDataStreamProvider
{
public FormDataStreamer(string rootPath) : base(rootPath) { }
public FormDataStreamer(string rootPath, int bufferSize) : base(rootPath, bufferSize) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
var srcFileName = headers.ContentDisposition.FileName.Replace("\"", "");
return Guid.NewGuid() + Path.GetExtension(srcFileName);
}
}
}
}
我的HTML
<form name="form1" method="post" enctype="multipart/form-data" action="/api/BulkUpload">
<div>
<label for="caption">Image Caption</label>
<input name="caption" type="text" />
</div>
<div>
<label for="image1">Image File</label>
<input name="image1" type="file" />
</div>
<div>
<input type="submit" value="ok" />
</div>
</form>
你是对的。当您提交表单时,文件将通过 HTTP POST 请求发送到控制器,并且页面必然会刷新或重定向。如果您不希望页面刷新或重定向,则必须使用 AJAX 将文件 post 发送到控制器。
来自 Mozilla Developer document on HTTP requests,
The GET method requests a representation of the specified resource.
Requests using GET should only retrieve data.
The POST method is used to submit an entity to the specified
resource, often causing a change in state or side effects on the
server.
来自 Web Programming from Nanyang Technological University、
上的这些注释
[The] POST request method is used to "post" additional data up to the server
(e.g., submitting HTML form data or uploading a file). Issuing an HTTP
URL from the browser always triggers a GET request. To trigger a POST
request, you can use an HTML form with attribute method="post" or
write your own network program. For submitting HTML form data, POST
request is the same as the GET request except that the URL-encoded
query string is sent in the request body, rather than appended behind
the request-URI.
因此,您可以看到,由于您使用标准 HTTP 请求 post 将文件发送到服务器,因此 必然 刷新或重定向在某种程度上。
为避免这种情况,您可以使用jQuery 将文件异步post 到服务器而不刷新页面。有很多文章介绍如何执行此操作。我建议你试一试,如果遇到困难,post 再问一个问题。
非常感谢您的帮助,它引导我朝着正确的方向前进。我最终从这个 [How to submit html form without redirection? 得到了答案。 Iframe 方法是最简单的方法,它是一种临时修复方法,因为一些文章说虽然大多数现代浏览器仍然支持它,但它已被弃用。
我正在通过链接到控制器的视图上传文件,但是在上传上传后,应用程序正在尝试刷新或重定向,我需要阻止这种情况。能否请您指出正确的方向以避免重定向和刷新?我读了一些书,我怀疑这一行 action="/api/BulkUpload">
可能是导致问题的原因。
我的控制器
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using Repositories.BulkUpload;
using Repositories.Interfaces.BulkUpload;
namespace SimSentinel.Controllers
{
//[Authorize]
public class BulkUploadController : ApiController
{
private readonly IBulkUploadRepository _bulkUploadRepository;
public async Task<HttpResponseMessage> PostFile()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/Files");
var provider = new FormDataStreamer(root);
try
{
StringBuilder sb = new StringBuilder(); // Holds the response body
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
sb.Append(string.Format("{0}: {1}\n", key, val));
}
}
// This illustrates how to get the file names for uploaded files.
foreach (var file in provider.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
sb.Append(string.Format("Uploaded file: {0} ({1} bytes)\n", fileInfo.Name, fileInfo.Length));
}
return new HttpResponseMessage()
{
Content = new StringContent(sb.ToString())
};
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
public class FormDataStreamer : MultipartFormDataStreamProvider
{
public FormDataStreamer(string rootPath) : base(rootPath) { }
public FormDataStreamer(string rootPath, int bufferSize) : base(rootPath, bufferSize) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
var srcFileName = headers.ContentDisposition.FileName.Replace("\"", "");
return Guid.NewGuid() + Path.GetExtension(srcFileName);
}
}
}
}
我的HTML
<form name="form1" method="post" enctype="multipart/form-data" action="/api/BulkUpload">
<div>
<label for="caption">Image Caption</label>
<input name="caption" type="text" />
</div>
<div>
<label for="image1">Image File</label>
<input name="image1" type="file" />
</div>
<div>
<input type="submit" value="ok" />
</div>
</form>
你是对的。当您提交表单时,文件将通过 HTTP POST 请求发送到控制器,并且页面必然会刷新或重定向。如果您不希望页面刷新或重定向,则必须使用 AJAX 将文件 post 发送到控制器。
来自 Mozilla Developer document on HTTP requests,
The GET method requests a representation of the specified resource. Requests using GET should only retrieve data.
The POST method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server.
来自 Web Programming from Nanyang Technological University、
上的这些注释[The] POST request method is used to "post" additional data up to the server (e.g., submitting HTML form data or uploading a file). Issuing an HTTP URL from the browser always triggers a GET request. To trigger a POST request, you can use an HTML form with attribute method="post" or write your own network program. For submitting HTML form data, POST request is the same as the GET request except that the URL-encoded query string is sent in the request body, rather than appended behind the request-URI.
因此,您可以看到,由于您使用标准 HTTP 请求 post 将文件发送到服务器,因此 必然 刷新或重定向在某种程度上。
为避免这种情况,您可以使用jQuery 将文件异步post 到服务器而不刷新页面。有很多文章介绍如何执行此操作。我建议你试一试,如果遇到困难,post 再问一个问题。
非常感谢您的帮助,它引导我朝着正确的方向前进。我最终从这个 [How to submit html form without redirection? 得到了答案。 Iframe 方法是最简单的方法,它是一种临时修复方法,因为一些文章说虽然大多数现代浏览器仍然支持它,但它已被弃用。