如何从服务器端ASP.NET MVC门户调用本地Windows服务API?
一、Windows服务中API URL结构优化与配置
你当前的路由配置可以调整得更规范,同时补充必要的格式化和跨域支持,适配后续Web应用的调用需求:
修改后的服务启动代码
protected override void OnStart(string[] args) { // 监听所有网卡的8085端口,若仅需本地调用可改为http://localhost:8085/ HttpSelfHostConfiguration config = new HttpSelfHostConfiguration("http://*:8085/"); // 配置JSON返回格式,移除XML格式化器 config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(); config.Formatters.Remove(config.Formatters.XmlFormatter); // 配置带api前缀的路由,更符合RESTful规范 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); // 启用跨域(后续Web应用调用需要) config.EnableCors(new EnableCorsAttribute("*", "*", "*")); using (HttpSelfHostServer server = new HttpSelfHostServer(config)) { server.OpenAsync().Wait(); LogEvent("Printing API Service started on http://*:8085/api/"); } }
注意:需要先安装
Microsoft.AspNet.WebApi.CorsNuGet包才能启用跨域。
示例打印控制器
创建对应的API控制器,实现打印逻辑:
public class PrintController : ApiController { // GET 请求示例:http://localhost:8085/api/print/testprint/1001 [HttpGet] public IHttpActionResult TestPrint(int id) { // 这里替换为实际打印测试逻辑 return Ok($"打印任务 {id} 已接收"); } // POST 请求示例:http://localhost:8085/api/print/printdocument [HttpPost] public IHttpActionResult PrintDocument([FromBody] PrintRequest request) { if (request == null || string.IsNullOrEmpty(request.DocumentContent)) { return BadRequest("打印请求参数无效"); } // 调用自定义打印工具类执行打印 bool isSuccess = PrintHelper.ExecutePrint(request.DocumentContent, request.PrinterName); return isSuccess ? Ok("打印完成") : InternalServerError(new Exception("打印失败")); } } // 打印请求模型 public class PrintRequest { public string DocumentContent { get; set; } public string PrinterName { get; set; } }
关键配置注意事项
- 端口权限:运行Windows服务的账户需要绑定端口的权限,可通过管理员命令执行
netsh http add urlacl url=http://*:8085/ user=DOMAIN\Username预留权限 - 防火墙设置:确保Windows防火墙开放8085端口,允许传入连接
- 监听地址:若需要服务器或局域网设备访问,不能仅监听
localhost,需用*:8085或电脑内网IP(如http://192.168.1.105:8085/)
二、ASP.NET MVC Web应用调用本地Printing API的两种方案
由于Windows服务运行在用户本地电脑,Web应用部署在服务器,需根据业务需求选择调用方式:
方案1:前端直接调用本地API
无需服务器中转,直接由浏览器和本地服务交互,延迟更低:
<script> async function startPrint() { const printParams = { DocumentContent: "这是测试打印内容", PrinterName: "默认打印机" }; try { // 调用用户本地的API服务 const res = await fetch('http://localhost:8085/api/print/printdocument', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(printParams) }); const result = await res.json(); alert(result); } catch (err) { alert("调用本地打印服务失败,请确认服务已启动"); } } </script> <button onclick="startPrint()">触发本地打印</button>
方案2:Web后端中转调用
如果需要服务器参与权限验证、日志记录等逻辑,可通过MVC控制器转发请求:
public class PrintManageController : Controller { private readonly HttpClient _httpClient; public PrintManageController() { _httpClient = new HttpClient(); } [HttpPost] public async Task<JsonResult> TriggerLocalPrint(PrintRequest request) { // 获取用户本地电脑的IP(局域网场景有效) string userLocalIp = Request.UserHostAddress; string apiUrl = $"http://{userLocalIp}:8085/api/print/printdocument"; try { var response = await _httpClient.PostAsJsonAsync(apiUrl, request); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); return Json(new { success = true, msg = result }); } catch (HttpRequestException ex) { return Json(new { success = false, msg = $"调用失败:{ex.Message}" }); } } }
前端通过AJAX调用后端接口:
<script> async function triggerPrint() { const printData = { DocumentContent: "后端中转测试打印", PrinterName: "默认打印机" }; try { const res = await fetch('/PrintManage/TriggerLocalPrint', { method: 'POST', headers: { 'Content-Type': 'application/json', 'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val() }, body: JSON.stringify(printData) }); const result = await res.json(); alert(result.msg); } catch (err) { alert("请求失败"); } } </script>
三、核心注意事项
- 网络可达性:用户电脑和服务器必须在同一局域网;若为公网访问,需使用内网穿透工具暴露本地8085端口
- 服务状态处理:Web应用需增加服务未启动的异常捕获和提示
- 权限控制:Windows服务运行账户需具备打印权限,生产环境需限制跨域来源为Web应用域名,可添加API密钥验证防止未授权调用
内容的提问来源于stack exchange,提问作者Suzy
相关产品推荐
相关产品推荐

