Отправить форму, используя AJAX в ASP.Net Core MVC
Я работаю с ASP.Net Core 2.1 и пытаюсь загрузить файл, возвращая его URL-адрес, не обновляя страницу.
Я пытаюсь написать JavaScript в site.js, так как _RenderPartial("scripts") отображает все сценарии в конце страницы и, следовательно, непосредственное использование тега script в представлении бритвы не работает. Во-вторых, добавление его в site.js дает мне возможность вызывать скрипт для всех видов сайта.
Мое действие контроллера выглядит так:
[HttpPost]
[DisableRequestSizeLimit]
public async Task<IActionResult> Upload()
{
// Read & copy to stream the content of MultiPart-Form
// Return the URL of the uploaded file
return Content(FileName);
}
Мой взгляд выглядит так:
<form id="FileUploadForm" action="~/Resources/Upload" method="post" enctype="multipart/form-data">
<input name="uploadfile" type="file" />
<button name="uploadbtn" type="submit" onclick="SubmitForm(this.parentElement, event)">Upload</button>
В настоящее время site.js выглядит так:
function SubmitForm(form, caller) {
caller.preventDefault();
$.ajax(
{
type: form.method,
url: form.action,
data: form.serialize(),
success: function (data) { alert(data); },
error: function (data) { alert(data); }
})}
В настоящее время код обходит весь сценарий, и файл загружается, и возвращается новое представление, отображающее имя файла. Мне нужна помощь для создания JavaScript.
3 ответа
К сожалению, JQuery serialize()
Метод не будет включать элементы входного файла. Таким образом, выбранный пользователем файл не будет включен в сериализованное значение (которое в основном является строкой).
Что вы можете сделать, это создать FormData
объект, добавьте файл (ы) к этому. При выполнении вызова AJAX необходимо указать processData
а также contentType
значения свойств для false
<form id="FileUploadForm" asp-action="Upload" asp-controller="Home"
method="post" enctype="multipart/form-data">
<input id="uploadfile" type="file" />
<button name="uploadbtn" type="submit">Upload</button>
</form>
и здесь ненавязчивым способом обрабатывается событие отправки формы, где мы остановим обычное поведение и вместо этого сделаем отправку ajax.
$(function () {
$("#FileUploadForm").submit(function (e) {
e.preventDefault();
console.log('Doing ajax submit');
var formAction = $(this).attr("action");
var fdata = new FormData();
var fileInput = $('#uploadfile')[0];
var file = fileInput.files[0];
fdata.append("file", file);
$.ajax({
type: 'post',
url: formAction,
data: fdata,
processData: false,
contentType: false
}).done(function (result) {
// do something with the result now
console.log(result);
if (result.status === "success") {
alert(result.url);
} else {
alert(result.message);
}
});
});
})
Предполагая, что у вашего метода на стороне сервера есть параметр с именем, совпадающим с тем, который мы использовали при создании FormData
запись объекта (file
). Вот пример, где он будет загружать изображение в uploads
каталог внутри wwwwroot
,
Метод action возвращает объект JSON со свойством status и url/message, и вы можете использовать его в success
/done
обработчик вызова AJAX на все, что вы хотите сделать.
public class HomeController : Controller
{
private readonly IHostingEnvironment hostingEnvironment;
public HomeController(IHostingEnvironment environment)
{
_context = context;
hostingEnvironment = environment;
}
[HttpPost]
public async Task<IActionResult> Upload(IFormFile file)
{
try
{
var uniqueFileName = GetUniqueFileName(file.FileName);
var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
var filePath = Path.Combine(uploads, uniqueFileName);
file.CopyTo(new FileStream(filePath, FileMode.Create));
var url = Url.Content("~/uploads/" + uniqueFileName);
return Json(new { status = "success", url = url });
}
catch(Exception ex)
{
// to do : log error
return Json(new { status = "error", message = ex.Message });
}
}
private string GetUniqueFileName(string fileName)
{
fileName = Path.GetFileName(fileName);
return Path.GetFileNameWithoutExtension(fileName)
+ "_"
+ Guid.NewGuid().ToString().Substring(0, 4)
+ Path.GetExtension(fileName);
}
}
Поделиться кодом, который работал для меня, реализуя ответ @Shyju.
Вид (Страница Razor):
<form name="UploadForm" action="~/Resources/Upload" method="post" enctype="multipart/form-data">
<input name="uploadfile" type="file" />
<button name="uploadbtn" type="submit" onclick="SubmitForm(this.parentElement, event)">Upload</button>
Код AJAX, добавленный в Site.js (чтобы сделать его многоразовым):
// The function takes Form and the event object as parameter
function SubmitForm(frm, caller) {
caller.preventDefault();
var fdata = new FormData();
var file = $(frm).find('input:file[name="uploadfile"]')[0].files[0];
fdata.append("file", file);
$.ajax(
{
type: frm.method,
url: frm.action,
data: fdata,
processData: false,
contentType: false,
success: function (data) {
alert(data);
},
error: function (data) {
alert(data);
}
})
};
если вы хотите отправить форму без использования запроса ajax
var form = document.getElementById('formId');
form.submit();