不显眼的 Ajax 与不显眼的验证

Unobtrusive Ajax w/ Unobtrusive Validation

提问人:s15199d 提问时间:7/27/2023 最后编辑:Qing Guos15199d 更新时间:7/31/2023 访问量:89

问:

我有一个带有单个文本框的表单。绑定到该文本框的字段是必需的。

当我发布该文本框为空的表单时,我得到了预期的结果。但是,表单仍然会触发 .ModelState.IsValid = Falsedata-ajax-success

相关 .cshtml

<form method="post" asp-page-handler="ProductAliasCreate" data-ajax="true" data-ajax-method="post" data-ajax-success="refreshPartial('GetAliases', 'product-aliases-container')" data-ajax-failure="handleError">

相关 .cshtml.cs

public async Task<IActionResult> OnPostProductAliasCreateAsync()
{
    if (!ModelState.IsValid || _context.ProductAliases == null || ProductAlias == null)
    {
        return Page();
    }

    _context.ProductAliases.Add(ProductAlias);
    await _context.SaveChangesAsync();

    return Page();
}

它首先击中了那张支票。return Page();Isvalid

如何防止 data-ajax-success 回调在 ModelState.IsValid = false 时触发?

注意:我之前有过回调,结果相同......所以我把它移到认为这将是这个问题的解决方案。refreshPartialdata-ajax-completedata-ajax-success

asp.net-core .net-core razor-pages unobtrusive-ajax

评论

0赞 Qing Guo 7/28/2023
在Isvalid检查中添加怎么样?return PartialView("_Errorview");
0赞 s15199d 7/29/2023
@QingGuo感谢您的回复!我希望视图保持原位,并且不显眼的验证显示 .我该怎么做?<span asp-validation-for="ProductAlias.ProductAliasName" class="text-danger"></span>

答:

1赞 Ruikai Feng 7/28/2023 #1

Return Page() 总是在你的 senaro 中返回带有 200 个雕像代码的响应,如果你想在 modelstate 无效时触发,你应该返回带有 400 个雕像代码的响应data-ajax-success

一个最小的例子,希望能有所帮助:

页面模型:

public class MyEntityModel : PageModel
    {
        [BindProperty(SupportsGet =true)]
        public MyEntity? MyEntity { get; set; }
        public void OnGet()
        {
        }
        public async Task<IActionResult> OnPostProductAliasCreateAsync()
        {
            if (!ModelState.IsValid )
            {
                return BadRequest();
            }         

            return new OkObjectResult("");
        }
    }

页:

@page
@model MyEntityModel
@{
}
<form method="post" asp-page-handler="ProductAliasCreate" data-ajax="true" data-ajax-method="post" data-ajax-success="success()" data-ajax-failure="fail()">

    Id:
    <input asp-for="MyEntity.Id" />
    Name:
    <input asp-for="MyEntity.Name" />

    <input type="submit" />
</form>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-ajax-unobtrusive/jquery.unobtrusive-ajax.js"></script>
<script>
    function success() {
        console.log("success")
    }
    function fail(){
        console.log("fail")
    }
</script>

结果:

enter image description here

根据您的评论进行更新

如果您已通过客户端验证(在我的情况下,null 检查)并在服务器上出现模型状态错误(例如,重复的名称)

如果要显示错误,则必须由于ajax调用而自己刷新页面

我的解决方案:

创建筛选器:

public class MyPageFilter : IPageFilter
    {       

        public void OnPageHandlerSelected(PageHandlerSelectedContext context)
        {
            
        }
        public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
        {
            
        }
        public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
        {
            if (context.ModelState.ErrorCount != 0)
            {
                context.HttpContext.Response.StatusCode = 400;
            }
        }
    }

页面模型:

[TypeFilter(typeof(MyPageFilter))]
    public class EntityModel : PageModel
    {
        private readonly MyRazorPageApp.Areas.Identity.Data.MyRazorPageAppContext _context;
        private readonly ICompositeViewEngine _viewEngine;

        public EntityModel(MyRazorPageApp.Areas.Identity.Data.MyRazorPageAppContext context, ICompositeViewEngine viewEngine)
        {
            _context = context;
            _viewEngine = viewEngine;
        }

        public IActionResult OnGet()
        {
            
            return Page();
        }

        [BindProperty]
        public MyEntity MyEntity { get; set; } = default!;
        

        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
            ModelState.AddModelError("MyEntity.Name", "Not Valid");
            if (!ModelState.IsValid || _context.MyEntity == null || MyEntity == null)
            {
               
                return Page();
            }            
            return RedirectToPage("./Index");
        }
    }

页:

@page
@model MyRazorPageApp.Pages.EntityModel

@{
    
}

<h1>Enyity</h1>

<h4>MyEntity</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post" data-ajax="true" data-ajax-method="post" data-ajax-success="success" data-ajax-failure="fail">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="MyEntity.Name" class="control-label"></label>
                <input asp-for="MyEntity.Name" class="form-control" />
                <span asp-validation-for="MyEntity.Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="MyEntity.Prop" class="control-label"></label>
                <input asp-for="MyEntity.Prop" class="form-control" />
                <span asp-validation-for="MyEntity.Prop" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>
<div id="mydiv"></div>

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-ajax-unobtrusive/jquery.unobtrusive-ajax.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

<script>
    function success() {
        console.log("success")
    }
    fail=function (response) {
        console.log("fail")
       
        var newDoc = document.open("text/html", "replace");
        newDoc.write(response.responseText);
        newDoc.close();
    }
</script>

结果:enter image description here

评论

0赞 s15199d 7/28/2023
谢谢!BadRequest() 阻止了触发,但我没有像我预期的那样显示。对那件作品有什么建议吗?data-ajax-success<span asp-validation-for="ProductAlias.ProductAliasName" class="text-danger"></span>
0赞 Ruikai Feng 7/31/2023
嗨,@ S15199D ,请检查我更新的内容,这是你想要的吗?
0赞 Qing Guo 7/31/2023 #2

我希望视图保持在原地,并且不显眼的验证 显示<span asp-validation-for="ProductAlias.ProductAliasName" class="text-danger"></span>

在表单有效之前,客户端验证会阻止提交。“提交”按钮运行 JavaScript,用于提交表单或显示错误消息。

您可以添加以下代码:

    <p>
    ProductAlias.ProductAliasName:
    <input asp-for="ProductAlias.ProductAliasName" data-val-required="This is required." data-val= "true"/>
    @*<span asp-validation-for="ProductAlias.ProductAliasName" class="text-danger"></span>*@
    <span data-valmsg-for="ProductAlias.ProductAliasName"
          data-valmsg-replace="true" 
                      style="margin-left: 75px; color: red;" />
   </p>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.12/jquery.validate.unobtrusive.js"></script>

结果:enter image description here

您可以阅读客户端验证以了解更多信息。