Ich versuche, einen generischen Ansatz zu implementieren, um die Möglichkeit für verschiedene Assemblies in meiner Weblösung zu bieten, eingebettete JavaScript- und CSS-Dateien aus eingebetteten Ressourcen zu verwenden. This blog post zeigt eine Technik, die einen VirtualPathProvider verwendet. Dies funktioniert einwandfrei, aber der VirtualPathProvider muss in jeder Assembly enthalten sein, die eingebettete Ressourcen enthält.ASP.NET mit eingebetteten Ressourcen in Bundling
Ich versuchte, die VirtualPathProvider aus der Blog-Post zu verbessern, so dass eine Baugruppe hinein geführt werden kann und es die Ressource aus seiner Assembly lädt:
public EmbeddedVirtualPathProvider(VirtualPathProvider previous, Assembly assembly)
{
this.previous = previous;
this.assembly = assembly;
}
Bei der Initialisierung liest sie alle eingebetteten Ressourcen aus dem übergebenen Montag:
protected override void Initialize()
{
base.Initialize();
this.assemblyResourceNames = this.assembly.GetManifestResourceNames();
this.assemblyName = this.assembly.GetName().Name;
}
Und die GetFile
liest den Inhalt aus dem übergebenen assembly:
public override VirtualFile GetFile(string virtualPath)
{
if (IsEmbeddedPath(virtualPath))
{
if (virtualPath.StartsWith("~", System.StringComparison.OrdinalIgnoreCase))
{
virtualPath = virtualPath.Substring(1);
}
if (!virtualPath.StartsWith("/", System.StringComparison.OrdinalIgnoreCase))
{
virtualPath = string.Concat("/", virtualPath);
}
var resourceName = string.Concat(this.assembly.GetName().Name, virtualPath.Replace("/", "."));
var stream = this.assembly.GetManifestResourceStream(resourceName);
if (stream != null)
{
return new EmbeddedVirtualFile(virtualPath, stream);
}
else
{
return _previous.GetFile(virtualPath);
}
}
else
return _previous.GetFile(virtualPath);
}
prüft Ressource eine eingebettete Ressource dieser Anordnung ist durch die Ressourcennamen in der Initialize
Methode lesen Überprüfung:
private bool IsEmbeddedPath(string path)
{
var resourceName = string.Concat(this.assemblyName, path.TrimStart('~').Replace("/", "."));
return this.assemblyResourceNames.Contains(resourceName, StringComparer.OrdinalIgnoreCase);
}
Ich zog die EmbeddedVirtualPathProvider
Klasse auf die Haupt Webprojekt (ProjectA), so dass es doesn ‚müssen t in jeder Baugruppe enthält eingebettete Ressourcen einbezogen werden und registriert es den folgenden Code in Global.asax
mit:
HostingEnvironment.RegisterVirtualPathProvider(
new EmbeddedVirtualPathProvider(
HostingEnvironment.VirtualPathProvider,
typeof(ProjectB.SomeType).Assembly));
im Projekt die eingebetteten Ressourcen enthält (ProjectB) ich immer noch das folgende Bündel in einerstellen:
BundleTable.Bundles.Add(new ScriptBundle("~/Embedded/Js")
.Include("~/Scripts/SomeFolder/MyScript.js")
);
Scripts/MyScript.js
ist die eingebettete Ressource in ProjectB.
Damit erhalte ich die folgende Ausnahme:
Verzeichnis 'C: \ webs \ ProjectA \ Scripts \ SomeFolder \' existiert nicht. Fehler beim Starten der Überwachung von Dateiänderungen.
aktualisieren Voll Stack-Trace in this Gist verfügbar.
Update Auch der VirtualPathProvider selbst scheint gut zu funktionieren. Wenn ich die Datei direkt und nicht durch das Bündel laden und legen Sie den folgenden Eintrag in der web.config
lädt es das eingebettete Javascript aus ProjectB:
<system.webServer>
<handlers>
<add name="MyStaticFileHandler" path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler"/>
</handlers>
</system.webServer>
Wo ist Ihre Startup-Klasse? In ProjectA oder in ProjectB? –
ProjectA ist ein NuGet-Paket, das den VirtualPathProvider enthält. ProjectB ein anderes NuGet-Paket mit einigen Funktionen mit Ansichten (es gibt mehrere davon). Das NuGet-Paket ProjectB ist von dem NuGetPackage-ProjektA abhängig. Anwendungen installieren die ProjectB NuGetPackages. Daher befindet sich der Startvorgang außerhalb von ProjectA und ProjectB, aber ProjectA und ProjectB können sich in PreApplicationStartMethod einklinken. –
Es scheint, dass die 'IsEmbeddedPath'-Methode' false' zurückgibt, während sie 'true' zurückgeben sollte. Können Sie uns den Wert von 'path' und' resourceName' mitteilen, bevor der Fehler auftrat? –