1

ユーザーがいくつかのテーマを設定できるマルチテナンシー MVC 4 アプリケーションを開発しています。/Scripts/booking.js
などのテーマ テーブルに相対パスを追加することで、すべてのリソース (css、js、jpg、png など) をオーバーライドできます。

どのテナントを使用するかは、URL (例: http://myapp/tenant/Booking/New ) によって判断されます。これは、使用する接続文字列の名前です。

したがって、特定のリソースに対してリクエストが行われた場合、データベースにこのリソースのオーバーライドされたバージョンがあるかどうかを最初に確認し、見つかった場合はそれを使用する必要があります。

ここで、Microsoft が System.Web.Optimization 名前空間で提供する新しいバンドル機能と縮小機能を実装したいと思います。しかし、データベース内のファイルでこれを達成する方法がわかりませんでした。

これを実現するために、独自の JsMinify 実装のプロトタイプを作成しました

public class MyJsMinify : JsMinify
{
    private static byte[] GetContentFile(FileInfo filePath)
    {
        string fullName = filePath.FullName;
        int indexOf = fullName.IndexOf("content", StringComparison.OrdinalIgnoreCase);
        string substring = fullName.Substring(indexOf + 8).Replace(@"\\", "/").Replace(@"\", "/");

        ThemingService themingService = ObjectFactory.GetInstance<ThemingService>();
        Theming myTheming = themingService.Find(new ThemingFilter { FilePathLike = substring });
        if (myTheming == null)
        {
            return themingService.GetContentFile(fullName);
        }
        return myTheming.FileData;
    }

    public override void Process(BundleContext context, BundleResponse response)
    {
        StringBuilder newContent = new StringBuilder();
        foreach (FileInfo fileInfo in response.Files)
        {
            using (MemoryStream memoryStream = new MemoryStream(GetContentFile(fileInfo)))
            {
                using (StreamReader myStreamReader = new StreamReader(memoryStream, true))
                {
                    newContent.AppendLine(myStreamReader.ReadToEnd());
                }
            }
        }

        response.Content = newContent.ToString();

        base.Process(context, response);
    }
}

これはリリース モードの場合に機能するようですが、開発中は各スクリプトを個別に参照したいと考えています。これは、バンドルおよび縮小フレームワーク全体で自動的に行われます。フレームワークによって生成されたリソース URL は次のようになります。

<script src="/myapp/Content/Scripts/jquery-1.9.0.js"></script>

しかし、このように見えるはずです

<script src="/myapp/tenant/Content/Scripts/jquery-1.9.0.js"></script>

次のルートを構成しました。

routeCollection.MapRoute("Content1", "{mandator}/Content/{*filePath}", new { mandator = defaultMandator, controller = "Environment", action = "ContentFile" }, new { mandator = mandatorConstraints });
routeCollection.MapRoute("Content2", "Content/{*filePath}", new { mandator = defaultMandator, controller = "Environment", action = "ContentFile" }, new { mandator = mandatorConstraints });

ContentFile メソッドは次のようになります

    [AcceptVerbs(HttpVerbs.Get)]
    [AcceptType(HttpTypes.All)]
    [OutputCache(CacheProfile = "ContentFile")]
    public ActionResult ContentFile(string filePath)
    {
        if (string.Compare(filePath, "Stylesheets/Import.css", StringComparison.OrdinalIgnoreCase) == 0)
        {
            return GetContentImport(CssFileArray, "Stylesheets/");
        }
        if (string.Compare(filePath, "Stylesheets/ImportOutlook.css", StringComparison.OrdinalIgnoreCase) == 0)
        {
            return GetContentImport(OutlookCssFileArray, "Stylesheets/");
        }
        if (string.Compare(filePath, "Scripts/OutlookAddin/Import.js", StringComparison.OrdinalIgnoreCase) == 0)
        {
            return GetContentImport(OutlookJsFileArray, "Scripts/");
        }
        return new FileContentResult(GetContentFile(filePath), MimeType(filePath));
    }

どうすればこれを達成できるか考えている人はいますか?
従うべきマルチテナンシー パターンはありますか?

4

1 に答える 1

0

したがって、あなたのシナリオを完全に理解しているかどうかはわかりませんが、これが VirtualPathProviders を使用できると信じています。

1.1-alpha1 リリースでサポートを追加したため、バンドルは ASP.NET に登録された VirtualPathProvider を自動的に使用してファイルのコンテンツを取得します。

~/Scripts/booking.js の正しいバージョンを常に返すことができるカスタム VPP を作成する場合、すべてが機能するはずです。

于 2013-01-21T22:15:16.397 に答える