首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于Ajax加载的部分参数的ModelState.AddModelError

用于Ajax加载的部分参数的ModelState.AddModelError
EN

Stack Overflow用户
提问于 2020-11-27 00:14:41
回答 1查看 22关注 0票数 0

我在我的主页上有一个加载表单的局部视图,模型如下:

代码语言:javascript
运行
复制
public class CreateRequestViewModel
    {
        [Required]
        public short ClientId { get; set; }
        [Required]
        public Guid SystemId { get; set; }

        [Required]
        public string RequestedUsername { get; set; }
        public string TicketReference { get; set; }
        public string Notes { get; set; }

        public List<SelectListItem> Clients { get; set; }
        public List<SelectListItem> Systems { get; set; }
    }

这是局部视图:

代码语言:javascript
运行
复制
@model Models.CreateRequestViewModel

@Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" })

<div class="row">
    <div class="col-lg-4 col-md-4 col-sm-12">
        <h1>Create a Request</h1>
    </div>
    <div class="col-lg-8 col-md-8 col-sm-12 right">
        <div class="form-group">
            @Html.DropDownListFor(m => m.ClientId, Model.Clients, htmlAttributes: new { @class = "form-control form-control-lg", @id = "ClientSelect" })
            @Html.ValidationMessageFor(m => m.ClientId, "", htmlAttributes: new { @class = "text-danger" })
        </div>
        <div class="form-group">
            @Html.DropDownListFor(m => m.SystemId, Model.Systems, htmlAttributes: new { @class = "form-control form-control-lg", @id = "ClientSystemSelect" })
            @Html.ValidationMessageFor(m => m.SystemId, "", htmlAttributes: new { @class = "text-danger" })
        </div>
        <div class="form-group">
            @Html.TextBoxFor(m => m.RequestedUsername, htmlAttributes: new { @class = "form-control form-control-lg", @placeholder = "Username" })
            @Html.ValidationMessageFor(m => m.RequestedUsername, "", htmlAttributes: new { @class = "text-danger" })
        </div>
        <div class="form-group">
            @Html.TextBoxFor(m => m.TicketReference, htmlAttributes: new { @class = "form-control form-control-lg", @placeholder = "Ticket reference" })
        </div>
        <div class="form-group">
            @Html.TextAreaFor(m => m.Notes, htmlAttributes: new { @class = "form-control form-control-lg", @rows = 3, @placeholder = "Notes..." })
        </div>
        <input type="Submit" class="btn btn-secondary btn-block send-request" value="Submit" name="">
    </div>
</div>

这是我加载页面的方式:

代码语言:javascript
运行
复制
<div class="container">
    <div class="row">
        <div class="col-lg-6">
            <form asp-action="CreateRequest" asp-controller="Access"
                data-ajax="true"
                data-ajax-method="POST"
                data-ajax-mode="replace"
                data-ajax-update="#createRequest">
                <div id="createRequest">
                    @await Html.PartialAsync("_CreateRequest", Model.CreateRequestModel)
                </div>
            </form>
        </div>
    </div>
</div>

使用模型并使用不显眼的javascript,例如,将RequestedUsername留空将导致表单不被提交,并为其显示验证消息。这太棒了。

但是,我需要首先根据数据库中的条目检查表单数据,如果存在记录,则抛出错误。我认为,随着所有客户端验证的通过,我应该在控制器中使用ModelState.AddModelError,如下所示:

代码语言:javascript
运行
复制
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult CreateRequest(CreateRequestViewModel model)
{
    if(model.RequestedUsername == "someincorrectvalue"){ //actual logic removed for brevity
        ModelState.AddModelError("RequestedUsername", "Already in use");
    }

    if(!ModelState.IsValid)
    {
        //reset lists on model, removed
        return PartialView("_CreateRequest", model);
    }

    _logger.LogInformation("CreateRequest successful");

    return RedirectToAction(nameof(Index));
}

但是,如果我使用ModelState.AddModelError,return PartialView("_CreateRequest", model)调用最终会重新加载整个页面,就像它返回一个完整视图一样。

我不知道为什么会发生这样的事情。我能看到的不同之处在于,我在控制器中添加了一个ModelState错误,而验证发生在客户端。

有谁有主意吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-27 02:54:21

所以,这被证明是一系列问题的组合。首先,我在解决方案中使用的不显眼的Ajax脚本无法运行。我不知道为什么,但我把它们换成了CDN中的一个:https://ajax.aspnetcdn.com/ajax/jquery.unobtrusive-ajax/3.2.5/jquery.unobtrusive-ajax.min.js

这解决了整个页面重新加载的问题,而不是通过低调的ajax返回部分页面。

第二个问题是,在成功时,我重定向到Index控制器操作,而不是再次返回Partial。这会导致整个Index页面呈现在我选择作为ajax目标的div中。我的控制器操作现在看起来像这样:

代码语言:javascript
运行
复制
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult CreateRequest(CreateRequestViewModel model)
{
    if(model.RequestedUsername == "someincorrectvalue"){ //actual logic removed for brevity
        ModelState.AddModelError("RequestedUsername", "Already in use");
    }

    if(!ModelState.IsValid)
    {
        //reset lists on model, removed
        return PartialView("_CreateRequest", model);
    }

    _logger.LogInformation("CreateRequest successful");

    // reset lists on model, removed
    ModelState.Clear(); // get rid ofany model details to make way for a new request
    return PartialView("_CreateRequest", model);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65025663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档