【发布时间】:2018-09-18 11:02:36
【问题描述】:
以下简单的 .NET Core 2.1 MVC 代码在我提交创建时报告“验证状态:无效”。没有 Owner 财产一切正常;如果不需要 Owner 属性,它就可以工作。
所有者是服务器端上下文中的当前用户,不应从客户端提交,因此 Create.cshtml 在表单中没有所有者输入。
错误:
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method AnnouncementApp.Controllers.AnnouncementsController.Create (AnnouncementApp) with arguments (AnnouncementApp.Models.Announcement) - Validation state: Invalid
型号:
using System;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using AnnouncementApp.Models.Attributes;
using Microsoft.AspNetCore.Identity;
//using System.Security.Claims;
namespace AnnouncementApp.Models
{
public class Announcement
{
public int ID { get; set; }
[Required]
public string Content { get; set; }
[Display(Name = "Start Date and Time")]
public DateTime StartDate { get; set; }
[StartEndDate("End Date and Time must be after Start Date and Time")]
[Display(Name = "End Date and Time")]
public DateTime EndDate { get; set; }
[Required]
[BindNever]
public IdentityUser Owner { get; set; }
}
}
控制器方法:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,Content,StartDate,EndDate")] Announcement announcement)
{
if (ModelState.IsValid)
{
var user = await _userManager.GetUserAsync(this.User);
announcement.Owner = user;
_context.Add(announcement);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(announcement);
}
Create.cshtml
@model AnnouncementApp.Models.Announcement
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<h4>Announcement</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Content" class="control-label"></label>
<textarea asp-for="Content" class="form-control"></textarea>
<span asp-validation-for="Content" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="StartDate" class="control-label"></label>
<input asp-for="StartDate" class="form-control" />
<span asp-validation-for="StartDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EndDate" class="control-label"></label>
<input asp-for="EndDate" class="form-control" />
<span asp-validation-for="EndDate" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
【问题讨论】:
-
ID 需要隐藏字段吗?
-
不,我不知道。我认为Required 和BindNever 只是冲突。必需的似乎优先。我想将其设置为必需,因为我希望实体框架脚手架使 CREATE TABLE sql 在结果 OwnerId 列上具有 NOT NULL;但这会破坏模型绑定验证。
-
int 应转换为 NOT NULL。诠释? (或可为空的数据类型)转换为 NULL。但是您可能需要考虑创建一组与您的域模型分开的 ViewModel。域模型可以关联到数据库,而 ViewModel 可以关联到网页。
-
@sean 是正确的。为什么要包含您永远不想从客户端传递的东西作为客户端验证?仅使用视图通过任何测试和验证输入所需的内容创建 ViewModel。
-
@sean 是正确的。我应该将 ViewModel 从域模型中分离出来。谢谢。
标签: .net-core asp.net-core-mvc