ASP.NET Core 2.1 Angular 6.0 SPA шаблон - страница бритвы (cshtml) для индекса вместо статической страницы - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь перенести приложение ASP.NET Core 2.0 Angular 5 с настройкой webpack на ASP.NET Core 2.1 Angular 6 с Angular-Cli.

Краткий вопрос:

Как я могу принудительно выполнить разбор директив бритвенных страниц из cshtml с Microsoft.AspNetCore.SpaServices.Extensions?

Я не хочу использовать index.html из Angular.json, но index.cshtml.

Длинное описание:

Я начал новыйПроект ASP.NET Core от Угловой шаблон .Есть немало вещей, которые просто волшебным образом работают.

  1. В папке ClientApp/src находится файл index.html, который автоматически обслуживается при запуске приложения.
  2. При запуске приложения до тега </body> из index.html (изпервый пункт) вставлено несколько скриптов: inline.bundle.js, polyfills.bundle.js, vendor.bundle.js, main.bundle.js и styles.bundle.css до тега </head>.

Я не уверен, кто вставил эти скрипты, но я хочу вставить их на страницу Razor (cshtml).

Я пытался использовать код из своего старого проекта:

<!DOCTYPE html>
<html>
<head>
    <base href="/" />
    <title>@ViewData["Title"]</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
@{string googleAnalyticsId = Html.Raw(ViewData["GoogleAnalyticsId"]).ToString();}
@if (!string.IsNullOrEmpty(googleAnalyticsId))
{
    <script>
        (function(i, s, o, g, r, a, m)
        {
           ...
        })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');

        ga('create', '@googleAnalyticsId', 'auto');
    </script>
}
<script>
    @Html.Raw(ViewData["TransferData"])
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/0.8.2/css/flag-icon.min.css" async defer />
<script src="https://apis.google.com/js/platform.js" async defer></script>
<app>
    <!-- loading layout replaced by app after startupp -->
    <div class="page-loading">
        <div class="bar">
            <i class="sphere"></i>
        </div>
    </div>
</app>
</body>
</html>

и указывать параметры индекса в Angular.json дляthis index.cshtml:

  "architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
        "options": {
            "outputPath": "wwwroot/dist",
            "index": "Views/Home/Index.cshtml",   //<----- here

Проблема в том, что содержимое (все теги @) не обрабатывается ASP.NET Core, но выводит прямой контент:

<!DOCTYPE html>
<html>
<head>
    <base href="/" />
    <title>@ViewData["Title"]</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
@{string googleAnalyticsId = Html.Raw(ViewData["GoogleAnalyticsId"]).ToString();}
@if (!string.IsNullOrEmpty(googleAnalyticsId))
{
    <script>
...

, но это должно быть:

<!DOCTYPE html>
<html>
<head>
    <base href="/" />
    <title>Test title</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
    <script>

Я хочу напечатать некоторые переменные (из appsettings.json) в конце html-страницы.Поскольку я уже использую ASP.NET Core, страница Razor кажется хорошим решением.

Я также пытаюсь:
добавить новый RazorPage, содержимое C # (директивы @) обрабатываются, ноникто не вставляет угловые сценарии.

Ответ для AndyCunningham:

ng build --prod записывает эти файлы:

<script type="text/javascript" src="runtime.b38c91f828237d6db7f0.js"></script><script type="text/javascript" src="polyfills.2fc3e5708eb8f0eafa68.js"></script><script type="text/javascript" src="main.16911708c355ee56ac06.js"></script> 

в index.html.Как написать это на страницу бритвы.

Ответы [ 3 ]

0 голосов
/ 29 июля 2018

это старый вопрос, но я надеюсь, что ответ поможет кому-то

Что ж, сложно сделать так, чтобы веб-пакет вставлял тег скриптов в ваш index.cshtml, но вы можете включить теги в index.cshtml, например:

@{
    ViewData["title"] = "I'am from cshtml";
}
<app-root>Loading...</app-root>
<script type="text/javascript" src="/runtime.js"></script>
<script type="text/javascript" src="/polyfills.js"></script>
<script type="text/javascript" src="/styles.js"></script>
<script type="text/javascript" src="/vendor.js"></script>
<script type="text/javascript" src="/main.js"></script>

тогда вы можете маршрутизировать свой mvc как

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller}/{action=Index}/{id?}");

    routes.MapRoute(
        name: "spa-fallback",
        template: "{*url:regex(^((?!.css|.map|.js|sockjs).)*$)}",
        defaults: new { controller = "Home", action = "Index" });

});

