Unobtrusive Ajax与不显眼的验证

huangapple go评论72阅读模式
英文:

Unobtrusive Ajax w/ Unobtrusive Validation

问题

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

当我提交带有空文本框的表单时,如预期的那样,我得到了ModelState.IsValid = False。但是,表单仍然触发了data-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();
}

IsValid检查中的第一个return Page();处停止了执行。

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

注意:我之前在data-ajax-complete中使用了refreshPartial回调,结果相同...所以我将它移到了data-ajax-success,以为这会解决这个问题。

英文:

I have a form with a single textbox. The field bound to that textbox is required.

When I post the form with that textbox empty I get ModelState.IsValid = False as expected. But, the form still fires the data-ajax-success.

Relevant .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">

Relevant .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();
}

It's hitting that first return Page(); inside that Isvalid check.

How do I prevent the data-ajax-success callback from firing when ModelState.IsValid = false?

Note: I previously had the refreshPartial callback in the data-ajax-complete with the same result...so I moved it to data-ajax-success thinking that'd be the solution to this issue.

答案1

得分: 1

以下是您要翻译的部分:

"Return Page() would always return response with 200 statue code in your senaro,if you want fire data-ajax-success when modelstate is invalid,you should return response with 400 statuecode"

"A minimal example,hopes help:"

"PageModel:"

"Page:"

"Result:"

"Update based on your comment:"

"If you've passed client validation(in my case,null check) and got model state error on server(for example,duplicated Name)"

"If you want to show the errors ,you have to refresh the page yourself due to ajax call"

"My solution:"

"PageModel:"

"Page:"

"Result:"

英文:

Return Page() would always return response with 200 statue code in your senaro,if you want fire data-ajax-success when modelstate is invalid,you should return response with 400 statuecode

A minimal example,hopes help:

PageModel:

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:

@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>

Result:

Unobtrusive Ajax与不显眼的验证

Update based on your comment:

If you've passed client validation(in my case,null check) and got model state error on server(for example,duplicated Name)

If you want to show the errors ,you have to refresh the page yourself due to ajax call

My solution:

create a filter:

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;
            }
        }
    }

PageModel:

[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:

@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>

Result:
Unobtrusive Ajax与不显眼的验证

答案2

得分: 0

我希望视图保持不变,并显示<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 data-valmsg-for="ProductAlias.ProductAliasName" data-valmsg-replace="true" style="margin-left: 75px; color: red;"></span>
</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>

结果:

Unobtrusive Ajax与不显眼的验证

您可以阅读客户端验证以获取更多信息。

英文:

> I'm wanting the view to stay put and the unobtrusive-validation to
> show the &lt;span asp-validation-for=&quot;ProductAlias.ProductAliasName&quot;
&gt; class=&quot;text-danger&quot;&gt;&lt;/span&gt;

Client-side validation prevents submission until the form is valid. The Submit button runs JavaScript that either submits the form or displays error messages.

You can add below code :

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

Result:
Unobtrusive Ajax与不显眼的验证

You can read Client-side validation to know more.

huangapple
  • 本文由 发表于 2023年7月27日 22:44:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76780902.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定