.NET Core中实现自定义Html助手传递模型到局部视图并渲染至StringWriter
实现.NET Core自定义HTML生成器:传递模型到同名局部视图并渲染为字符串
我之前在项目里刚好碰到过类似需求,在.NET Core中要完成这个功能,得借助ASP.NET Core的视图渲染服务来实现。下面是完整的可运行代码方案:
首先,我们需要在HtmlExtensions类中注入必要的视图渲染服务,核心是通过ICompositeViewEngine查找视图,再利用ViewContext完成渲染:
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewEngines; using Microsoft.AspNetCore.Mvc.ViewFeatures; using System.IO; using System.Threading.Tasks; public static class HtmlExtensions { public static async Task<HtmlString> BuildTextboxForAsync(this IHtmlHelper helper, object model) { if (model == null) return new HtmlString(string.Empty); // 取模型类型名称作为局部视图名称 var viewName = model.GetType().Name; // 从服务容器获取视图引擎和TempData工厂 var viewEngine = helper.ViewContext.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine; var tempDataFactory = helper.ViewContext.HttpContext.RequestServices.GetService(typeof(ITempDataDictionaryFactory)) as ITempDataDictionaryFactory; // 查找指定名称的局部视图 var viewResult = viewEngine.FindView(helper.ViewContext, viewName, isMainPage: false); if (!viewResult.Success) { // 视图不存在时可抛出异常或返回默认内容,这里选抛出异常示例 throw new InvalidOperationException($"找不到名为 {viewName} 的局部视图"); } // 创建ViewData并传入模型 var viewData = new ViewDataDictionary(helper.ViewData) { Model = model }; // 创建TempData var tempData = tempDataFactory.GetTempData(helper.ViewContext.HttpContext); // 构建ViewContext using var writer = new StringWriter(); var viewContext = new ViewContext( helper.ViewContext, viewResult.View, viewData, tempData, writer, new HtmlHelperOptions() ); // 异步渲染视图到StringWriter await viewResult.View.RenderAsync(viewContext); // 返回渲染后的HTML字符串 return new HtmlString(writer.ToString()); } }
关键细节说明:
- 我把方法改成了异步版本
BuildTextboxForAsync,因为ASP.NET Core的视图渲染默认是异步的,更符合框架设计规范 - 视图名称直接取模型的类型名称(比如模型是
UserInputModel,就会自动查找UserInputModel.cshtml局部视图) - 处理了视图不存在的异常场景,你可以根据需求改成返回默认HTML片段或者空字符串
- 复用了当前请求的
ViewContext上下文信息,保证视图里的辅助服务(比如UrlHelper)能正常工作
使用方式:
在你的视图中,直接传入模型对象即可:
@await Html.BuildTextboxForAsync(new UserInputModel { Id = 1, Label = "用户名", Placeholder = "请输入用户名" })
这样就能自动渲染对应名称的局部视图,并返回HTML字符串啦!
内容的提问来源于stack exchange,提问作者user9565685
相关产品推荐
相关产品推荐

