MVC Razor, включить JS/CSS файлы из другого проекта - программирование
Подтвердить что ты не робот

MVC Razor, включить JS/CSS файлы из другого проекта

У меня есть проект С# MVC, который использует синтаксис Razor.
Чтобы иметь возможность повторно использовать некоторый код, я хочу поместить некоторые из моих файлов JavaScript и CSS в другой проект и каким-то образом включить их.
Вот как мои скрипты включены atm:

<script src="@Url.Content("~/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/bootstrap-dropdown.js")" type="text/javascript"></script>

В momemnt скрипты находятся в том же проекте, что и файл cshtml. Но скрипты должны быть помещены в проект Common.Web вместо...
Я хочу сделать это (не работает):

<script src="@Url.Content("Common.Web/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>
<script src="@Url.Content("Common.Web/Scripts/bootstrap-dropdown.js")" type="text/javascript"></script>
4b9b3361

Ответ 1

Я делаю именно это. Однако я вставляю файлы Javascript и другой контент в другую DLL, а затем вызываю их из синтаксиса бритвы. Вот код, который я использую. В представлении: Script пример:

        <script [email protected]("GetEmbeddedResource", "Shared", new { resourceName = "Namespace.Scripts.jquery.qtip.min.js", pluginAssemblyName = @Url.Content("~/bin/Namespace.dll") }) type="text/javascript" ></script>

Пример изображения:

@Html.EmbeddedImage("corporate.gif", new { width = 150, height = 50})

Вот мои вспомогательные методы:

        public static MvcHtmlString EmbeddedImage(this HtmlHelper htmlHelper, string imageName, dynamic htmlAttributes)
    {
        UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
        var anchor = new TagBuilder("img");
        anchor.Attributes["src"] = url.Action("GetEmbeddedResource", "Shared",
                                              new
                                                  {
                                                      resourceName = "Namespace.Content.Images." + imageName,
                                                      pluginAssemblyName = url.Content("~/bin/Namespace.dll")
                                                  });

        if (htmlAttributes != null)
        {
            string width = "";
            string height = "";
            PropertyInfo pi = htmlAttributes.GetType().GetProperty("width");
            if (pi != null)
                width = pi.GetValue(htmlAttributes, null).ToString();

            pi = htmlAttributes.GetType().GetProperty("height");
            if (pi != null)
                height = pi.GetValue(htmlAttributes, null).ToString();

            if (!string.IsNullOrEmpty(height))
                anchor.Attributes["height"] = height;

            if (!string.IsNullOrEmpty(width))
                anchor.Attributes["width"] = width;
        }
        return MvcHtmlString.Create(anchor.ToString());
    }

Наконец, мой общий контроллер:

        [HttpGet]
    public FileStreamResult GetEmbeddedResource(string pluginAssemblyName, string resourceName)
    {
        try
        {
            string physicalPath = Server.MapPath(pluginAssemblyName);
            Stream stream = ResourceHelper.GetEmbeddedResource(physicalPath, resourceName);
            return new FileStreamResult(stream, GetMediaType(resourceName));
            //return new FileStreamResult(stream, GetMediaType(tempResourceName));
        }
        catch (Exception)
        {
            return new FileStreamResult(new MemoryStream(), GetMediaType(resourceName));
        }
    }

    private string GetMediaType(string fileId)
    {
        if (fileId.EndsWith(".js"))
        {
            return "text/javascript";
        }
        else if (fileId.EndsWith(".css"))
        {
            return "text/css";
        }
        else if (fileId.EndsWith(".jpg"))
        {
            return "image/jpeg";
        }
        else if (fileId.EndsWith(".gif"))
        {
            return "image/gif";
        }
        else if (fileId.EndsWith(".png"))
        {
            return "image/png";
        }
        return "text";
    }

Помощник ресурса:

    public static class ResourceHelper
{
    public static Stream GetEmbeddedResource(string physicalPath, string resourceName)
    {
        try
        {
            Assembly assembly = PluginHelper.LoadPluginByPathName<Assembly>(physicalPath);

            if (assembly != null)
            {
                string tempResourceName = assembly.GetManifestResourceNames().ToList().FirstOrDefault(f => f.EndsWith(resourceName));
                if (tempResourceName == null)
                    return null;
                return assembly.GetManifestResourceStream(tempResourceName);
            }
        }
        catch (Exception)
        {

        }

        return null;
    }
}  