. Убедитесь, что все маршруты, которые не соответствуют {controller} {action = Index} / {id?}, Попадают в "spa-fallback ", в котором говорится, что если файл не имеет .css или .map или .js или .sockjs, то он служит вашим домом / индексом.Необходимо, чтобы "regex" для .NET обслуживал файлы сценариев necesarys.

Последний шаг - настройка вашего angular.json для поддержки имени сценариев с помощью outputHashing: все

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "ClientApp": {
      ...
      "architect": {
        "build": {
            ...
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all", //<--add this line
                  ...
            },
            ....
  },
  "defaultProject": "ClientApp"
}

Наконец, мы можем проверить, является ли URL действительным или нет (иначе любой URL-сервер индексной страницы), который вы можете использовать в файле startup.cs, например,

app.Use(async (context, next) =>
{
    string path = context.Request.Path.Value.Substring(1);
    bool encontrado = path.EndsWith(".js") || path.EndsWith(".css") || path.EndsWith(".map") || path.StartsWith("sockjs");
    if (!encontrado)
    {
        ..use your code to check the url...
    }
    if (encontrado)
        await next.Invoke(); //<--continue
    else
    {   //send to an error404 page
        context.Response.ContentType = "text/html";
        await context.Response.SendFileAsync(Path.Combine(env.WebRootPath, "error404.html"));
    }
});

ПРИМЕЧАНИЕ. Я поместил href скриптов в абсолютное значение.путь, например, src = "/ runtime.js", хорошо в пакете json у нас может быть несколько скриптов, таких как

"scripts": {
    "ng": "ng",
    "start": "ng serve --base-href=/ --serve-path=/",
    "start:fr": "ng serve --base-href=/fr-FR/ --configuration=fr --serve-path=/fr-FR",
    "build": "ng build",
    ...
  },

Если мы используем --serve-path = fr-FR, href скрипта должен использоватьэтот путь подачи, например, src = "/ fr-FR / runtime.js"

0 голосов
/ 06 октября 2018

Я основываю этот ответ на своем опыте с расширениями React SPA, но он должен быть полезен и для Angular, так как он использует тот же самый механизм промежуточного программного обеспечения ClientApp/index.html и тот же IApplicationBuilder.UseSpa точка входа.

Проблема в том, что при использовании app.UseSpa(...) реализация по умолчанию этого расширения настраивает промежуточное ПО, которое прослушивает ВСЕ запросы интерфейса иПерейдите к index.html .

Я построил краткий пример того, как мы можем обойти это для наших проектов: https://github.com/andycmaj/aspnet_spa_without_indexhtml/pull/1/files должен показать вам, что нужно изменить, чтобы игнорироватьindex.html и используйте вместо этого бритвенное представление.

По сути, я заново реализовал то, что делает UseSpa, но без присоединения промежуточного программного обеспечения, которое перехватывает и перематывает к index.html.

Обратите внимание, что бритвенное представление Home по-прежнему должно выполнять более важные задачи, которые выполнял index.html.Наиболее важно, чтобы включало bundle.js, обслуживаемых промежуточным ПО статического контента SPA.

0 голосов
/ 21 июня 2018

Вы на правильном пути, вам все еще нужно все, что у вас есть в _layout.cshtml, но вы не изменяете Angular index.html.Вместо этого ваш Home/Index.cshtml или _layout.cshtml будет включать элемент <app-root>, а также все ваши угловые сценарии.Скорее всего, вы захотите отключить хэши в сгенерированных угловых файлах и использовать ASP.NET для аннулирования вашего JS.

Эта ссылка подробно объясняет это, но у меня все еще есть небольшие проблемы с ним в Angular 6 + ASP.NETCore 2.1: Добавление проекта Angular 5 CLI в проект ASP.Net Core 2.0

...