猿问

模型未验证

所以,当为我的模型输入文本时,它总是有效的,即使我明确要求它有一个 minLength,尽管它是空的或小于 minLength。


楷模:


public class CommentaarCreate_VM

{

    public Stad Stad { get; set; }

    [Required]

    public Commentaar Commentaar { get; set; }

}

public class Commentaar

{

    [Key]

    public int CommentaarId { get; set; }

    [Required]

    public string UserId { get; set; } 

    [Required]

    public int StadId { get; set; }

    [Required(AllowEmptyStrings=false, ErrorMessage="You need to enter a comment of valid length")]

    [MinLength(5, ErrorMessage ="You need to enter a comment of valid length")]

    public string CommentaarText { get; set; }

    [Required]

    [DataType(DataType.DateTime)]

    public DateTime Tijdstip { get; set; }

}

看法:


@model DataGent.Web.ViewModels.CommentaarCreate_VM


@{

ViewData["Title"] = "Create new comment";

}

<div class="row">

<div class="col-md-4">

    <form asp-action="Create">

        <div asp-validation-summary="All" class="text-danger"></div>

        <input type="hidden" asp-for="Stad.Id" />

        <input type="hidden" asp-for="Stad.Naam" />

        <input type="hidden" value="@Html.AntiForgeryToken()" />


        <div class="form-group">

            <label asp-for="Commentaar" class="control-label"></label>

            <input asp-for="Commentaar" class="form-control" />

            <span asp-validation-for="Commentaar.CommentaarText" class="text-danger"></span>

        </div>

        <div class="form-group">

            <input type="submit" value="Save" class="btn btn-default" />

        </div>

    </form>

</div>

控制器动作:


public ActionResult Create(int id)

    {

        CommentaarCreate_VM vm = new CommentaarCreate_VM()

        {

            Stad = _dataGentService.GetStadFromId(id),

            Commentaar = null

        };


        return View(vm);

    }


有什么我想念的吗?我以为除了数据注释之外的所有工作都是由 MVC 完成的?


潇潇雨雨
浏览 213回答 3
3回答

鸿蒙传说

您的输入是:<input asp-for="Commentaar" class="form-control" />您必须将 asp-for 从 Commentaar 更改为 Commentaar.CommentaarText 以便对其进行验证:<div class="form-group">&nbsp; &nbsp; <label asp-for="Commentaar.CommentaarText" class="control-label"></label>&nbsp; &nbsp; <input asp-for="Commentaar.CommentaarText" class="form-control" />&nbsp; &nbsp; <span asp-validation-for="Commentaar.CommentaarText" class="text-danger"></span></div>更新:在将 Commentaar 对象传递给视图之前,在视图模型中初始化它:public ActionResult Create(int id){&nbsp; &nbsp; CommentaarCreate_VM vm = new CommentaarCreate_VM()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Stad = _dataGentService.GetStadFromId(id),&nbsp; &nbsp; &nbsp; &nbsp; Commentaar = new Commentaar()&nbsp; &nbsp; };&nbsp; &nbsp; return View(vm);}

RISEBY

一个好的做法是ModelState.IsValid在您的 post 方法上使用,以检查正在发送的模型的属性。也就是说, ModelState.IsValid 检查您在模型上编写的数据注释。[HttpPost]&nbsp; &nbsp; [ValidateAntiForgeryToken]&nbsp; &nbsp; public ActionResult Create([Bind("CommentaarText, Tijdstip")] int id, IFormCollection collection) //Bind = protect from overposting&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(ModelState.IsValid)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//If it is valid, do all your business logic, like creating a new entry.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//Handle it&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return View();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; }另一件事是我看到你使用ViewModels哪个好。因此,您可以将视图模型作为操作的参数发送。你可以这样做:[HttpPost]&nbsp; &nbsp; [ValidateAntiForgeryToken]&nbsp; &nbsp; public ActionResult Create(CommentaarCreate_VM viewmodel)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(ModelState.IsValid)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//It is valid&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//All your logic&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//Not valid&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return View(Viewmodel model)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; }通过这样做,您必须将数据注释添加到 CommentaarCreate_VM&nbsp; public class CommentaarCreate_VM&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public Stad Stad { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; [Required(AllowEmptyStrings=false, ErrorMessage="You need to enter a comment of valid length")]&nbsp; &nbsp; &nbsp; &nbsp; [MinLength(5, ErrorMessage ="You need to enter a comment of valid length")]&nbsp; &nbsp; &nbsp; &nbsp; public Commentaar Commentaar { get; set; }&nbsp; &nbsp; }

素胚勾勒不出你

所以我至少找到了一些解决方案,但潜在的问题仍然存在。问题是在控制器中 Modelstate.IsValid 始终为真,即使某些模型不应该是有效的,所以它只是在重定向到另一个页面之前执行我想要的操作。解决方案是,如果在控制器中检查字符串是否为空或为空,则我可以使错误消息正常工作,如果是,则返回(viewmodel),然后使错误消息正常工作。显然,Modelstate.IsValid 不应该返回真,我仍然不知道为什么会这样。[HttpPost]&nbsp; &nbsp; [ValidateAntiForgeryToken]&nbsp; &nbsp; public ActionResult Create([Bind("CommentaarText, Tijdstip")] int id, CommentaarCreate_VM viewModel, IFormCollection collection) //Bind = protect from overposting&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //If incoming string is null or empty&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (string.IsNullOrEmpty(collection["Commentaar"]))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return View(viewModel);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }//This always returns true. It really shouldn't, because otherwise I wouldn't need that earlier check.&nbsp;//If the model isn't valid in the View, this one should be false, right?&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (ModelState.IsValid)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Creating&nbsp; object to POST&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //.....&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return RedirectToAction(nameof(Index));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return View();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return View();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }
随时随地看视频慕课网APP
我要回答