问题
我有一个客户端视图模型,它包含一些必需的属性和非必需的属性。视图包含用于更新不同视图模型属性的不同部分。如果我用需要的客户端详细信息(如FirstName、LastName、道布等)更新视图的一部分,那么我可以将输入类型包装到ajax表单中,控制器将从视图模型中获取这些属性,并相应地使用ModelState.IsValid进行验证,验证就会成功。但是,如果我在同一视图上有另一节需要更新视图模型(即Notes)上的非必需属性,并将其从ajax表单post中传递出去,那么ModelState验证就会失败,因为其他必需的属性是空的,因为它们从未作为ajax表单的一部分提交。请注意,在加载客户端详细信息页之前,所需字段应该始终填充数据,因此不应该为null。
代码
ViewModel
public class ClientDetailViewModel
{
public int ID { get; set; }
[Required]
[StringLength(50, MinimumLength = 2)]
public string FirstName { get; set; }
[Required]
[StringLength(50, MinimumLength = 2)]
public string LastName { get; set; }
[Required]
[Display(Name = "Date of Birth")]
[DataType(DataType.Date)]
public DateTime DOB { get; set; }
[Required]
public string Gender { get; set; }
public string Notes { get; set; }
}视图
@model MSIC.Models.ClientViewModels.ClientDetailViewModel
@inject MSIC.Services.Custom.IGenderService GenderService;
<!-- tab-pane for updating core client details -->
<div class="tab-pane active" id="tab_1">
<form asp-controller="Client" asp-action="Edit" class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="FirstName" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="LastName" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="DOB" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input asp-for="DOB" class="form-control" />
<span asp-validation-for="DOB" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Gender" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<select asp-for="Gender" asp-items="@(new SelectList(GenderService.GetAll(),"Code","Name"))" class="form-control">
</select>
<span asp-validation-for="Gender" class="text-danger" />
</div>
</div>
</form>
</div>
<!-- different section for updating client notes -->
<div id="divNotes" class="center-block">@Model.Notes</div>
<a href="#" class="btn btn-danger btn-block" data-toggle="modal" data-target="#notesModal" role="button"><b>Edit Notes</b></a>
<form asp-controller="Client" asp-action="EditNotes" class="form-horizontal" data-ajax="true" data-ajax-method="POST" data-ajax-update="#divNotes" data-ajax-mode="replace" data-ajax-success="CloseModal('#notesModal')" data-ajax-failure="AjaxOnFailure(xhr, status, error)">
<div class="modal fade" id="notesModal" tabindex="-1" role="dialog" aria-labelledby="notesModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="notesModalLabel">edit Reason</h4>
</div>
<div class="modal-body">
<input type="hidden" asp-for="ID" />
<div class="form-group">
<div class="col-sm-10">
<textarea asp-for="Notes" class="form-control" autofocus></textarea>
<span asp-validation-for="Notes" class="text-danger" />
</div>
</div>
</div>
<div class="modal-footer">
<div class="text-danger pull-left">
<i id="modalErrorIcon" class=""></i>
<span id="modalErrorText"></span>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</form>控制器
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult EditNotes(ClientDetailViewModel model)
{
//validation fails because required fields in model are null since they were not submitted with this ajax form
if (ModelState.IsValid)
{
//update database with client notes and return notes to screen
return Content(model.Notes);
}
return Content("i haven't coded this yet");
}问题
提前谢谢。
发布于 2016-10-19 08:10:20
虽然我无法得到建议的方法来按照建议行事,但我确实使用了关于将视图模型分离出来以用于呈现和提交的建议。我想我被微软ASP.NET核心网站上的电影教程引入了歧途,它在细节和编辑页面上都使用了相同的电影模型。
为了进一步解决我的问题,我已经为细节页面采用了一个大的视图模型,我将对需要更新的页面的各个部分使用view组件。这允许我为每个View组件提供一个单独的视图模型,我的控制器post操作可以只接受与相应的View组件相关的视图模型,这样它只能执行必要的ModelState验证。
来自一个jQuery ajax帖子的服务器端验证导致了关于将ModelState错误返回给客户端以供显示的下一个问题,但是我提交了一个新的问题.
发布于 2016-10-17 14:54:03
为所有调用(通过使用隐藏字段)发送所有的东西并不昂贵,但它很麻烦,不是一个直接的解决方案。
MVC中的视图模型不必是呈现页面和提交表单的同一个类。在您的示例中,您可以定义一个视图模型,用于如下所示的呈现:
public class ClientDetailViewModel {
public ClientBasicViewModel Basics {get;set;}
public ClientNotesViewModel Notes {get;set;}
}然后将字段(姓名、性别等)放在两个新的类中。使用两个单独的控制器方法来处理表单提交。跟踪FirstName如何发送和接收:
input name="FirstName"...https://stackoverflow.com/questions/40087998
复制相似问题