我们正在构建一个建立在razor之上的自定义报告引擎,供我们自己内部使用,到目前为止一切都很顺利。然而,我们已经开始将初始原型代码分解为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中不能清晰地呈现。相反,它只是在ViewComponent的位置吐出Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewBuffer
。
我们该如何让它与razor一起工作呢?
作为参考,我们从基于客户端Javascript的版本移植系统。本质上,它们是相同的,但是这个版本将在服务器端而不是客户端加载所有组件。
发布于 2018-07-13 06:17:35
在我看来,如果您能够将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();
https://stackoverflow.com/questions/51314617
复制相似问题