使用剃须刀页面调用服务器方法而无需重新加载页面

Posted

技术标签:

【中文标题】使用剃须刀页面调用服务器方法而无需重新加载页面【英文标题】:Call server method without page reload with razor page 【发布时间】:2019-08-27 03:46:07 【问题描述】:

在我的 .net core razor 页面项目中,我想从 cshtml 输入调用服务器端方法,而无需重新加载页面。我仍然是剃刀页面的新手。

.cshtml : 

input type="submit" id="AddCart" asp-page-handler="AddToCart" hidden

Some JS to .click() the input.

.cs :
public async void OnPostAddToCart()

//code

到目前为止,我还没有找到阻止页面重新加载并仍然访问我的服务器端方法的方法。

谢谢

编辑: 查看 brad 提供的链接,我设法使它工作。

我添加了@Page "handler?" 来编写没有处理程序的 url(不确定它是否对 ajax 重要), 我将我的 ajax url 设置为“thePage/theMethod”, 我用 [ValidateAntiForgeryToken] 装饰了我的剃须刀控制器类 并提到了ajax中的防伪令牌:

$.ajax(
                url: "/mainPage/AddToCart",
                type: "POST",
                contentType: "application/json; charset=utf-8",
                beforeSend: function (xhr) 
                    xhr.setRequestHeader("XSRF-TOKEN",
                        $('input:hidden[name="__RequestVerificationToken"]').val());
                ,
                success: function () 
                    alert("success");
                ,
                complete: function () 
                    alert("complete")
                ,
                failure: function () 
                    alert("failure");
                
            );

【问题讨论】:

目前仅靠 razor 页面无法做到这一点,您必须使用 AJAX。 或者你可以试试Blazor,如果你有足够的勇气使用最前沿的实验框架;) 请参阅***.com/questions/46410716/… 了解有关回调剃须刀页面的更多信息 【参考方案1】:

首先,更改 Handler 方法的命名,如下所示:

 public async void OnPostAddToCartAsync()
    
        //code
    

有关命名约定的更多详细信息,请参阅Handler Methods in Razor Pages。

其次,如果你想在 Razor Pages 中使用 ajax,URL 模式应该类似于“/mainPage?handler=AddToCart”。需要注意的一点是,Razor Pages 旨在防止 (CSRF/XSRF)攻击。因此,防伪令牌生成和验证自动包含在 Razor 页面中。我相信这就是这里的问题。如果您的 HTML 中有表单标签,则您的页面上可能存在防伪令牌。但是您需要在 Ajax 请求中传递相同的内容。

如果没有,则使用 @Html.AntiForgeryToken() 添加防伪令牌 存在。

修改您的 Ajax 请求以在请求标头中发送相同的内容,例如 下面:

<input type="button" id="AddCart"  onclick="clickbtn()" value="Submit"/>
function clickbtn() 
    $.ajax(
        url: "/Test?handler=AddToCart",
        type: 'POST',
        beforeSend: function (xhr) 
            xhr.setRequestHeader("X-XSRF-TOKEN",
                $('input:hidden[name="__RequestVerificationToken"]').val());
        ,
        success: function ()
        
            alert("success");
        ,
        complete: function ()
        
            alert("complete")
        ,
        failure: function ()
        
            alert("failure");
        
    );

由于脚本在名为 X-XSRF-TOKEN 的标头中发送令牌, 配置防伪服务以查找 X-XSRF-TOKEN 标题:

services.AddAntiforgery(option => option.HeaderName = "X-XSRF-TOKEN");

阅读这篇文章Handle Ajax Requests in ASP.NET Core Razor Pages,了解更多关于使用 ASP.NET Core razor 页面发出 ajax 请求的信息。

【讨论】:

【参考方案2】:

如果您不想重新加载页面,则必须使用ajaxXMLHttpRequest,(前者基于后者)。

<script>
window.onload=function()

  window.click=function()
  
        $.ajax(  
            url: '[baseUrl/OnPostAddToCart]',  
            data: JSON.stringify(postData), //your data 
            type: 'POST',  
            contentType: 'application/json',  
            dataType: 'json',  

            success: function (result)   
                alert(result);  //do something if successful
            ,  
            complete: function()  
                 //do something on complete
            ,  
            failure: function (err)                   
                alert(err); // Display error message  
              
        );
   

</script>
<input  onclick="click()" type="button"/>

使用XMLHttpRequest

window.click=function()

var xhr = new XMLHttpRequest();
xhr.open("POST", "[Your URL]");
xhr.onload=function()

  if(xhr.status==200)
    resolve(xhr.response);
  else
    reject("error:"+xhr.status);

var data=JSON.stringify(some_data);
xhr.send(data);

控制器方法

 public class MyController:Controller
 
    [HttPost]
    [Route("/OnPostAddToCart")]
    public async Task AddToCart(object data)
    

    
 

P.S欲了解更多信息ajax

【讨论】:

感谢您的帮助。我仍然无法使用这个 ajax 访问我的 AddToCart 方法: $.ajax( url: "/mainPage?handler=AddToCart", type: 'POST', success: function () alert("success"); ,完成:函数()警报(“完成”),失败:函数()警报(“失败”););我收到“完成”警报。 您需要指定完整的url 才能访问您的服务器。找出您的服务器正在运行的hostnameport 并将您的url 属性设置为:@ 987654335@ AddToCart 方法在 mainPage razor 页面中。如果我使用 input id="AddCart" type="submit" asp-page-handler="AddToCart",我会到达该方法,并且在执行代码后,我的 url 是localhost:XXXXX/mainPage?handler=AddToCart。我尝试将 url 属性设置为:localhost:55318/mainPage?handler=AddToCart;或localhost:55318/mainPage/OnPostAddToCart 没有成功。 如果您想从您的controller 访问method,您必须将网址设置为[baseurl]/[controller-method] 并使用controller method 装饰您的controller method 属性,就像我在上面所做的那样例子。 感谢您的帮助阿德里安。查看您的 Controller 方法,您无法使用 route 和 HttPost 属性装饰 razor 页面处理程序方法。

以上是关于使用剃须刀页面调用服务器方法而无需重新加载页面的主要内容,如果未能解决你的问题,请参考以下文章

从 javascript POST 重新加载剃须刀页面

在后台发送论坛而无需重新加载页面

添加到浏览器历史记录而无需重新加载页面

同时使用time.sleep()循环而无需重新加载页面

更改 url 并更新页面内容而无需重新加载

更改 url 而无需重新加载页面