ASP.NET C# 执行.exe进程完成后触发页面重载的实现问题
问题描述
我正在开发一款通过Web GUI配置软件组件的应用,其中一个配置模块需要调用可执行程序选择SFTP文件夹,选中的路径会和其他参数共同存入JSON文件,最终回显到表单输入字段中。
前端cshtml代码
<button class="btn btn-primary" onclick="browseSftp()">Select SFTP folder</button> <script> function browseSftp() { window.$.ajax({ type: "POST", url: "/BackupConfiguration?handler=BrowseSftp", contentType: "application/json; charset=utf-8", beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", window.$('input:hidden[name="__RequestVerificationToken"]').val()); }, data: JSON.stringify({ autoBackup: $('input[name="FormData.autoBackup"]:checked').val(), backupTime: $('#FormData_backupTime').val(), keepAllBackups: $('input[name="FormData.keepAllBackups"]:checked').val(), backupsKept: $('#FormData_backupsKept').val(), hostName: $('#FormData_hostName').val(), hostKey: $('#FormData_hostKey').val(), port: $('#FormData_port').val(), username: $('#FormData_username').val(), password: $('#FormData_password').val(), remoteFolder: $('#FormData_remoteFolder').val(), localFolder: $('#FormData_localFolder').val(), isLocal: $('input[name="FormData.isLocal"]:checked').val(), }), success: function (response) { alert("success"); } }); }; </script>
后端cshtml.cs接口代码
public void OnPostBrowseSftp([FromBody] FormData formData) { //string[] args = { FormData.autoBackup, FormData.backupTime, FormData.keepAllBackups, FormData.backupsKept, FormData.hostName, FormData.hostKey, FormData.port, FormData.username, FormData.password, FormData.remoteFolder, FormData.localFolder, "TRUE" }; string[] args = {FormData.hostName, FormData.username, FormData.password}; if(formData.autoBackup == null) { formData.autoBackup = "false"; } if(formData.keepAllBackups == null) { formData.keepAllBackups = "false"; } var process = System.Diagnostics.Process.Start(_browseSftpScript, formData.hostName + " " + formData.username + " " + formData.password + " " + formData.autoBackup + " " + formData.backupTime + " " + formData.keepAllBackups + " " + formData.backupsKept + " " + formData.port + " " + formData.isLocal + " " + _jsonPath); process.WaitForExit(); Response.Redirect("/backupConfiguration"); }
OnGet页面初始化代码
public void OnGet() { if (HttpContext.Session.GetString(SettingName) == null || HttpContext.Session.GetString(SettingName) != "AlreadyLoaded") { HttpContext.Session.SetString(SettingName, "AlreadyLoaded"); if (System.IO.File.Exists(_systemSettingJsonPath)) { FormData = SettingsService.GetData<FormData>(_systemSettingJsonPath); SettingsService.SaveData(FormData, _jsonPath); } else { FormData = SettingsService.GetData<FormData>(_jsonPath); } } else { FormData = SettingsService.GetData<FormData>(_jsonPath); } }
问题现象
正常来说OnGet方法会重新初始化页面、填充表单字段,但当前没有生效,只有手动跳转到其他页面再返回时才会加载最新数据。查看日志后推测原因是OnGet方法在BrowseSftp请求处理完成前就被调用:
2021-11-25 17:31:22.922 +01:00 [Microsoft.AspNetCore.Routing.EndpointMiddleware] [INF] Executed endpoint '/BackupConfiguration' 2021-11-25 17:31:22.922 +01:00 [Microsoft.AspNetCore.Hosting.Diagnostics] [INF] Request finished HTTP/1.1 POST http://localhost:5000/BackupConfiguration?handler=BrowseSftp application/json;+charset=UTF-8 228 - 200 - text/html;+charset=utf-8 705431.7372ms
原本预期process.WaitForExit();执行完再跳转页面的逻辑未生效,最终目标是在.exe进程执行完毕后正常触发页面重载。
解决方案
你的问题核心有两个,依次修改即可:
- 后端
Response.Redirect对AJAX请求无效
你用AJAX发送POST请求时,后端返回的302跳转指令只会被AJAX异步处理,浏览器不会主动刷新当前页面,跳转后的页面内容只会作为响应返回给前端JS的success回调,所以你看不到页面刷新。
解决方法:不要在后端做跳转,改成在前端AJAX的success回调里执行页面刷新,修改前端JS的success逻辑:
success: function (response) { // 进程执行完成后主动刷新当前页 window.location.reload(); }
同时删掉后端OnPostBrowseSftp里的Response.Redirect("/backupConfiguration");代码即可。
- OnGet方法的Session判断逻辑冗余
你在OnGet里设置了AlreadyLoaded的Session标识,只要Session没过期,后续刷新页面只会走else分支,虽然你else分支是读取最新的_jsonPath,不会影响配置读取,但如果有系统配置更新的场景会导致无法同步,不需要该逻辑可以直接删除Session判断,或者在调用完SFTP选择程序后主动清空这个Session标识。
另外补充一个优化点:你拼接进程启动参数的时候直接用空格拼接,如果参数里有空格会导致参数解析错误,建议给每个参数加上双引号包裹,避免参数解析异常。
内容的提问来源于stack exchange,提问作者Jukilo
相关产品推荐
相关产品推荐

