ASP.NET Razor页面按钮触发API调用及传参问题求助
解决Razor页面调用API并展示结果的问题
后端代码(Test.cshtml.cs)
确保页面模型继承PageModel,注入HttpClient(推荐在Program.cs中注册builder.Services.AddHttpClient();),通过绑定属性接收前端参数,调用API后将结果存入模型属性供页面展示:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System.Net.Http.Json; public class TestModel : PageModel { private readonly HttpClient _httpClient; public TestModel(HttpClient httpClient) { _httpClient = httpClient; } // 绑定前端输入的文件路径 [BindProperty] public string FilePath { get; set; } // 存储API返回结果 public string ApiResult { get; set; } // 处理按钮触发的POST请求 public async Task<IActionResult> OnPostCallApiAsync() { if (string.IsNullOrEmpty(FilePath)) { ApiResult = "请输入文件路径"; return Page(); } try { // 替换为你的API地址,根据API请求方式调整(示例为GET带参数) var encodedPath = Uri.EscapeDataString(FilePath); var response = await _httpClient.GetFromJsonAsync<string>($"https://your-api-domain/api/your-endpoint?filePath={encodedPath}"); // 若API为POST请求,可改用以下方式: // var requestBody = new { FilePath = FilePath }; // var apiResponse = await _httpClient.PostAsJsonAsync("https://your-api-domain/api/your-endpoint", requestBody); // apiResponse.EnsureSuccessStatusCode(); // ApiResult = await apiResponse.Content.ReadAsStringAsync(); ApiResult = response ?? "API返回空结果"; } catch (Exception ex) { ApiResult = $"调用失败:{ex.Message}"; } return Page(); } }
前端代码(Test.cshtml)
提供两种实现方式,按需选择:
同步表单版本(简单直接)
通过表单提交触发后端方法,页面刷新展示结果:
@page @model TestModel <h3>API调用测试</h3> <form method="post"> <div class="form-group"> <label>文件路径:</label> <input type="text" class="form-control" asp-for="FilePath" placeholder="输入文件路径"> </div> <button type="submit" asp-page-handler="CallApi" class="btn btn-primary mt-2">调用API</button> </form> @if (!string.IsNullOrEmpty(Model.ApiResult)) { <div class="mt-3"> <h4>结果:</h4> <pre class="border p-2">@Model.ApiResult</pre> </div> }
异步AJAX版本(无刷新体验)
通过JS发送请求,不刷新页面即可展示结果:
@page @model TestModel <h3>API调用测试</h3> <div class="form-group"> <label>文件路径:</label> <input type="text" id="filePathInput" class="form-control" placeholder="输入文件路径"> </div> <button id="callApiBtn" class="btn btn-primary mt-2">调用API</button> <div id="resultContainer" class="mt-3" style="display: none;"> <h4>结果:</h4> <pre id="resultContent" class="border p-2"></pre> </div> <script> document.getElementById('callApiBtn').addEventListener('click', async () => { const filePath = document.getElementById('filePathInput').value; if (!filePath) { alert('请输入文件路径'); return; } const resultContainer = document.getElementById('resultContainer'); const resultContent = document.getElementById('resultContent'); resultContainer.style.display = 'block'; resultContent.textContent = '正在调用API...'; try { const response = await fetch('/Test?handler=CallApi', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value }, body: `FilePath=${encodeURIComponent(filePath)}` }); if (!response.ok) throw new Error('请求异常'); const pageHtml = await response.text(); const tempDiv = document.createElement('div'); tempDiv.innerHTML = pageHtml; const apiResult = tempDiv.querySelector('#resultContent')?.textContent || '未获取到结果'; resultContent.textContent = apiResult; } catch (ex) { resultContent.textContent = `调用失败:${ex.message}`; } }); </script> @Html.AntiForgeryToken() @if (!string.IsNullOrEmpty(Model.ApiResult)) { <script> document.getElementById('resultContainer').style.display = 'block'; document.getElementById('resultContent').textContent = '@Model.ApiResult'; </script> }
核心注意点
- 参数编码:文件路径含特殊字符(空格、斜杠等)时,必须用
Uri.EscapeDataString(后端)或encodeURIComponent(前端)编码,避免请求解析错误。 - CSRF防护:Razor页面POST请求必须携带
__RequestVerificationToken,同步表单会自动生成,AJAX需手动添加(示例已包含)。 - HttpClient复用:通过依赖注入使用
HttpClient,避免频繁创建实例导致套接字资源耗尽。 - 错误捕获:添加异常处理逻辑,确保页面稳定并给出明确的错误提示。
内容的提问来源于stack exchange,提问作者d4n0
相关产品推荐
相关产品推荐

