正如某人在评论中指出的那样,Razor页面不需要 Controller ,就像您以前在MVC中那样。我现在也 Razor 没有按钮单击事件的 native 处理。为了在用户单击按钮时执行某些操作(在“隐藏代码”中),我们至少有两个选择:

  • 使用提交按钮
  • 使用ajax调用

  • 我找到了许多MVC示例,它们展示了如何定义Controller功能。但是正如我所说,我没有一个。

    因此,我试图理解这两种方式。这是我的测试cshtml:
    <form method="post">
        <input type="submit" class="btn btn-primary" value="way1">Way 1/>
    </form>
    
    <button id="btn" type="button" class="btn btn-primary" value="way2">Way 2</button>
    
    <script>
    $(document).ready(function() {
        $("#btn").click(function (e) {
            e.preventDefault();
            $.ajax({
                url: "@Url.Action("Way2")",
                type: "POST",
                data: "foo",
                datatype: "text",
                success: function (data) {
                    alert(data);
                }
            });
            return false;
        });
    });
    </script>
    

    这里是cshtml.cs:

    公共(public)类TestModel:PageModel
    {
    私有(private)只读MyContext _context;
    public TestModel(MyContext context)
    {
        _context = context;
    }
    
    public IActionResult OnPost()
    {
        // here I can put something to execute
        // when the submit button is clicked
    }
    
    public ActionResult Way2(string data)
    {
        // this is never triggered
    }
    

    问题
  • 使用“Way1”(提交),我可以捕捉按钮的点击,但是有一些缺点。默认情况下,由于帖子的缘故,页面被重新加载。有时我不需要更改任何内容,而只需调用C#函数。但是我不明白如何处理多个按钮。 IE。如果我有5个按钮,每个按钮该怎么做?
  • 使用“Way2”时,我做错了一些事情,因为CS代码中的函数从未到达,并且出现Bad Request错误(400)。我错过了什么?
  • 最佳答案

    普通格式提交

    进行常规表单提交时,按照约定,您需要处理程序方法名称以遵循On{{HttpVerb}}{{YourHanderName}}格式

    public ActionResult OnPostWay2(string data)
    {
        // to do : return something
    }
    

    现在,请确保您在form标记内包含了提交按钮,并且提到了asp-page-handler。该属性的值应该是页面模型类(Way2)中的处理程序名称。
    <form method="POST">
        <button type="submit" asp-route-data="foo" asp-page-handler="Way2">Way 2</button>
    </form>
    

    上面的代码将生成一个带有 formaction attribute的按钮标记,该标记设置为url yourBaseUrl/YourPageName?data=foo&handler=Way2
    当用户单击“提交”按钮时,它将在表单中发布此url,因为formaction属性值将覆盖表单的默认操作url。收到请求后, Razor 页面框架将使用此参数(handler)并将请求定向到相应的处理程序方法。

    Ajax调用

    由于框架希望RequestVerificationToken作为已发布的请求数据的一部分,因此您将收到400(错误请求)响应。如果检查页面的查看源,则可以在表单内部看到一个名称为__RequestVerificationToken的隐藏输入元素。框架使用它来防止可能的CSRF攻击。如果您的请求没有此信息,则框架将返回400错误的请求。

    为了使您的ajax代码能够正常工作,您要做的就是明确地发送此代码。这是一个工作样本
    $("#btn").click(function(e) {
        e.preventDefault();
    
        var t = $("input[name='__RequestVerificationToken']").val();
        $.ajax({
            url: $(this).attr("formaction"),
            headers:
            {
                "RequestVerificationToken": t
            },
            type: "POST",
            data: { data: 'foo2' },
        }).done(function(data) {
            console.log(data);
        }).fail(function(a, v, e) {
            alert(e);
        });
    });
    

    现在,由于您正在进行ajax调用,因此返回json响应很有意义
    public ActionResult OnPostWay2(string data)
    {
        return new JsonResult("Received "+ data + " at "+DateTime.Now);
    }
    

    在上面的示例中,我们使用一些jQuery代码获取名称为__RequestVerificationToken的输入元素并读取其值。一种更可靠的方法是将IAntiforgery实现注入(inject) View 并使用GetAndStoreTokens方法。
    @inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
    @functions{
        public string GetAntiXsrfRequestToken()
        {
            return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
        }
    }
    <script>
         $(function () {
    
             $("#btn").click(function(e) {
                 e.preventDefault();
                 var t = '@GetAntiXsrfRequestToken()';
                 $.ajax({
                          url: $(this).attr("formaction"),
                          headers:
                          {
                              "RequestVerificationToken": t
                          },
                          type: "POST",
                          data: { data: 'foo2' },
                 }).done(function(data) {
                         console.log(data);
                 }).fail(function(a, v, e) {
                         alert(e);
                 });
             });
        })
    </script>
    

    关于c# - ASP.NET Core 2,在没有MVC的Razor页面上单击按钮,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47459793/

    10-12 00:25
    查看更多