Сборка и минификация ASP.NET включают динамические файлы из базы данных.

Я разрабатываю многопользовательское приложение MVC 4, в котором у пользователя есть некоторые возможности тем.
Он может переопределить каждый отдельный ресурс (css, js, jpg, png, ect...), добавив относительный путь к тематическая таблица, например /Scripts/booking.js

Какой арендатор использовать, определяется 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));
    }

Есть ли у кого-нибудь идеи, как этого добиться?
Существует ли шаблон мультиарендности, которому нужно следовать?


person Lukas    schedule 17.01.2013    source источник


Ответы (1)


Поэтому я не уверен, что полностью понимаю ваш сценарий, но я считаю, что именно для этого можно использовать VirtualPathProviders.

Мы добавили поддержку в выпуске 1.1-alpha1, поэтому пакеты будут автоматически использовать VirtualPathProvider, зарегистрированный в ASP.NET, для извлечения содержимого файла.

Если бы вы написали собственный VPP, который всегда может вернуть правильную версию ~/Scripts/booking.js, все должно просто работать.

person Hao Kung    schedule 21.01.2013