首页 > 解决方案 > 如何使用 ajax post 方法以模态形式显示验证摘要?

问题描述

我是 ASP.NET Core MVC 的初学者。我的网站代码有问题。

我的模型User有一些字段,我根据这些字段编写了一个视图模型。

我编写了以下代码:

我的视图模型RegisterViewModel::

public class RegisterViewModel
{
    [Display(Name = "Username")]
    [Required(ErrorMessage = "Enter {0} value please.")]
    [MaxLength(20, ErrorMessage = "{0} Shouldn't have more than {1} Characters")]
    public string Username { get; set; }
    
    [Display(Name = "Password")]
    [Required(ErrorMessage = "Enter {0} value please.")]
    [MaxLength(50, ErrorMessage = "{0} Shouldn't have more than {1} Characters")]
    public string Password { get; set; } 
}

我的控制器AccountController

public class AccountController : Controller
{
    private IUser _iuser;

    public AccountController(IUser iuser)
    {
        _iuser = iuser;
    }

    public IActionResult Register()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Register(RegisterViewModel register)
    {
        if (ModelState.IsValid)
        {
            if (_iuser.isUsernameExist(register.Username))
            {
                ModelState.AddModelError("UserName", "This User Exists!");
                return PartialView(register);
            }
            else
            {
                User user = new User()
                {
                    Username = register.Username,
                    Password = HashGenerators.EncodingPassWithMD5(register.Password),
                    RoleId = 2,
                };

                _iuser.AddUser(user);
                string TabName = "UserTab";
                return Json(new { redirectToUrl = Url.Action("Index", "Profile", new {TabName}) });
            }
        }
        else
        {
            return PartialView(register);
        }
    }
}

注册操作有一个显示为模式的视图。

查看Register.cshtml

<div class="row">
<div class="col-md-8 col-md-offset-2">
    <hr />
    <form asp-action="Register">
        <div asp-validation-summary="ModelOnly" class="text-danger text-right"></div>          
        <div class="form-group">
            <input asp-for="Username" class="form-control" , placeholder="username" id="txtUsername"/>
            <span asp-validation-for="Username" class="text-danger" id="ValidationSummery"></span>
        </div>
        <div class="form-group">
            <input asp-for="Password" class="form-control" , placeholder="password" id="txtPassword"/>
            <span asp-validation-for="Password" class="text-danger text-right" id="ValidationSummery"></span>
        </div>
        <div class="form-group">
            <input type="button" value="Create" onclick='AddUser()' class="btn-red pull-left" />
            <button href="#" type="button" onclick='ClearForm()' class="btn-red pull-right"> Clear Form </button>
        </div>
    </form>
</div>
</div>

模态代码(在上面代码的末尾):

<div id="myModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
    <div class="modal-content">
        <div id="bodyModal" class="modal-body">
        </div>
    </div>
</div>
</div>

最后,我有这些 Ajax 脚本:

<script>
function ClearForm() {
    $.ajax({
        url: "/Account/Register/",
        type: "Get",
        data: {}
    }).done(function (result) {
        $('#myModal').modal('show');
        $('#bodyModal').html(result);
    });
    $('#myModal').modal('dispose'); }
</script>
<script>
function AddUser() {
$.ajax({
    url: "/Account/Register/",
    type: "Post",
    data: {
        Username: $("#txtUsername").val(),
        Password: $("#txtPassword").val(),
    },
    success: function (response) {
        window.location.href = response.redirectToUrl;
    }
}).done(function (result) {
    $('#myModal').modal('show');
    $('#bodyModal').html(result);
});}
</script>

程序运行时,ClearForm按钮工作正常,Createmodelstate有效时按钮工作正常。但是当模型状态无效时,它会进入一个错误页面(Hello world!),我看到 1 秒钟的验证错误,但浏览器打开了一个错误的页面,并且没有停留在显示验证错误的模式上。

注意:当我在成功部分从 ajax AddUser 函数中删除:( window.location.href = response.redirectToUrl;) 时,模式保持打开状态并显示验证错误。但如果模型状态有效,模式保持打开状态,但它是空的,并且目标页面(索引/配置文件#用户标签)不显示。

请帮助我,我该如何更改上面的代码来解决这个问题?

标签: ajaxasp.net-core

解决方案


我认为您可以有一个新的局部视图来显示验证消息。

在局部视图中添加一个隐藏的输入字段:

<input name="IsValid" type="hidden" value="@ViewData.ModelState.IsValid.ToString()" />

然后在ajax成功函数中通过判断的值来判断是显示modal还是redirectIsValid

基于您的代码的简单演示。

注册.cshtml:

@model RegisterViewModel
@{
    ViewData["Title"] = "Register";
}

<h1>Register</h1>

<div class="row">
    <div class="col-md-8 col-md-offset-2">
        <hr />
        <form asp-action="Register">
            <div asp-validation-summary="ModelOnly" class="text-danger text-right"></div>
            <div class="form-group">
                <input asp-for="Username" class="form-control" , placeholder="username" id="txtUsername" />
                <span asp-validation-for="Username" class="text-danger" id="ValidationSummery"></span>
            </div>
            <div class="form-group">
                <input asp-for="Password" class="form-control" , placeholder="password" id="txtPassword" />
                <span asp-validation-for="Password" class="text-danger text-right" id="ValidationSummery"></span>
            </div>
            <div class="form-group">
                <input type="button" value="Create" onclick='AddUser()' class="btn-red pull-left" />
                <button href="#" type="button" onclick='ClearForm()' class="btn-red pull-right"> Clear Form </button>
            </div>
        </form>
    </div>
</div>

<div id="myModal" class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div id="bodyModal" class="modal-body">
            
            </div>
        </div>
    </div>
</div>

@section scripts{

    <script>
        function AddUser() {
            $.ajax({
                url: "/Account/Register/",
                type: "Post",
                data: {
                    Username: $("#txtUsername").val(),
                    Password: $("#txtPassword").val(),
                },
                success: function (response) {
                    $('#bodyModal').html(response);
                    var isValid = $('body').find('[name="IsValid"]').val() == 'True';
                    if (!isValid) {
                        $('#myModal').modal('show');
                    } else {
                        window.location.href = "@Url.Action("Index", "Profile")";
                    }
                
                }
            });
        }
    </script>
}

_Register.cshtml(部分视图):

@model RegisterViewModel

<form asp-action="Register">
    <input name="IsValid" type="hidden" value="@ViewData.ModelState.IsValid.ToString()" />
    <div asp-validation-summary="ModelOnly" class="text-danger text-right"></div>
    <div class="form-group">
        <input asp-for="Username" class="form-control" , placeholder="username" id="txtUsername" readonly />
        <span asp-validation-for="Username" class="text-danger" id="ValidationSummery"></span>
    </div>
    <div class="form-group">
        <input asp-for="Password" class="form-control" , placeholder="password" id="txtPassword" readonly />
        <span asp-validation-for="Password" class="text-danger text-right" id="ValidationSummery"></span>
    </div>
</form>

控制器:

public class AccountController : Controller
{
    public IActionResult Register()
    {
        
        return View();
    }

    [HttpPost]
    public IActionResult Register(RegisterViewModel register)
    {
        if (ModelState.IsValid)
        {
            // do some stuff
        }

        return PartialView("_Register",register);
        
    }
}

结果:

在此处输入图像描述


推荐阅读