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

Posted

技术标签:

【中文标题】从 javascript POST 重新加载剃须刀页面【英文标题】:Reload razor page from javascript POST 【发布时间】:2021-09-01 15:34:00 【问题描述】:

我有一个显示一些表格和统计信息的 asp.net 仪表板页面,以及一个带有一些复选框和日期范围选择器的过滤器面板。每当单击复选框时,我都会编写 jQuery 来触发。 jQuery 使用 Ajax POST 将过滤器设置发送到控制器,然后控制器查询数据库、应用过滤器设置、创建新页面模型并将其发送到视图。在这一点上,我希望新创建的剃刀视图和浏览器显示一个新呈现的页面,但没有任何变化,我在控制台中收到 500 错误,可能是因为控制器没有发送适当的响应。有没有更好的方法来实现我想要做的事情?

数据已成功到达控制器,并且正在正确创建新页面模型。在这之后我不知道该怎么做。

javascript

function sendFilterData() 

            var checks = getFilterSettings(); //stringified JSON

            $.ajax(
                method: 'POST',
                url: '@Url.Action("ApplyDashboardFilter", "Home")',
                data: 
                    checks: checks, start: globalstart.format("YYYY-MM-DD HH:mm:ss"), end: globalend.format("YYYY-MM-DD HH:mm:ss") ,
                success: function (response) 
                    //???
                ,
                failure: function (response) 
                    console.log(response);
                
            );
        

C#

public IActionResult ApplyDashBoardFilter(string checks, DateTime start, DateTime end)

    var filters = JsonConvert.DeserializeObject<List<FilterItem>>(checks);
    ViewModel vm = new ViewModel();
    foreach(var f in filters)
    
        vm.AddFilter(f);      
    
    vm.StartDate = start;
    vm.EndDate = end;

    return Dashboard(vm);

 
public IActionResult Dashboard(ViewModel model)

    //Get data and apply filters
     return View(model);

【问题讨论】:

【参考方案1】:

在 MVC 中,当使用“手动”AJAX 调用“跳过”回发时,不会启动刷新/更新页面上的 html 的进程。发出手动 AJAX 请求时,它不会返回视图,而是返回对 AJAX 请求的响应(如您在代码示例中所见)。该响应接收更新页面所需的数据,而无需完整的回发/页面刷新。由于这是手动 AJAX 请求,因此必须使用响应中返回的 JSON 数据对页面的 HTML 进行使用 JavaScript 的手动更新。

这与使用 WebAPI 控制器操作非常相似(您发送请求,然后它发送响应)。

由于这是一个发布动作,最好将 [HttpPost] 注释添加到控制器动作中。您的数据对象应作为 JSON 对象返回给您的 AJAX 请求。

[HttpPost]
public IActionResult ApplyDashBoardFilter(string checks, DateTime start, DateTime end)

    var filters = JsonConvert.DeserializeObject<List<FilterItem>>(checks);
    ViewModel vm = new ViewModel();
    foreach(var f in filters)
    
        vm.AddFilter(f);      
    
    vm.StartDate = start;
    vm.EndDate = end;

    return Dashboard(vm);

请注意,AJAX 请求“成功”函数接收一个响应参数。此参数应接收控制器创建的 JSON 数据。使用此 JSON 数据和必要的 JavaScript 来更新页面的 HTML。

function sendFilterData() 

            var checks = getFilterSettings(); //stringified JSON

            $.ajax(
                method: 'POST',
                url: '@Url.Action("ApplyDashboardFilter", "Home")',
                data: 
                    checks: checks, start: globalstart.format("YYYY-MM-DD HH:mm:ss"), end: globalend.format("YYYY-MM-DD HH:mm:ss") ,
                success: function (response) 
                    //place JavaScript to update your page's HTML here
                    console.log(response) //use this to test your JSON 
                ,
                failure: function (response) 
                    console.log(response);
                
            );
        

【讨论】:

感谢您的解释。由于在后端完成了大量的数据处理,因此用 JavaScript 更新页面是没有意义的。我最终将复选框添加到页面的表单中,并在单击它们时使用 jQuery 提交表单。【参考方案2】:

我认为最好的方法是在应用过滤器后可以使用部分视图来渲染视图。

    在主视图中添加带有 id 的 div:

    创建仪表板该部分的部分视图并从控制器返回。所以不是

     public IActionResult ApplyDashBoardFilter(string checks, DateTime start, 
     DateTime end)
     
         var filters = JsonConvert.DeserializeObject<List<FilterItem>>(checks);
         ViewModel vm = new ViewModel();
         foreach(var f in filters)
         
             vm.AddFilter(f);      
         
          vm.StartDate = start;
          vm.EndDate = end;
          return Dashboard(vm);
      
    

你可以写

    public IActionResult ApplyDashBoardFilter(string checks, DateTime start, DateTime end)
    
        var filters = JsonConvert.DeserializeObject<List<FilterItem>>(checks);
        ViewModel vm = new ViewModel();
        foreach(var f in filters)
        
           vm.AddFilter(f);      
        
        vm.StartDate = start;
        vm.EndDate = end;    
        return PartialView("_DashboardPartial", vm);

    在ajax的成功方法中,将部分视图添加到主视图的div中:

     function sendFilterData() 
    
         var checks = getFilterSettings(); //stringified JSON
    
         $.ajax(
             method: 'POST',
             url: '@Url.Action("ApplyDashboardFilter", "Home")',
             data: 
                 checks: checks, start: globalstart.format("YYYY-MM-DD HH:mm:ss"), end: globalend.format("YYYY-MM-DD HH:mm:ss") ,
             success: function (response) 
                 $("#DashboardFilter").html(response)
             ,
             failure: function (response) 
                 console.log(response);
             
         );
     
    

提示:您可以在 DashboardPartial div 中显示加载程序,直到 ajax 方法未完成。

【讨论】:

以上是关于从 javascript POST 重新加载剃须刀页面的主要内容,如果未能解决你的问题,请参考以下文章

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

在 .Net Core 3.1 上发布时未使用新 ViewModel 重新加载表单

如何将两个数组作为 POST 请求参数从 AJAX 发送到 MVC 控制器(ASP .NET Core 3.1 剃须刀)?

从 Blazor 中的剃须刀页面加载完整日历?

根网址 javascript

将剃须刀模型转换为 JS 对象属性为空