Совместное использование контроллеров и представлений с несколькими веб-приложениями - PullRequest
20 голосов
/ 26 января 2011

Я хотел бы разбить мои контроллеры и представления на отдельные библиотеки классов, чтобы их можно было повторно использовать в нескольких приложениях ASP.NET MVC 3.Часть контроллеров не была проблемой при использовании отдельной сборки, однако получение движка представления для определения местоположения было.

В итоге я использовал Скомпилируйте ваши представления Razor asp.net mvc в отдельную DLL .

Есть ли более простой способ, который я пропустил?

Ответы [ 3 ]

18 голосов
/ 10 мая 2011

Я изменил идею, опубликованную здесь , для работы с MVC3.Это было довольно быстро и легко.Единственным незначительным недостатком является то, что совместно используемые представления должны быть встроенными ресурсами и, следовательно, компилироваться.

  • Поместите ваши общие представления (файлы .cshtml, .vbhtml) в проект библиотеки.(У меня также есть некоторые общие контроллеры в этом проекте.) Если вы хотите использовать _Layout.cshtml из своего приложения, убедитесь, что вы включили _ViewStart.cshtml, который указывает на него, в ваши общие представления.

  • В проекте библиотеки установите для всех свойств представлений Build Action значение Embedded Resource.

  • В проекте библиотеки добавьте следующий код, который будет записывать содержимоеваших просмотров в каталог tmp / Views.

.

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);
    }
}

Я использую модуль записи Adrian's StreamToFile, найденный здесь .

  • В 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);
}
3 голосов
/ 24 июля 2012

Всего несколько дополнений к превосходному посту Карсона Херрика ...

  1. Вам нужно разрешить несколько ссылок (вам нужно будет включить System.Runtime.Remoting в ваш проект).

  2. Utils.SaveStreamToFile необходимо изменить на ->

    System.Runtime.Remoting.MetadataServices.MetaData.SaveStreamToFile(resStream, rootPath + fileName + "." + extension);
    
  3. Вы можете получить ошибку - представление должно быть производным от WebViewPage или WebViewPage<TModel>. Ответ здесь: Представление должно быть производным от WebViewPage или WebViewPage

  4. Когда вы развертываете проект, весьма вероятно, что вы получите ошибку при загрузке проекта. Вам нужно предоставить APP POOL, который вы используете (полный), права на папку.

3 голосов
/ 26 января 2011

Взгляните на портативные области mvc contrib: http://www.lostechies.com/blogs/hex/archive/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib.aspx Они были сделаны специально для этой цели.Если вы пойдете по этой дороге, вам понадобится меньше кода; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...