需要通過 AJAX jQuery/JSON 使用 MVC 模型投標上傳檔案。
我正在使用普通的提交表單上傳,但現在我需要更改為 AJAX。我怎樣才能做到這一點?我的意思是,使用 MVC 和 AJAX 進行投標,序列化我的表單或類似的東西。
現在,我在 Controller 上的 imagemPro 和 imagemPre 始終為“空”。
在我看來:
@model Ri.Models.Produto
<form class="settings-form" id="frmAdd" enctype="multipart/form-data">
<label for="setting-input-1" class="form-label">Título</label>
<input asp-for="@Model.TituloProduto" type="text" class="form-control" required>
<input asp-for="@Model.ImagemProduto" type="file" class="form-control" required>
<label for="setting-input-1" class="form-label">Premio</label>
<input asp-for="@Model.TituloPremio" type="text" class="form-control" required>
<input asp-for="@Model.ImagemPremio" type="file" class="form-control" required>
<input type="button" value="Criar" class="btn app-btn-primary" id="btnAdd">
</form>
@section scripts{
<script src="~/admin/js/produtoAdd.js"></script>
}
在我的控制器:
[HttpPost("/api/ProdutoAdd")]
public async Task<IActionResult> ProdutoAdd([Bind("TituloProduto,ImagemProduto,TituloPremio,ImagemPremio")] Produto produto, IFormFile imagemPro, IFormFile imagemPre)
{
if (!ModelState.IsValid)
{
return Json(new { success = false, msg = "1" });
}
if (imagemPro != null)
{
var name = Path.Combine(_enviroment.WebRootPath "/imgs", System.IO.Path.GetFileName(imagemPro.FileName));
await imagemPro.CopyToAsync(new FileStream(name, FileMode.Create));
produto.ImagemProduto = imagemPro.FileName;
}
if (imagemPro != null)
{
var name = Path.Combine(_enviroment.WebRootPath "/imgs", System.IO.Path.GetFileName(imagemPre.FileName));
await imagemPro.CopyToAsync(new FileStream(name, FileMode.Create));
produto.ImagemPremio = imagemPre.FileName;
}
_context.Add(produto);
await _context.SaveChangesAsync();
return Json(new { success = true });
}
我的腳本:
$(function () {
$("#btnAdd").click(function (e) {
e.preventDefault();
var _this = $(this);
var _form = _this.closest("form");
var isvalid = _form.valid();
if (isvalid) {
Create();
}
else {
//alert('false');
}
});
Create = function () {
var options = {};
options.type = "POST";
options.url = "/api/ProdutoAdd";
options.dataType = "JSON";
options.cache = true;
options.async = true;
contentType = "application/json; charset=utf-8",
options.data = $('#frmAdd').serialize();
options.beforeSend = function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
};
options.success = function (data) {
};
options.error = function (res) {
};
$.ajax(options);
};
});
uj5u.com熱心網友回復:
我建議你創建一個 viewModel
public class ProdutoViewModel
{
public Produto Produto {get; set;}
public IFormFile ImagemPro {get; set;}
public IFormFile ImagemPre {get; set;}
}
動作(也洗掉 Bind 屬性)
[HttpPost("/api/ProdutoAdd")]
public async Task<IActionResult> ProdutoAdd(ProdutoViewModel model )
我建議您使用提交按鈕而不是 ajax,這對您來說會容易得多
@model ProdutoViewModel
<form class="settings-form" id="frmAdd" enctype="multipart/form-data">
....
<input type="submit" value="Criar" class="btn app-btn-primary">
</form>
uj5u.com熱心網友回復:
1.Model Binding通過name屬性系結property,你這里的引數名是imagemPro/ imagemPre。
2.jQueryserialize()方法將不包含輸入檔案元素。因此,選擇的檔案用戶不會包含在序列化值中。
您需要創建一個FormData物件,將檔案附加到該物件,然后將表單欄位值也附加到同一個 FormData 物件。您可以簡單地遍歷所有輸入欄位并添加它。
這是您可以遵循的完整作業演示:
@model Produto
//add `method="post"` in form tag
//otherwise it will not generate token input
<form class="settings-form" id="frmAdd" enctype="multipart/form-data" method="post">
<label for="setting-input-1" class="form-label">Título</label>
<input asp-for="@Model.TituloProduto" type="text" class="form-control" required>
<input asp-for="@Model.ImagemProduto" type="file" class="form-control" required>
<label for="setting-input-1" class="form-label">Premio</label>
<input asp-for="@Model.TituloPremio" type="text" class="form-control" required>
<input asp-for="@Model.ImagemPremio" type="file" class="form-control" required>
<input type="button" value="Criar" class="btn app-btn-primary" id="btnAdd">
</form>
@section scripts{
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/admin/js/produtoAdd.js"></script>
}
JS:
<script>
$(function () {
$("#btnAdd").click(function (e) {
e.preventDefault();
var _this = $(this);
var _form = _this.closest("form");
var isvalid = _form.valid();
if (isvalid) {
Create();
}
else {
}
});
Create = function () {
var fdata = new FormData();
var fileInput1 = $('#ImagemProduto')[0];
var file1 = fileInput1.files[0];
fdata.append("imagemPro", file1);
var fileInput2 = $('#ImagemPremio')[0];
var file2 = fileInput2.files[0];
fdata.append("imagemPre", file2);
$("form input[type='text']").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
var options = {};
options.type = "POST";
options.url = "/api/ProdutoAdd";
options.dataType = "JSON";
options.contentType = false; //change here...
options.processData= false; //add this...
options.data = fdata;
options.beforeSend = function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
};
options.success = function (data) {
};
options.error = function (res) {
};
$.ajax(options);
};
});
</script>
uj5u.com熱心網友回復:
您的有效負載和您的內容型別不匹配。jQuery.serialize將您的表單資料編碼為application/x-www-form-urlencoded,但您告訴服務器期望內容型別為application/json. 最簡單的解決方案是更改內容型別。
此外,您可能希望使用表單的表單提交事件,而不是按鈕上的“點擊”事件。這樣做的原因是瀏覽器會通過點擊按鈕以外的其他方式提交表單(例如,在文本輸入中按下“enter”鍵)。Submit 將處理所有這些方法。
另一個注意事項:您創建options物件的方法將起作用,但該語法有點尷尬。最常見的“最佳實踐”是宣告與物件行內的屬性:
var options = {
type: 'POST',
url: '/api/ProdutoAdd',
// etc ...
success: function (data) {
},
// etc ...
};
這使您不必options.在每個屬性之前輸入。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/446489.html
標籤:C# jQuery json asp.net 核心 .net-6.0
上一篇:僅替換字串中的第二個數字
下一篇:單擊按鈕時模式未打開
