【问题标题】:Nancy fails to find static content in custom conventionNancy 无法在自定义约定中找到静态内容
【发布时间】:2015-04-28 03:30:03
【问题描述】:

我已经设置了一个 Nancy 引导程序来提供来自非默认目录路径的静态内容(它是自托管的 Nancy)。

奇怪的是,以下适用于自定义视图位置约定,但不适用于 js 或 css 静态内容约定(是的,文件和文件夹都存在于这些位置!)。我试图解决这个问题的尝试更加复杂,因为我还没有弄清楚如何记录在找不到静态内容时发生的错误。

using System;
using System.IO;

using Nancy;
using Nancy.Conventions;
using Nancy.Bootstrapper;
using Nancy.TinyIoc;

namespace MyApp
{
    public class ApplicationBootstrapper : DefaultNancyBootstrapper
    {

    private const string RELATIVE_PATH_TO_SOURCE = @"../static/MyApp/";

    protected override void ConfigureConventions(NancyConventions nancyConventions)
    {

        nancyConventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("js", string.Concat(RELATIVE_PATH_TO_SOURCE, "Scripts/")));
        nancyConventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("css", string.Concat(RELATIVE_PATH_TO_SOURCE, "Content/")));
        this.Conventions.ViewLocationConventions.Add((viewName, model, context) =>
        {
            return string.Concat(RELATIVE_PATH_TO_SOURCE, "Views/", viewName);
        });
        this.Conventions.ViewLocationConventions.Add((viewName, model, context) =>
        {
            return string.Concat(RELATIVE_PATH_TO_SOURCE, "Views/", context.ModuleName, "/", viewName);
        });

        base.ConfigureConventions(nancyConventions);
    }

    protected override IRootPathProvider RootPathProvider
    {
        get
        {
            return new MyRootPathProvider();
        }
    }

    protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
    {
        pipelines.OnError += (ctx, ex) =>
        {
            Console.WriteLine("RootPath : {0}", DebugRootPathProvider.RootPath);
            Console.WriteLine("Unhandled error on request: {0} : {1}", ctx.Request.Url, ex.Message); //HACK
            Console.WriteLine(ex.StackTrace); //HACK poor man's logging
            return null;
        };
    }
}

public class MyRootPathProvider : IRootPathProvider
{
    public static readonly string RootPath;
    static MyRootPathProvider()
    {
        RootPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    }

    public string GetRootPath()
    {
        return RootPath;
    }
}
}

Chrome 和 ProcMon 的输出如下:

我应该怎么做:

  1. 找不到 js 和 css 文件时出现日志错误?
  2. 使用静态文件约定解决 404 错误?

【问题讨论】:

  • 我在想,如果你调用 base ConfigureConventions 之后你会发现它会重置它……但这只是猜测。跨度>
  • 我在这两个地方都试过ConfigureConventions,但都没有运气。
  • Nancy 似乎是designed not to serve static content outside of any child folders,但它仍然没有解释为什么它会静默失败并且不提供错误消息。
  • 您如何托管应用程序?我在使用 Nancy.Owin 和 Microsoft.Owin.Host.SystemWeb 时遇到了类似的问题,因为 IIS 没有对包含点的请求路径使用 Owin 处理程序 - 默认情况下,IIS 将对其中带有点的任何内容使用静态文件处理程序。您可以通过告诉 IIS 对所有请求使用 Owin 来修复它:<add name="Owin" verb="*" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb" />
  • @mattk - 完美!为我解决了:)

标签: nancy


【解决方案1】:

您可以使用sysinternals process monitor 代替记录,并查找nancy 进程(exe 或IIS 工作进程)试图读取的文件。

【讨论】:

  • 好电话。其中有一个奇怪的东西。所有操作都从正确的 Contents 和 Scripts 目录请求 css 和 js 文件,全部返回 SUCCESS,但在浏览器中仍然是 404...
  • 我在问题中添加了 ProcMon 和 web 检查器的屏幕截图。
  • Hrm,输出窗口中是否出现任何第一次机会异常?你可以随时进入 nancy 代码。
  • 感谢指点,找到the reason
  • @sprocketonline 我想 BDD 有话要说。
【解决方案2】:

我在自托管环境中提供静态文件(在我的情况下为 js 文件)时也遇到了问题。它们根本不被识别,甚至在默认的“内容”文件夹中也不被识别。我的解决方案:我安装了Microsoft StaticFiles NuGet Package

在启动类中,像这样注册一个静态文件夹:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseStaticFiles("/Scripts");
        app.MapSignalR();
        app.UseNancy();
    }
}

这样,“脚本”文件夹中的所有文件和子文件夹都将作为静态文件提供。还有一个 UseStaticFiles() 函数的重载,它允许您将物理路径映射到虚拟路径。

这里很重要:对 UseNancy() 的调用必须是最后一次,否则之后的一切都将不起作用。正如您在上面看到的,我还尝试将它与 SignalR 结合使用,并且 UseNancy() 调用也必须在最后。

【讨论】:

  • 这适用于我的设置(Nancy、Owin、在 linux 上使用单声道的自托管)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 2019-10-30
  • 2015-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多