首页 文章

ASP.NET Core 2,使用没有MVC的Razor页面单击按钮

提问于
浏览
3

正如有人在评论中指出的那样,Razor页面不像你以前在MVC那样需要控制器 . 我现在也是Razor没有按钮点击事件的原生处理 . 要在用户单击按钮时执行某些操作(在“代码隐藏”中),我们至少有两个选项:

  • 使用提交按钮

  • 使用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 class TestModel:PageModel {private readonly 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#函数 . 但我不明白如何处理多个按钮 . 即如果我有5个按钮,如何为每个按钮做一些不同的事情?

  • 使用“Way2”我做错了,因为cs代码中的函数永远不会到达,我收到错误请求错误(400) . 我错过了什么?

1 回答

  • 4

    Normal form submit

    在执行普通表单提交时,按照约定,您需要处理程序方法名称遵循 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 . 当用户点击提交按钮时,它会发布此网址的表单,因为格式属性值将覆盖表单的默认操作网址 . 收到请求后,剃刀页面框架将使用此参数( handler )并将请求定向到相应的处理程序方法 .

    Ajax call

    您收到400(错误请求)响应,因为框架期望 RequestVerificationToken 作为已发布请求数据的一部分 . 如果检查页面的视图源,则可以在表单中看到名为 __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 的input元素并读取它的值 . 更强大的方法是将 IAntiforgery 实现注入视图并使用 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>
    

相关问题