在 Razor 页面中更新图表的值

Updating values of a chart in a razor page

提问人:Daniel Scerpa 提问时间:11/4/2023 最后编辑:wenbingeng-MSFTDaniel Scerpa 更新时间:11/13/2023 访问量:140

问:

我在 Visual Studio 2019 中创建了一个 Asp Net Razor 项目。

我正在通过一些练习来学习这项技术。具体来说,我想在页面上显示一个图表,我想通过 ApiController 检索其数据。

   [Route("api/[controller]")]
    [ApiController]
    public class AjaxAPIController : ControllerBase
    {
        public ChartData chartData = new ChartData();

        [HttpGet]
        [Route("ChartDataJson")]
        public IActionResult ChartDataJson()
        {
            // First example
            var x = new List<double> { 1.0,};
            var y = new List<double> { 10.0,};
            var chartData = new { x, y };
            return Ok(chartData);
        }

        [HttpGet]
        [Route("ChartDataJson2")]
        public IActionResult ChartDataJson2()
        {
            // Second Example
            var x = new List<double> {1.0, 20.0, 30.0 };
            var y = new List<double> {2.0, 30.0,  45.0};
            var chartData = new { x, y };
            return Ok(chartData);
        }

        [HttpPost]
        [Route("UpdateChartData")]
        public IActionResult UpdateChartData([FromBody] ChartData data)
        {
            // Read received data
            var newDataX = data.X; 
            var newDataY = data.Y;
            var chartData = new { x = new List<double>[] { newDataX }, y = new List<double>[] { newDataY } };
            return Ok(chartData);
        }
    }

图表的值可以通过 3 种不同的方式更新:

  1. 点击按钮1:用固定值更新图表的值;(获取)
 //  When the button 1 is clicked, get  data from the controller and update the chart
        $("#btnGet").click(function () {
            console.log("button 1 click is executed.");
            $.get("/api/AjaxAPI/ChartDataJson", function (data) {
                updateScatterChart(data);
            });
        });
  1. 单击按钮 2:与点 1 相同,但值不同;(获取)
         //  When the button 2 is clicked, get  data from the controller and update the chart
        $("#btnGet2").click(function () {
            console.log("button 2 click is executed.");
            $.get("/api/AjaxAPI/ChartDataJson2", function (data) {
                updateScatterChart(data);
            });
        });
  1. 呼叫帖子:当我从外部收到带有 json 格式数据的帖子呼叫时。(邮政)
        // Update the data chart when a post request is received
        $.post("/api/AjaxAPI/UpdateChartData", function (data) {
            console.log("X values:", data.x);
            console.log("Y values:", data.y);
            updateScatterChart(data);
        });

结果如下所示:

Application

第 1 步和第 2 步工作正常,但第 3 步不起作用...

加载页面时会出现第一个问题:

jquery.min.js:2 POST https ://localhost:44354/api/AjaxAPI/UpdateChartData 400(错误请求)

此外,如果我尝试在浏览器控制台中启动脚本:

fetch("https://localhost:44354/api/AjaxAPI/UpdateChartData", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ X: [400.0], Y: [600.0] }),
})
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error("Error: " + error));

为了模拟发布请求,我可以在调试中读取 ApiController 类中的值,但我无法正确更新图表的值。

我的完整代码可以在这里找到: https://github.com/DanielScerpa/RazorPageChart/tree/dev_chart

总结:

我想了解如何在收到发布请求时正确更新图表值,并且我想了解启动问题 400(错误请求)

!!!...编辑。。。!!!

总结:

  1. 当我在 apicontroller 中收到 post 调用时,如何自动更新图表?

例如,有人调用:

 <https://localhost:44354/api/AjaxAPI/UpdateChartData>

我通过代码拦截了 post 调用:

    [HttpPost]
        [Route("UpdateChartData")]
        public IActionResult UpdateChartData([FromBody] ChartData data)
        {
            // Read received data
            var newDataX = data.X; 
            var newDataY = data.Y;
            var chartData = new { x = new List<double>[] { newDataX }, y = new List<double>[] { newDataY } };
            return Ok(chartData);
        }
    }

此时,如何使用新检索到的值(data.x 和 data.y)更新图表?

  1. 如何解决启动时的 404 错误请求错误?
asp.net visual-studio visual-studio-2019 razor-pages asp.net-apicontroller

评论