Помощник плагина

public static T LoadPluginByPathName<T>(string pathName)
{
    string viewType = typeof(T).GUID.ToString();

    if (HttpRuntime.Cache[viewType] != null)
        return HttpRuntime.Cache[viewType] is T ? (T)HttpRuntime.Cache[viewType] : default(T);

    object plugin = Assembly.LoadFrom(pathName);
    if (plugin != null)
    {
        //Cache this object as we want to only load this assembly into memory once.
        HttpRuntime.Cache.Insert(viewType, plugin);
        return (T)plugin;
    }

    return default(T);
}

Помните, что я использую их как встроенный контент!

Ответ 2

Насколько я знаю, вы не можете этого сделать, поскольку путь будет за пределами веб-сайта.

Однако вы можете сделать следующее:

1) Поместите все сценарии, которые вы хотите использовать в Common.Web\Scripts
2) Для каждого файла script в вашем веб-приложении 'Добавить как ссылку' в ваши скрипты Common.Web(вам даже не нужно сделайте этот шаг, однако приятно видеть, какие сценарии используются вашим веб-приложением в VS)
3) Добавьте событие post-build в ваше веб-приложение, которое копирует сценарии из Common.Web\Scripts в папку WebApp\Scripts:

copy $(ProjectDir)..\Common.Web\Scripts * $(ProjectDir)\Scripts

поэтому с вашей точки зрения в Visual Studio у вас будет только одно место для обновления ваших .js файлов, которые могут использоваться несколькими проектами.

Ответ 3

Вместо использования Url помощника используйте относительную адресацию. То, что вы пытались сделать, не имеет смысла, поскольку помощник используется для разрешения путей относительно этого проекта.

Поскольку вы пытаетесь использовать ресурсы другого проекта, вполне можно предположить, что вы знаете заранее, где собираетесь развертывать каждый проект. Несмотря на то, что мне не нравится эта практика, я могу придумать для этого прагматичное решение.


Если ваши два приложения связаны с URL-адресами:

http://www.mysite.com/app1
http://www.mysite.com/Common.Web

вы могли бы обратиться следующим образом:

<script src="@Url.Content("~")/../Common.Web/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>

значение, разрешить мою корневую папку приложения, подняться на уровень и спуститься вниз по пути.

Ответ 4

Я просто нашел этот вопрос, ища тот же ответ. Благодаря предыдущим плакатам, которые ясно дали понять, что это невозможно сделать с помощью только Visual Studio: вы всегда закончите с копией исходного файла или неполным набором файлов доставки.

Я не хочу изобретать велосипед, когда у меня есть простая общая функциональность, поэтому у меня есть папка для обычных скриптов на моем жестком диске: /Общие/Javascript

Мой веб-проект расположен в: /Имя_проекта

поэтому мои общие скрипты лежат вне моего веб-проекта.

Я решил это через контроль источника. Большинство репозиториев управления версиями будут иметь функциональные возможности для отображения файла в другом каталоге. Мои шаги:

  • Создать пустую папку в моем проекте VS:/ProjectName/Scripts/Common
  • Выполняется пустая папка для управления исходным кодом
  • Используя Subversion (мой исходный контроль), я настроил "extern", чтобы мой общий файл был связан с новой папкой. Другое программное обеспечение для управления версиями может называть это "ссылкой" или какой-либо другой такой вещи.
  • Обновлена ​​новая папка, и мои общие файлы Javascript вошли и теперь могут быть добавлены в мой веб-проект в Visual Studio.

Очевидно, я тестировал это, изменяя файлы в Visual Studio и фиксируя их. Изменения действительно отражались в исходных файлах, сидящих в /Common/Javascript.

Теперь я могу просто добавить extern в любой другой веб-проект, который должен использовать одну и ту же функциональность: хотя, конечно, изменение этих файлов теперь сопряжено с дополнительным риском, так как я могу неожиданно сломать другие проекты, которые их используют. Хотя я могу настроить extern для использования конкретной ревизии файла, это не то, что я хочу сделать в этот момент; Я буду ждать такой сложности, когда и когда это произойдет.