MVC 6 更改视图块的呈现位置

19 浏览
0 Comments

MVC 6 更改视图块的呈现位置

我的目标是创建一个类似于razor @section Scripts {...}语法的模拟,可以在视图和视图组件中同样有效。如果将JavaScript转换为Windows字符串,我可以通过帮助方法来实现这一点。然而,这将破坏智能感知功能,使您陷入字符转义困境,并且不允许您在渲染之前进行重复和排序脚本。

我希望以一种允许Visual Studio编辑器将JavaScript作为JavaScript进行编辑的方式来实现此目标。似乎我应该能够做到类似这样的事情:

@using (Html.BeginNamedScript($"StatDisplay{Model.UniqueId}"))

{

}

HtmlHelperExtension:

public static NamedScript BeginNamedScript(this IHtmlHelper htmlHelper, string name, params string[] dependancies)

{

return new NamedScript(htmlHelper.ViewContext, name, htmlHelper, dependancies);

}

NamedScript类:

using System;

using System.Diagnostics;

using System.IO;

using Microsoft.AspNet.Mvc.Rendering;

using Microsoft.AspNet.Mvc.ViewFeatures;

namespace WebUIB8.Helpers

{

public class NamedScript : IDisposable

{

private bool _disposed;

private readonly FormContext _originalFormContext;

private readonly ViewContext _viewContext;

private readonly TextWriter _writer;

private readonly string _name;

private readonly HtmlHelper _helper;

private readonly string[] _dependsOn;

public NamedScript(ViewContext viewContext, string name, params string[] dependsOn):this(viewContext, name, null, dependsOn)

{

}

internal NamedScript(ViewContext viewContext, string name, IHtmlHelper helper, params string[] dependsOn)

{

if (viewContext == null)

{

throw new ArgumentNullException(nameof(viewContext));

}

_name = name;

_dependsOn = dependsOn;

_helper = helper as HtmlHelper;

_viewContext = viewContext;

_writer = viewContext.Writer;

Debug.WriteLine("Beginning:\r\n" + _viewContext);

_originalFormContext = viewContext.FormContext;

viewContext.FormContext = new FormContext();

Begin();

}

public void Dispose()

{

Dispose(true);

GC.SuppressFinalize(this);

}

public void Begin()

{

//No beginning action needed

}

private void End()

{

Debug.WriteLine("Ending:\r\n" + _writer);

_helper?.AddJavaScript(_name, _writer.ToString(), _dependsOn);

}

protected virtual void Dispose(bool disposing)

{

if (!_disposed)

{

_disposed = true;

End();

if (_viewContext != null)

_viewContext.FormContext = _originalFormContext;

}

}

public void EndForm()

{

Dispose(true);

}

}

}

我尝试过使用以下方法将脚本渲染为字符串,但它在.RenderAsync调用内抛出异常,并造成页面中止并出现503.2错误:

private async Task RenderView(ViewContext viewContext)

{

using (var sw = new StringWriter())

{

var newViewContext = new ViewContext(viewContext, viewContext.View, viewContext.ViewData, sw);

var razorView = newViewContext.View as RazorView;

razorView.RenderAsync(newViewContext).Wait();

sw.Flush();

return sw.ToString();

}

}

问题:

1. 我是否错过了一个更简单的解决方案?是否有一种更简单的方法来渲染Razor标记的结果并将其传递给HTML帮助方法?

2. 如何将@using块中的ViewContext渲染为文本?

3. 如何防止该ViewContext与其余视图一起渲染?(以便稍后在页面上呈现)

0
0 Comments

MVC 6中更改视图块呈现位置的原因是想要将脚本内容从输出中移除,但又想保留在内存中供后续使用。为了实现这个行为,可以使用标签助手(tag helpers)来实现。

首先,创建一个名为"InlineScriptConcatenatorTagHelper"的标签助手,用于处理" ...

然后,在"_Layout.cshtml"文件中添加一个单独的脚本元素,用于呈现所有具有相同bundle名称的脚本的连接输出:

...


最终呈现的输出将包含一个单独的脚本元素,其中包含所有在inline bundle中包含的脚本内容:

...


最后别忘了在程序集中注册这些标签助手,可以通过在"_ViewImports.cshtml"文件中添加一个@addTagHelper指令来实现。

另外,还可以参考一个名为"ScriptManagerPlus"的github项目,该项目基于上述方法,并支持去重和依赖项排序,以支持脚本压缩和提供nuget包的功能。

0