Nancy无法在自定义约定中找到静态内容

时间:2014-01-14 20:14:49

标签: nancy

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

奇怪的是,以下内容适用于自定义View位置约定,但不适用于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的输出如下: ProcMon output Google Chrome output

我该怎么做:

  1. 使用未找到的js和css文件记录错误?
  2. 使用静态文件约定解决404错误?

2 个答案:

答案 0 :(得分:3)

您可以使用sysinternals process monitor而不是日志记录来查找nancy进程(exe或IIS工作进程)尝试读取的文件。

答案 1 :(得分:2)

我在自托管环境中提供静态文件(在我的案例中是js文件)也遇到了问题。它们根本没有被识别,甚至在默认的“Content”文件夹中也没有被识别。我的解决方案:我安装了Microsoft StaticFiles NuGet Package

在启动类中,注册一个静态文件文件夹,如下所示:

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

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

重要的是:对UseNancy()的调用必须是最后一个,否则它之后的所有内容都将无效。我也尝试将它与SignalR结合起来,如上所示,并且UseNancy()调用也必须在最后。