【问题标题】:How to show Validation Summary in a modal form with ajax post method?如何使用 ajax post 方法以模态形式显示验证摘要?
【发布时间】:2020-11-11 06:19:53
【问题描述】:

我是 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按钮效果很好,modelstate有效时Create按钮效果很好。但是当模型状态无效时,它会进入一个错误页面(Hello world!),我看到 1 秒钟的验证错误,但浏览器打开了一个错误的页面,并且没有停留在显示验证错误的模式上。

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

请帮帮我,我怎样才能改变上面的代码来解决这个问题?

【问题讨论】:

    标签: ajax asp.net-core


    【解决方案1】:

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

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

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

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

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

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

    结果:

    【讨论】:

    • 感谢您的帮助。但是注册视图本身就是一个模态。而且我不想打开另一个模式。在您的示例中,注册视图是一个完整视图。
    • 当我测试你的建议代码时,isValid 值总是假的! (在我的代码中,注册视图是模态视图)
    【解决方案2】:

    https://stackoverflow.com/users/11965297/mj1313 鼓舞人心的帮助下,我改变了我的代码,如下所示,我的问题完全解决了......

    在控制器中,我通过 ViewBag 向我的视图发送一个参数(有效),以指定 ModelState 的有效性状态。

    [HttpPost]
    public IActionResult Register(RegisterViewModel register)
    {
        if (ModelState.IsValid)
        {
            if (_iuser.isUsernameExist(register.Username))
            {
                ViewBag.Valid= "1"; // It's part of my change
                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);
                ViewBag.Valid= "0"; // It's part of my change
                string TabName = "UserTab";
                return Json(new { redirectToUrl = Url.Action("Index", "Profile", new {TabName}) });
            }
        }
        else
        {
            ViewBag.Valid= "1"; // It's part of my change
            return PartialView(register);
        }
    }
    

    在我看来,我使用隐藏输入来保存 ViewBag。

    <form asp-action="Register">
    
        <input name="IsValid" type="hidden" value="@ViewBag.Valid" /> @*It's part of my change*@
        
        <div asp-validation-summary="ModelOnly" class="text-danger text-right"></div>          
        <div class="form-group">
            <input asp-for="Username" class="form-control" , placeholder="username" 
        </div>
         .....
    </form>
    

    最后,我改变了Ajax功能,成功部分:

    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();
                if (isValid) {
                     $('#myModal').modal('show');
                 } else {
                     window.location.href = response.redirectToUrl;
                 }           
           }
     }).done(function (result) {
          $('#myModal').modal('show');
          $('#bodyModal').html(result);
     });}
    

    【讨论】:

      猜你喜欢
      • 2017-05-09
      • 2014-03-15
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多