2011-01-26 23 views
20

複数のASP.NET MVC 3アプリケーションで再利用できるように、コントローラとビューを別々のクラスライブラリに分割したいと思います。別のアセンブリを使用する場合、コントローラの部分は問題ではありませんでしたが、ビューエンジンを取得してビューを配置するのは問題ありませんでした。複数のWebアプリケーションでコントローラとビューを共有する

私はCompile your asp.net mvc Razor views into a seperate dllを使用してしまいました。

もっと簡単な方法がありますか?

答えて

3

mvc contribのポータブルエリアをご覧ください。 http://www.lostechies.com/blogs/hex/archive/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib.aspx これは、この目的のために特別に作られたものです。あなたがその道を行くなら、コードは少なくて済む;-)

+0

私はlos techiesの投稿を見ました。私はそれが人々のためにうまくいくと確信していますが、それは私が必要とするもののために全面的な過剰です。バスと他の構成とのメッセージングは​​、私に重い手渡しを受けているようです。 Razorビューのコンパイルはビュー上の1つのプロパティ設定です(ただし、すべてのビューに適用されます)。 – blu

18

投稿されたアイデアをhereに変更し、MVC3で作業する。かなり速くて簡単でした。唯一の小さな欠点は、共有ビューが埋め込まれたリソースである必要があり、したがってコンパイルされる必要があることです。

  • 共有ビュー(.cshtml、.vbhtmlファイル)をライブラリプロジェクトに配置します。 (私はこのプロジェクトでいくつかの共有コントローラも持っています)アプリケーションから_Layout.cshtmlを使用する場合は、その共有ビューをポイントする_ViewStart.cshtmlを必ず含めてください。

  • ライブラリプロジェクトでは、すべてのビューのビルドアクションプロパティを埋め込みリソースに設定します。

  • ライブラリプロジェクトでは、ビューの内容をtmp/Viewsディレクトリに書き込む次のコードを追加します。

。私はエイドリアンのStreamToFileライターを使用してい

public class EmbeddedResourceViewEngine : RazorViewEngine 
{ 
    public EmbeddedResourceViewEngine() 
    { 
     ViewLocationFormats = new[] { 
     "~/Views/{1}/{0}.aspx", 
     "~/Views/{1}/{0}.ascx", 
     "~/Views/Shared/{0}.aspx", 
     "~/Views/Shared/{0}.ascx", 
     "~/Views/{1}/{0}.cshtml", 
     "~/Views/{1}/{0}.vbhtml", 
     "~/Views/Shared/{0}.cshtml", 
     "~/Views/Shared/{0}.vbhtml", 
     "~/tmp/Views/{0}.cshtml", 
     "~/tmp/Views/{0}.vbhtml" 
    }; 
     PartialViewLocationFormats = ViewLocationFormats; 

     DumpOutViews(); 
    } 

    private static void DumpOutViews() 
    { 
     IEnumerable<string> resources = typeof(EmbeddedResourceViewEngine).Assembly.GetManifestResourceNames().Where(name => name.EndsWith(".cshtml")); 
     foreach (string res in resources) { DumpOutView(res); } 
    } 

    private static void DumpOutView(string res) 
    { 
     string rootPath = HttpContext.Current.Server.MapPath("~/tmp/Views/"); 
     if (!Directory.Exists(rootPath)) 
     { 
      Directory.CreateDirectory(rootPath); 
     } 

     Stream resStream = typeof(EmbeddedResourceViewEngine).Assembly.GetManifestResourceStream(res); 
     int lastSeparatorIdx = res.LastIndexOf('.'); 
     string extension = res.Substring(lastSeparatorIdx + 1); 
     res = res.Substring(0, lastSeparatorIdx); 
     lastSeparatorIdx = res.LastIndexOf('.'); 
     string fileName = res.Substring(lastSeparatorIdx + 1); 

     Util.SaveStreamToFile(rootPath + fileName + "." + extension, resStream); 
    } 
} 

は、hereを発見しました。アプリケーションのGlobal.asax.csで

  • 追加:

。カーソンヘリックの優れた投稿に

public static void RegisterCustomViewEngines(ViewEngineCollection viewEngines) 
{ 
    //viewEngines.Clear(); //This seemed like a bad idea to me. 
    viewEngines.Add(new EmbeddedResourceViewEngine()); 
} 

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RegisterRoutes(RouteTable.Routes); 
    RegisterCustomViewEngines(ViewEngines.Engines); 
} 
+0

私の場合は、resStreamはnullです。ReflectionPermissions(http://msdn.microsoft.com/en-us/library/xc4235zt(v=vs.110).aspx)に関するいくつかの問題があります。誰か同じ問題がありますか? –

+0

これは実際に働いた。これまでの最も簡単な解決法。小道具! – Exzile

3

ただ、いくつかの追加...

  1. あなたは参照のいくつかを解決する必要があります(あなたのプロジェクトにSystem.Runtime.Remotingを含める必要があります)。

  2. Utils.SaveStreamToFileに変更する必要があります - あなたがエラーを取得することがあり>

    System.Runtime.Remoting.MetadataServices.MetaData.SaveStreamToFile(resStream, rootPath + fileName + "." + extension); 
    
  3. - ビューはWebViewPage、またはWebViewPage<TModel>から派生しなければなりません。答えは次のとおりです。The view must derive from WebViewPage, or WebViewPage<TModel>

  4. プロジェクトをデプロイすると、プロジェクトを読み込む際にエラーが発生する可能性が高くなります。あなたはAPP POOLにあなたが(完全な)権利を使用していることを伝える必要があります。

関連する問題