MVC 4 — использование представлений Razor в библиотеке классов

Я пытаюсь использовать MVC 4 Razor View в проекте библиотеки классов.

Я добавил файлы Web.Config в корневую папку моей библиотеки классов и в папку представлений, но, на мой взгляд, @model по-прежнему не распознается.

Я также добавил в проект пакет Microsoft.AspNet.Mvc.

Кто-нибудь знает, как это решить?

Это мои файлы Web.Config:

1 — Папка представлений

<?xml version="1.0"?>

<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
  </configSections>

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

  <appSettings>
    <add key="webpages:Enabled" value="false" />
  </appSettings>

  <system.web>
    <httpHandlers>
      <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
    </httpHandlers>

    <!--
        Enabling request validation in view pages would cause validation to occur
        after the input has already been processed by the controller. By default
        MVC performs request validation before a controller processes the input.
        To change this behavior apply the ValidateInputAttribute to a
        controller or action.
    -->
    <pages
        validateRequest="false"
        pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <controls>
        <add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
      </controls>
    </pages>
  </system.web>

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />

    <handlers>
      <remove name="BlockViewHandler"/>
      <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
    </handlers>
  </system.webServer>
</configuration>

2 — Корневая папка

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <httpRuntime targetFramework="4.5" />
    <compilation debug="true" targetFramework="4.5" />
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers" />
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.WebPages" />
      </namespaces>
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
</configuration>

Кто-нибудь знает, что мне не хватает?

Спасибо,

Мигель


person Miguel Moura    schedule 14.09.2012    source источник
comment
Что вы имеете в виду, пытаясь запустить представление в библиотеке классов? Это не имеет смысла - я не думаю, что ваш вопрос/цель очень ясны.   -  person naspinski    schedule 15.09.2012


Ответы (2)


Ваш проект должен быть веб-приложением для правильной работы IntelliSense. Веб-приложение — это просто специальная библиотека классов.

person Max Toro    schedule 14.09.2012

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

Первая попытка

У меня самого также была библиотека классов, в которой я хотел создать некоторые элементы управления, и все же я хотел иметь рабочее Razor View с полным интеллектом. служба поддержки. Хитрость в том, что:

  1. Добавить ссылки (для MVC)
  2. Добавьте ProjectTypeGuids в .csproj (отредактируйте как текст) после ProjectGUID: <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
  3. Добавьте файл .cshtml Razor View (он не будет работать до следующих частей)
  4. Добавьте файл Web.Config (см. папку просмотра web.config)
  5. Измените выходной путь Project Properties Build на bin\ (не bin\Debug)
  6. Очистите и соберите решение

Почти готово (в комментариях упоминается проблема с папкой Bin): https://conficient.wordpress.com/2013/11/27/asp-net-razor-views-in-class-libraries/

Еще одно руководство с Bin: http://thetoeb.de/2014/01/05/enabling-mvc5-intellisense-in-a-classlibrary-project/

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


Почти готово

Если вы просто хотите, чтобы ваши представления были скомпилированы и повторно использованы в качестве проекта многими другими реальными проектами ASP.Net MVC, вместо этого вы можете просто использовать Use Razor Generator , но даже здесь вы можете не хотите создавать свой проект как библиотеку классов, потому что это просто не весело...

  1. Установите расширение VS для Razor Generator
  2. Добавить новый проект Библиотека классов
  3. Добавьте пакет NuGet в свою библиотеку для RazorGenerator.Mvc.
  4. Добавьте пакет NuGet в свою библиотеку для PrecompiledMvcViewEngineContrib.
  5. Создайте папку Views и папку с именем контроллера под ней в вашей библиотеке для виртуального пути, к которому вы хотите получить доступ как
  6. Переместите любые представления в эту новую папку \Views\ControllerName\
  7. Установите для всех этих представлений библиотеки значение Custom Tool RazorGenerator (щелкните правой кнопкой мыши свойства представления).
  8. Добавьте ссылку на вашу библиотеку из вашего реального веб-приложения ASP.Net MVC.

Оттуда у меня часто возникают проблемы. Я застряну в С# 2.0, если не добавлю пакет nuget Microsoft.CodeDom.Providers.DotNetCompilerPlatform. Это для 4.5, поэтому для 4.6.x можно изменить новый раздел codedom в app.config на

  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701">
        <providerOption name="CompilerVersion" value="v4.0"/>
      </compiler>
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
    </compilers>
  </system.codedom>

Теперь вы можете использовать "var" как неявный тип и другие современные возможности C#.

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


Самый простой вариант

Но если вы воспользуетесь советом команды разработчиков Razor Generator и фактически установите Razor Generator поверх обычного веб-приложения MVC (просто создайте свою "библиотеку). strong>" как единое целое), то почти ничего из этой работы не нужно...

  1. Иметь основной реальный сайт MVC ASP.Net
  2. Создайте новый сайт MVC ASP.Net, который будет действовать как ваша «библиотека», чтобы вам не приходилось так много возиться с вещами.
  3. Установите пакет Nuget для RazorGenerator.MVC в «библиотеку»
  4. Установите пакет Nuget для PrecompiledMvcViewEngineContrib в «библиотеку»
  5. Переместите представления в аналогичную структуру в библиотеке и пометьте как Custom Tool RazorGenerator.
  6. Ссылайтесь на свою «библиотеку» с основного сайта, и так все будет работать с меньшими трудностями.

Прелесть в том, что в вашей указанной «библиотеке» есть код запуска приложения, который будет запускаться при запуске вашего основного приложения и который зарегистрирует PreCompiledViewEngine, который знает о виртуальных путях, а не только о физических путях. Затем ваши представления пользовательского инструмента RazorGenerator определят свой виртуальный путь, и когда путь представления будет разрешен, он сможет их найти.


Хороший справочник по теме: https://www.c-sharpcorner.com/UploadFile/97fc7a/article-precompiled-razor-view-using-razorgenerator-mvc-and/

person Greg    schedule 23.03.2019
comment
Если вы находитесь на этом пути, может пройти совсем немного времени, прежде чем вы захотите так или иначе расширить возможности базового типа страницы Razor. Базовый тип страницы можно изменить через web.config ‹pages pageBaseType=System.Web.Mvc.WebViewPage› haacked.com/archive/2011/02/21/ - person Greg; 23.03.2019