【问题标题】:Razor pages model binding with and without model name带有和不带有模型名称的 Razor 页面模型绑定
【发布时间】:2020-08-11 09:39:24
【问题描述】:

我有一个旨在实现联系表单的 ASP.NET 2.0 Razor 页面。这是 Contact.cshtml 文件的一部分:

@page
@model ContactModel
<form method="post">
    <input type="text" asp-for="ContactMessageModel.Name" />
    <input type="email" asp-for="ContactMessageModel.Email" />
    <input type="text" asp-for="ContactMessageModel.Message" />
    <div class="g-recaptcha" data-sitekey="<SiteKey>"></div>
    <button type="submit" class="btn btn-primary">Send</button>
</form>

这是 Contact.cshtml.cs 文件的一部分:

public class ContactModel : PageModel
{
    [BindProperty]
    public ContactMessageModel ContactMessageModel { get; set; }

    public IActionResult OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        return RedirectToPage("MessageSent");
    }
}

public class ContactMessageModel
{
    [Required]
    public string Name { get; set; }

    [Required]
    public string Email { get; set; }

    [Required]
    public string Message { get; set; }

    [Required, BindProperty(name="g-recaptcha-response"]
    public string RecaptchaResponse { get; set; }
}

表单提交时,请求中出现如下表单数据:

ContactMessageModel.Name: Fractor
ContactMessageModel.Email: fractor@example.com
ContactMessageModel.Message: Hi there!
g-recaptcha-response: <recaptcha response data>

由于动态创建的g-recaptcha-response表单数据名称不以ContactMessageModel开头,所以只绑定了Name、Email和Message属性。

我看过使用 [Bind(Prefix = "")],但看起来我无法将其应用于类中的(单个)属性。

有没有办法绑定到这个模型类中的所有属性,尽管前缀不同?

【问题讨论】:

    标签: asp.net-core razor-pages


    【解决方案1】:

    编辑

    可以在视图中创建a hidden control绑定RecaptchaResponse,并通过触发机器人的data-callback事件,将响应值传递给js中的隐藏控件。

        <form method="post">
            <input type="text" asp-for="ContactMessageModel.Name" />
            <input type="email" asp-for="ContactMessageModel.Email" />
            <input type="text" asp-for="ContactMessageModel.Message" />
            <div class="g-recaptcha" data-sitekey="your key" data-callback="ClickRobot"></div>
            <input type="hidden" asp-for="ContactMessageModel.RecaptchaResponse" />
            <button type="submit" class="btn btn-primary">Send</button>
        </form>
    
    <script src="https://www.google.com/recaptcha/api.js?hl=en-US"></script>
    <script src="https://code.jquery.com/jquery-3.5.0.js"></script>
    <script>
        var ClickRobot = function () {
            var response = grecaptcha.getResponse();
            $("#ContactMessageModel_RecaptchaResponse").val(response);
        };
    </script>
    

    联系方式:

     public class ContactModel : PageModel
        {
            [BindProperty]
            public ContactMessageModel ContactMessageModel { get; set; }
            public IActionResult OnPostAsync()
            {  
                if (!ModelState.IsValid)
                {
                    return Page();
                }
    
                return RedirectToPage("MessageSent");
            }
        }
    
        public class ContactMessageModel
        {
            [Required]
            public string Name { get; set; }
    
            [Required]
            public string Email { get; set; }
    
            [Required]
            public string Message { get; set; }
    
            [Required]
            public string RecaptchaResponse { get; set; }
        }
    

    测试过程如下:

    【讨论】:

    • 即使视图中没有对应的元素,表单数据也可以绑定属性。请参阅这篇文章中的SomeData 属性,如果表单数据中存在相应的值,则该属性会被绑定。只是由于某种原因无法验证。 stackoverflow.com/questions/61465796/…
    • @fractor,我修改了我的答案。可以使用g-recaptcha的data-callback事件获取client端验证的返回值,并绑定到RecaptchaResponse字段。
    • 谢谢您,感谢您为提供与此问题相关的信息所做的努力。但是,对于最初的问题“有没有办法绑定到这个模型类中的所有属性,尽管前缀不同?”,我们没有答案。
    猜你喜欢
    • 2020-07-02
    • 2019-03-12
    • 2021-10-07
    • 2021-03-07
    • 2013-09-04
    • 2021-10-13
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多