我们正在构建一个基于剃须刀的自定义报告引擎,供我们内部使用,到目前为止,一切进展顺利。但是,我们已经开始将初始原型代码分解为ReportViewer视图内部的功能,以使维护变得容易一些,但是我们遇到了一些问题。
原始原型代码(以非常简化的形式)如下所示:
@foreach (var widget in Model.ReportWidgets)
{
var longSide = Model?.DisplayOptions?.DisplayMedium?.Long ?? 0;
var units = Model?.DisplayOptions?.DisplayMedium?.Units ?? "px";
var height = widget.Rows * (longSide / Model.RowsPerPage);
var width = widget.Columns / Model.Columns * 100;
<div style="float: left;height: @(height)@(units); width: @(width)%">
@(await InvokeComponent(widget))
</div>
}
我们正在有效地尝试将其分解为看起来更像以下的函数:
public async Task<HtmlString> BuildContainer(IReportWidget widget)
{
var longSide = Model?.DisplayOptions?.DisplayMedium?.Long ?? 0;
var units = Model?.DisplayOptions?.DisplayMedium?.Units ?? "px";
var height = widget.Rows * (longSide / Model.RowsPerPage);
var width = widget.Columns / Model.Columns * 100;
var openDeclaration = $"<div style='float:left;height: {height}{units};width: {width}>";
var component = await InvokeComponent(widget);
var closeDeclaration = "</div>";
return new HtmlString(openDeclaration + component + closeDeclaration);
}
public async Task<IHtmlContent> InvokeComponent(IReportWidget widget)
{
return await Component.InvokeAsync("AnalyticsWidget", new {widget = widget});
}
但是,由于ViewComponent返回了IViewComponentResult
,因此在我们的HtmlString中无法清晰地呈现。相反,它只是吐出Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewBuffer
来代替ViewComponent。
我们将如何使它与剃须刀一起使用?
作为参考,我们正在从基于Javascript的客户端版本移植系统。本质上,它们是相同的,但是此版本将在服务器端而不是客户端加载所有组件。
答案 0 :(得分:1)
在我看来,如果您能够将结果从InvokeComponent
转换为String
,则应该解决此问题。因此,为什么不尝试从IHtmlContent获取字符串:
System.Text.StringBuilder sb = new System.Text.StringBuilder();
System.IO.StringWriter writer = new System.IO.StringWriter(sb);
System.Text.Encoding asciiEncoding = System.Text.Encoding.ASCII;
System.Text.Encodings.Web.HtmlEncoder hEncoder= System.Text.Encodings.Web.HtmlEncoder.Default;
component.WriteTo(writer, hEncoder);
String htmlString = writer.toString();