Javascript 如何在asp.net核心中的视图组件(具有输入文件的窗体)和控制器之间进行交互?
我是asp.net核心网页设计的初学者。我编写了一个视图组件,它有一个表单,其中包含一些与视图模型相关的输入。其中一个输入是文件输入(IFormFile数据类型) 我想将此视图模型提交给控制器的操作(POST模式),检查模型的有效性,如果模型状态有效,则返回其他视图组件,如果模型状态无效,则使用此视图模型保留此视图组件 这是我的视图模型:PricingViewModel.cs 我的视图组件(控制器):PricingComponent.cs 问题: 计划A:若我像上面一样使用提交输入标记(asp操作,asp控制器)选项,视图模型发送正确,但我不知道如何处理模型的有效性并停留在这个视图组件上。在上面的代码中,当“ShowPricing”操作运行时,如果模型状态有效,代码正常工作,但当模型无效时(1,2,3),“PricingView”不显示验证摘要,只加载当前视图模型 方案B:我使用ajax将viewModel发送到action,而不是显示验证摘要,而是使用ajax向用户发送警报。我将PricingView更改如下: 我的视图组件(视图):PricingView.cshtmlJavascript 如何在asp.net核心中的视图组件(具有输入文件的窗体)和控制器之间进行交互?,javascript,c#,ajax,asp.net-core,view-components,Javascript,C#,Ajax,Asp.net Core,View Components,我是asp.net核心网页设计的初学者。我编写了一个视图组件,它有一个表单,其中包含一些与视图模型相关的输入。其中一个输入是文件输入(IFormFile数据类型) 我想将此视图模型提交给控制器的操作(POST模式),检查模型的有效性,如果模型状态有效,则返回其他视图组件,如果模型状态无效,则使用此视图模型保留此视图组件 这是我的视图模型:PricingViewModel.cs 我的视图组件(控制器):PricingComponent.cs 问题: 计划A:若我像上面一样使用提交输入标记(asp操
$(文档).ready(函数(){
$('#ShowPricingBtn')。单击(函数(){
var_url='@url.Action(“ShowPricing”,“Home”);
var input=$(“#MyInputFile”).get(0).files[0];
$.ajax({
类型:“POST”,
url:_url,
数据:{
formFile:输入,
colCode:$(“#colCode”).val(),
colName:$(“#colName”).val(),
},
成功:功能(结果)
{
var IsValid=$('body').find('[name=“IsValidPricing”]').val();
如果(有效)
{
$(“#ShowExcelTable”).html(结果);
}
否则{
警报(“无效数据”);
}
},
});
});
});
问题:
在此代码中:1。如果模型状态无效,则正确发送警报。但如果模型状态有效:2。formFile输入未正确发送到操作,并且在视图模型中为空
我不知道我应该在A计划或B计划中做些什么来解决他们的问题。你知道我的错在哪里吗?我无法重现你的错误。您的代码,正如所展示的,按预期工作。将显示一条验证消息 为了使它成为一个工作示例,我首先添加了一个GET方法
[HttpGet]
public IActionResult ShowPricing() => ViewComponent("PricingComponent", new { pricing = new PricingViewModel() });
打开主页/ShowPricing的URL
填写表格
发送表格。并显示验证消息
不确定如何调用视图组件,以下是工作演示: 用于平面图 1.创建
ViewComponents/PricingComponent.cs
和ViewComponents/ShowPricingExcelComponent.cs
public class PricingComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(PricingViewModel pricing)
{
return await Task.FromResult((IViewComponentResult)View("PricingView", pricing));
}
}
public class ShowPricingExcelComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(PricingViewModel pricing)
{
return await Task.FromResult((IViewComponentResult)View("ShowPricingExcel", pricing));
}
}
3.创建视图/Shared/Components/ShowPricingExcelComponent/ShowPricingExcel.cshtml
@model PricingViewModel
<form class="text-left" method="post" enctype="multipart/form-data">
<input name="IsValidPricing" type="hidden" value="@ViewBag.isValid" />
<div class="form-group text-left">
<label asp-for="colCode" class="control-label"></label>
<input asp-for="colCode" class="form-control" id="colCodeId" />
<span asp-validation-for="colCode" class="text-danger"></span>
</div>
<div class="form-group text-left">
<label asp-for="colName" class="control-label"></label>
<input asp-for="colName" class="form-control" id="colNameId" />
<span asp-validation-for="colName" class="text-danger"></span>
</div>
<div class="form-group text-left">
<label asp-for="formFile " class="control-label"></label>
<input type="file" accept=".xlsx, .csv" asp-for="formFile" id="MyInputFile" />
</div>
<div class="form-group mt-4">
<input type="submit" asp-action="ShowPricing" asp-controller="Home" value="Show" id="ShowPricingBtn" />
</div>
</form>
<h1>Excel....</h1>
<h1>Excel....</h1>
5.家庭控制器:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult ShowPricing(PricingViewModel pricing)
{
if (ModelState.IsValid)
{
int temp;
if (!int.TryParse(pricing.colCode, out temp))
{
ViewBag.isValid = 0;
ModelState.AddModelError("colCode", "Invalid Data");
return View("Index", pricing);
}
if (!int.TryParse(pricing.colName, out temp))
{
ViewBag.isValid = 0;
ModelState.AddModelError("colName", "Invalid Data");
return View("Index", pricing);
}
else
{
ViewBag.isValid = 1;
// do something ...
return ViewComponent("ShowPricingExcelComponent"); //Call another view component
}
}
else
{
ViewBag.isValid = 0;
return View("Index", pricing); //3
}
}
}
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult ShowPricing(PricingViewModel pricing)
{
if (ModelState.IsValid)
{
int temp;
if (!int.TryParse(pricing.colCode, out temp)|| !int.TryParse(pricing.colName, out temp))
{
ViewBag.isValid = 0;
return Json(false);
}
else
{
ViewBag.isValid = 1;
// do something ...
return ViewComponent("ShowPricingExcelComponent"); //Call another view component
}
}
else
{
ViewBag.isValid = 0;
return Json(false);
}
}
}
结果:
用于PlanB
1.创建ViewComponents/PricingComponent.cs
和ViewComponents/ShowPricingExcelComponent.cs
public class PricingComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(PricingViewModel pricing)
{
return await Task.FromResult((IViewComponentResult)View("PricingView", pricing));
}
}
public class ShowPricingExcelComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(PricingViewModel pricing)
{
return await Task.FromResult((IViewComponentResult)View("ShowPricingExcel", pricing));
}
}
2.创建视图/Shared/Components/PricingComponent/PricingView.cshtml
@model PricingViewModel
<form class="text-left" method="post" enctype="multipart/form-data">
<input name="IsValidPricing" type="hidden" value="@ViewBag.isValid" />
<div class="form-group text-left">
<label asp-for="colCode" class="control-label"></label>
<input asp-for="colCode" class="form-control" id="colCodeId" />
<span asp-validation-for="colCode" class="text-danger"></span>
</div>
<div class="form-group text-left">
<label asp-for="colName" class="control-label"></label>
<input asp-for="colName" class="form-control" id="colNameId" />
<span asp-validation-for="colName" class="text-danger"></span>
</div>
<div class="form-group text-left">
<label asp-for="formFile " class="control-label"></label>
<input type="file" accept=".xlsx, .csv" asp-for="formFile" id="MyInputFile" />
</div>
<div class="form-group mt-4">
<input type="submit" asp-action="ShowPricing" asp-controller="Home" value="Show" id="ShowPricingBtn" />
</div>
</form>
<h1>Excel....</h1>
<h1>Excel....</h1>
首先,它应该是type=“button”
,否则它将调用两次后端。其次,您在ajax中所做的不正确,您可以参考更详细的解释。最后,您无法通过在Success函数中获取IsValidPricing
值来判断modelstate。因为您获取的值始终是您首次呈现页面的数据,所以在ajax发回时无法获取更改的ViewBag值
@model PricingViewModel
<form class="text-left" method="post" enctype="multipart/form-data">
<input name="IsValidPricing" type="hidden" value="@ViewBag.isValid" />
<div class="form-group text-left">
<label asp-for="colCode" class="control-label"></label>
<input asp-for="colCode" class="form-control" id="colCodeId" />
<span asp-validation-for="colCode" class="text-danger"></span>
</div>
<div class="form-group text-left">
<label asp-for="colName" class="control-label"></label>
<input asp-for="colName" class="form-control" id="colNameId" />
<span asp-validation-for="colName" class="text-danger"></span>
</div>
<div class="form-group text-left">
<label asp-for="formFile " class="control-label"></label>
<input type="file" accept=".xlsx, .csv" asp-for="formFile" id="MyInputFile" />
</div>
<div class="form-group mt-4">
@*it should be type="button"*@
<input type="button" value="Show" id="ShowPricingBtn" />
</div>
</form>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
$(document).ready(function () {
$('#ShowPricingBtn').click(function () {
var _url = '@Url.Action("ShowPricing", "Home")';
var input = $("#MyInputFile").get(0).files[0];
var fdata = new FormData();
fdata.append("formFile", input);
$("form input[type='text']").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
$.ajax({
type: "POST",
url: _url,
data: fdata,
contentType: false,
processData: false,
success: function (result)
{
console.log(result);
if (result==false)
{
alert("Invalid Data");
}
else {
$("#ShowExcelTable").html(result);
}
},
});
});
});
</script>
4.Views/Home/Index.cshtml
:
@await Component.InvokeAsync("PricingComponent")
@await Component.InvokeAsync("PricingComponent")
<div id="ShowExcelTable"></div>
结果:
我已经检查了您的代码,它正在进行验证。将显示错误。为什么要使用返回视图组件(…)而不是返回视图(…)?@Justthebenno您检查了哪个计划?您是如何编写工作正常并显示验证的代码的。我使用return viewComponent(…),因为我的视图是一个viewComponent(在~/Views/shared/Components中)。我做了一些更改,比如总是返回相同的viewComponent
return viewComponent(“PricingComponent”,new{pricing=pricing})代码>我希望避免每个案例都有新的组件。我构建了一个简单的GET方法,比如“``[HttpGet]public-IActionResult-ShowPricing()=>ViewComponent(“PricingComponent”,new{pricing=new-PricingViewModel()”;```然后把表格寄过来。结果:对于您的用例,一个简单的视图似乎就足够了。ViewComponents更适合@Justthebenno我不写我所有的项目。我只是写了其中的一部分。由于我的项目的其余部分,我不得不使用视图组件,而不是简单的视图。我想可能有一个输入错误,else if(!int.TryParse(updatePricing.colName,out temp))
到else if(!int.TryParse(pricing.colName,out temp))
但是,是的,你的代码。我能为你做的,就是有一个实时共享会话或类似的东西,我可以看看你的代码,我们可以试着找出原因。是的。因为它返回的是ViewComponent而不是视图。这是可能的。不过,您的输入文件使它有点复杂。看一看作为灵感。请记住,您需要将其他属性(如colCode
)添加到表单数据(formData.append(“colCode”);
)非常感谢您的帮助。。。我使用了PlanB(ajax)并得到了答案。
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult ShowPricing(PricingViewModel pricing)
{
if (ModelState.IsValid)
{
int temp;
if (!int.TryParse(pricing.colCode, out temp)|| !int.TryParse(pricing.colName, out temp))
{
ViewBag.isValid = 0;
return Json(false);
}
else
{
ViewBag.isValid = 1;
// do something ...
return ViewComponent("ShowPricingExcelComponent"); //Call another view component
}
}
else
{
ViewBag.isValid = 0;
return Json(false);
}
}
}