【发布时间】:2021-04-23 10:11:37
【问题描述】:
我是使用 ASP.NET Core 进行网页设计的初学者。我编写了一个视图组件,它有一个表单,其中包含一些与视图模型相关的输入。其中一个输入是文件输入(IFormFile 数据类型)。
我想将此视图模型提交给控制器的一个动作(POST 动作),检查模型的有效性,如果模型状态有效,则返回另一个视图组件,并使用此视图模型保留在此视图组件上如果模型状态无效。
这是我的视图模型:PricingViewModel.cs
public class PricingViewModel
{
[Display(Name = "Select a file")]
public IFormFile formFile { get; set; }
[Display(Name = "ColumnCode")]
[Required(ErrorMessage = "Enter {0} value, please")]
public string colCode { get; set; }
[Display(Name = "ColumnName")]
[Required(ErrorMessage = "Enter {0} value, please")]
public string colName { get; set; }
}
我的视图组件(控制器):PricingComponent.cs
public class PricingComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(PricingViewModel pricing)
{
return await Task.FromResult((IViewComponentResult)View("PricingView", pricing));
}
}
我的视图组件(视图):PricingView.cshtml
<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>
我的家庭控制器:HomeController.cs
[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 ViewComponent("PricingComponent", new { pricing = pricing }); // 1
}
else if (!int.TryParse(pricing.colName, out temp))
{
ViewBag.isValid = 0;
ModelState.AddModelError("colName", "Invalid Data");
return ViewComponent("PricingComponent", new { pricing = pricing }); //2
}
else
{
ViewBag.isValid = 1;
// do something ...
return ViewComponent("ShowPricingExcelComponent"); //Call another view component
}
}
else
{
ViewBag.isValid = 0;
return ViewComponent("PricingComponent", new { pricing = pricing }); //3
}
}
计划A
以上方法是我的主要计划。
问题
如果我像上面那样使用提交输入标签的选项(asp-action,asp-controller),视图模型会正确发送,但我不知道如何处理模型的有效性并保留在此视图组件上。在上面的代码中,当ShowPricing动作运行时,如果模型状态有效,代码可以正常工作,但是当模型无效(1,2,3)时,PricingView不显示验证摘要,并且只加载当前视图模型。
计划 B
我使用 AJAX 将 viewModel 发送到操作,而不是显示验证摘要,而是使用 AJAX 向用户发送警报。我将PricingView 更改为:
我的视图组件(视图):PricingView.cshtml
<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="fromFile " class="control-label"></label>
<input type="file" accept=".xlsx, .csv" asp-for="formFile" id="MyInputFile"/>
</div>
<script>
$(document).ready(function () {
$('#ShowPricingBtn').click(function () {
var _url = '@Url.Action("ShowPricing", "Home")';
var input = $("#MyInputFile").get(0).files[0];
$.ajax({
type: "POST",
url: _url,
data: {
formFile: input,
colCode: $("#colCode").val(),
colName: $("#colName").val(),
},
success: function (result)
{
var IsValid = $('body').find('[name="IsValidPricing"]').val();
if (IsValid)
{
$("#ShowExcelTable").html(result);
}
else {
alert("Invalid Data");
}
},
});
});
});
</script>
<div class="form-group mt-4">
<input type="submit" value="Show" id="ShowPricingBtn" />
</div>
</form>
问题
在这段代码中:
- 如果模型状态无效,警报会正确发送,但是
- 如果模型状态有效,
formFile输入不会正确发送到操作,并且在视图模型中为空。
我不知道我应该采用原始方法还是替代方法解决这些问题。你知道我哪里出错了吗?
【问题讨论】:
-
我已经检查了您的代码并且它正在使用验证。显示错误。为什么你使用
return ViewComponent(...)而不是返回View(...)? -
@Justthebenno 您检查了哪个计划?您是如何编写有效并显示验证的代码的。我使用 return viewComponent(...) 因为我的视图是一个视图组件(在 ~/Views/shared/Components 中)。
-
我做了一些改变,比如总是返回相同的 ViewComponent
return ViewComponent("PricingComponent", new { pricing = pricing });我想避免在每种情况下都有新的组件。我构建了一个简单的 GET 方法,例如 ``` [HttpGet] public IActionResult ShowPricing() => ViewComponent("PricingComponent", new { price = new PricingViewModel() });``` 并发送表单。结果:pasteboard.co/JKkcYTO.png -
对于您的用例,一个简单的视图似乎就足够了。 ViewComponents 更多用于advanced scenarios
-
@Justthebenno 我不会写我所有的项目。我只写其中的一部分。由于我的项目的其余部分,我必须使用视图组件,而不是简单的视图。
标签: javascript c# ajax asp.net-core asp.net-core-viewcomponent