0赞 Yong Shun 11/4/2023
步骤 3 中的 post 方法不会将请求正文发送到 API。而你的 fetch API () 它只是打印响应,而不是更新图表。您需要调用回调。fetch("https://localhost:44354/api/AjaxAPI/UpdateChartData"...)updateScatterChart(data)
0赞 Daniel Scerpa 11/5/2023
一旦我进入 api 控制器的方法:public IActionResult UpdateChartData([FromBody] ChartData data),如何通过回调调用 updateScatterChart(data) 方法?
0赞 Yong Shun 11/5/2023
用 JS 完成。fetch("https://localhost:44354/api/AjaxAPI/UpdateChartData", ...).then((response) => updateScatterChart(response.json()));
0赞 Daniel Scerpa 11/5/2023
对不起,如果我没有很好地解释它,实际上我希望在收到请求发布到 url 时自动这样做,是我的控制器调用图表更新。fetch 调用的示例只是“手动”测试控制器的一种方式。因此,我希望在调用时这样做:控制器获取图表的 X 和 Y 值(这已经正确发生),然后调用函数来更新图表值。https://localhost:44354/api/AjaxAPI/UpdateChartDatahttps://localhost:44354/api/AjaxAPI/UpdateChartDataupdateScatterChart(data)
0赞 Yong Shun 11/6/2023
嗨,对于 1,您应该需要 SignalR 库进行实时通信。对于 2,没有 404 错误请求,它是 400 错误请求或 404 未找到。并尝试详细阅读响应,我相信响应会为您提供失败的详细信息,可能发送的请求参数数据类型与您在控制器中定义的数据类型不匹配。

答:

0赞 Yong Shun 11/6/2023 #1

根据您的要求,当任何用户将请求发布到“UpdateChartData”API 时,您希望为图表更新 Web 应用程序。

这需要 SignalR 进行实时通信。安装和教程的完整演示,您可以参考提供的链接。

由于将 .NET Core 2.2 用于项目,并且此版本已弃用,因此 Microsoft.AspNetCore.SignalR.Common 唯一支持的版本是版本 1.1.0。下面提供的步骤用于在为 .NET Core 2.2 指定的应用程序中设置 SignalR。

  1. 通过 NuGet,安装 Microsoft.AspNetCore.SignalR.Common 1.1.0

  2. 右键单击“管理客户端库”>项目,它将生成一个libman.json文件。在该文件中,安装 @microsoft/signalr 库,如下所示:

{
  "version": "1.0",
  "defaultProvider": "unpkg",
  "libraries": [
    {
      "library": "@microsoft/signalr@latest",
      "destination": "wwwroot/js/signalr",
      "files": [
        "dist/browser/signalr.js",
        "dist/browser/signalr.min.js"
      ]
    }
  ]
}
  1. 创建 SignalR 中心
namespace Razor_WebAPI_Application.Hubs
{
    public class ChartHub : Hub
    {
        public async Task UpdateChart(ChartData chartData)
        {
            await Clients.All.SendAsync("UpdateChart", chartData);
        }
    }
}
  1. 在启动 .cs 中配置 SignalR
public class Startup 
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSignalR();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...

        app.UseSignalR(routes =>
            {
                routes.MapHub<ChartHub>("/chartHub");
            });
    }
}
  1. 从 DI 获取。并将数据发送到所有客户端。ChartHub
using Microsoft.AspNetCore.SignalR;
using Razor_WebAPI_Application.Hubs;

[Route("api/[controller]")]
[ApiController]
public class AjaxAPIController : ControllerBase
{

    private readonly IHubContext<ChartHub> _hubContext;

    public AjaxAPIController(IHubContext<ChartHub> hubContext)
    {
        _hubContext = hubContext;
    }
}
[HttpPost]
[Route("UpdateChartData")]
public IActionResult UpdateChartData([FromBody] ChartData data)
{
    // Read received data
    var newDataX = data.X;
    var newDataY = data.Y;
    var chartData = new { x = new List<double>[] { newDataX }, y = new List<double>[] { newDataY } };

    _hubContext.Clients.All.SendAsync("UpdateChart", chartData);

    return Ok(chartData);
}
  1. 添加 SignalR 客户端代码。这样,您就会等待 SignalRHub 发出“UpdateChart”事件并更新图表,但不会将 POST 请求发送到需要请求正文的“UpdateChartData”API。
<script src="~/js/signalr/dist/browser/signalr.js"></script>

<script type="text/javascript">

  ...
  var connection = new signalR.HubConnectionBuilder().withUrl("/chartHub").build();

  connection.on("UpdateChart", function (data) {
      updateScatterChart(data);
  });

  connection.start().then(function () {

  }).catch(function (err) {
      return console.error(err.toString());
  });
</script>

enter image description here