2014-01-14 99 views
6

我已經設置了Nancy引導程序來從非默認目錄路徑(它是自我託管的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中如下: ProcMon output Google Chrome output

我應該如何:有沒有發現js和css文件發生

  1. 登錄錯誤?
  2. 用靜態文件約定解決404錯誤?
+0

我在想*如果你在*改變約定後調用基礎'ConfigureConventions' *,你會發現它重置它......但這只是一個猜測。 – Crisfole

+0

我已經在兩個位置嘗試過'ConfigureConventions',沒有任何運氣。 –

+1

這似乎是南希[旨在不服務任何子文件夾以外的靜態內容](https://github.com/NancyFx/Nancy/blob/master/src/Nancy.Tests/Unit/StaticContentConventionBuilderFixture.cs# L107),但它仍然沒有解釋爲什麼它會默默地失敗並且不提供錯誤消息。 –

回答

3

取而代之的是,您可以使用sysinternals process monitor並查找nancy進程(exe或IIS工作進程)嘗試讀取哪些文件。

+0

良好的通話。其中還有陌生人的事情。所有操作都從正確的Contents和Scripts目錄請求css和js文件,返回所有成功的SUCCESS,但在瀏覽器中仍然是404 ... –

+0

我已經將ProcMon和web inspector的屏幕截圖添加到了問題中。 –

+0

Hrm,輸出窗口中發生的任何第一次機會異常?你可以隨時進入南希碼。 –

2

我在自己的主機環境中提供靜態文件(在我的情況下是js文件)也有問題。他們根本沒有被識別,即使在默認的「Content」文件夾中也沒有。我的解決方案:我安裝了Microsoft StaticFiles NuGet Package

在啓動類,註冊一個靜態文件的文件夾是這樣的:

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

這樣,在「腳本」文件夾中的所有文件和子文件夾都充當靜態文件。 UseStaticFiles()函數還有一個重載,它允許您將物理路徑映射到虛擬路徑。

重要的是:對UseNancy()的調用必須是最後一個,否則它後面的所有東西都不起作用。我也試着將它與SignalR結合起來,就像你上面看到的那樣,並且UseNancy()調用也必須在最後。

+0

這適用於我的設置(Nancy,Owin,在Linux上使用單聲道的自我主機)。 – FooBar