2016-01-06 5 views
18

Угловая 2 бета-версия использует html5 маршрутизацию по умолчанию. Однако при переходе к компоненту и изменениям маршрута (например, http://localhost:5000/aboutus) и вы перезагружаете/обновляете страницу, ничего не загружается.ASP.NET 5 + Угловая 2 маршрутизация (страница шаблона не загружается)

Вопрос был поднят в этом post также. Большинство ответов говорят, что если мы будем проводить маршрутизацию HTML5 в угловом 2, то эту проблему маршрутизации следует заботиться на стороне сервера. Другие обсуждения here.

Я не уверен, как справиться с этой проблемой, используя среду сервера asp.net.

Любые угловые 2 разработчики, которые также используют asp.net и сталкиваются с этой проблемой?

PS. Я использую ASP.NET 5. Мои маршруты Angular 2 используют маршруты MVC.

+0

Вы решаете эту проблему? У меня такая же проблема. – Jenan

ответ

15

Проблема, которую вы видите, связана с разницей между Угловой маршрутизацией на стороне клиента и маршрутизацией на стороне сервера MVC. Фактически вы получаете ошибку 404 Page Not Found, потому что у сервера нет контроллера и действия для этого маршрута. Я подозреваю, что вы не обрабатываете ошибки, поэтому кажется, что ничего не происходит.

При перезагрузке http://localhost:5000/aboutus или если вы попытаетесь установить ссылку на этот URL непосредственно из ярлыка или, введя его в адресную строку (глубокую ссылку), он отправит запрос на сервер. ASP.NET MVC попытается решить этот маршрут, и в вашем случае он попытается загрузить aboutusController и выполнить действие Index. Конечно, это не то, что вы хотите, потому что ваш маршрут aboutus является угловым компонентом.

Что нужно сделать, так это создать способ для маршрутизатора ASP.NET MVC передавать URL-адреса, которые должны быть разрешены Угловым обратно клиенту.

В файле Startup.cs, в методе Configure(), добавьте «спа-запасной вариант» маршрут к существующим маршрутам:

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

    // when the user types in a link handled by client side routing to the address bar 
    // or refreshes the page, that triggers the server routing. The server should pass 
    // that onto the client, so Angular can handle the route 
    routes.MapRoute(
     name: "spa-fallback", 
     template: "{*url}", 
     defaults: new { controller = "Home", action = "Index" } 
    ); 
}); 

Создав кетчуп все маршрут, который указывает на контроллер и вид, что в конечном счете загружает ваше приложение «Угловое», это позволит URL-адресам, которые сервер не обрабатывает, для передачи на клиент для правильной маршрутизации.

+0

Это почти работает для меня, когда я ударил обновление страницы, на которой я был загружен, однако URL-адрес отбрасывается, поэтому в моем случае, если вы снова нажмете обновление, оно заканчивается обратно на мою главную страницу входа. Например: localhost/home - обновляется один раз, перезагружается, но URL-адрес в браузере теперь локально/обновляется дважды, и он перезагружает основной маршрут, расположенный на корневом пути ... любые идеи случайно? – Sean

+0

Это не работает для меня? Я получаю 404 –

+0

Хммм ... Я видел это в нескольких местах, но он не работает для меня - я все еще получаю 404 - откат пути, кажется, никогда не ударил. –

0

Использовали ли вы:

директив: [RouterOutlet, RouterLink] в компоненте.

+0

Я добавил ее во все компоненты, но все еще не работал :( –

2

Функция, которую вы ищете, это переписать URL. Есть два возможных способа справиться с этим. Классический способ это позволить IIS сделать работу, как описано здесь:

https://stackoverflow.com/a/25955654/3207433

Если вы не хотите зависеть от IIS, вы можете вместо этого обращаться с этим в ASP.NET 5 промежуточного слоя, как показано на рисунке в моем ответе здесь:

https://stackoverflow.com/a/34882405/3207433

5

вы должны использовать этот маршрут в ASP.NET MVC

app.UseMvc(routes => 
{ 
    routes.MapRoute("Default", "{*url}", new { @controller = "App", @action = "Index" }); 
}); 

Затем вам нужно S et up SystemJS с опциями basePath

+0

, который работает, но теперь, когда я обновляю, я получил следующее: после обновления: localhost/users до: localhost/users/users – jcmordan

0

применять раствор в @ ZOXEXIVO в то, в вашем _Layout.cshtml добавить следующее:

<head> 
    <base href="/"/> 
    ..... 
</had> 
8

В вашем Startup.cs добавьте к этому методу Configure. Это должно быть перед другими операциями app.

app.Use(async (context, next) => { 
    await next(); 

    if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value)) { 
     context.Request.Path = "/index.html"; // Put your Angular root page here 
     await next(); 
    } 
}); 
+0

'await next();' это то, что отсутствует в других решениях. Он намного чище, чем стиль MVC. –

4

Мое любимое решения добавить следующий код Global.asax.cs который очень плавно и надежно заботится о выпуске:

 private const string RootUrl = "~/Home/Index"; 
    // You can replace "~Home/Index" with whatever holds your app selector (<my-app></my-app>) 
    // such as RootUrl="index.html" or any controller action or browsable route 

    protected void Application_BeginRequest(Object sender, EventArgs e) 
     { 
      // Gets incoming request path 
      var path = Request.Url.AbsolutePath; 

      // To allow access to api via url during testing (if you're using api controllers) - you may want to remove this in production unless you wish to grant direct access to api calls from client... 
      var isApi = path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase); 
      // To allow access to my .net MVCController for login 
      var isAccount = path.StartsWith("/account", StringComparison.InvariantCultureIgnoreCase); 
      if (isApi || isAccount) 
      { 
       return; 
      } 

      // Redirects to the RootUrl you specified above if the server can't find anything else 
      if (!System.IO.File.Exists(Context.Server.MapPath(path))) 
       Context.RewritePath(RootUrl); 
     } 
+0

* slow clap * Это именно то, что мне нужно, чтобы помочь мне интегрировать новый спа-центр в существующий, сложный, старый сайт .NET. Мы медленно двигаемся к Angular 2 spa для всего сайта, и это было именно то, что мне нужно, спасибо. –

0

Вы можете использовать как маршрутизацию при вызове Главная/Индекс от угловой маршрутизации.

написать

Home/Index.cshtml 
<my-app></my-app> 

app.routing.ts 
    const routes: Routes = [ 
     { path: '', redirectTo: '/Home/Index', pathMatch: 'full' }, 
     { path: 'Home/Index', component: DashboardComponent } 
    ] 

Так Когда URL будет Home/Index загрузит компонент активного URL поэтому он будет загружен приборной панели компонент.

1

Вот еще два варианта решения этой проблемы. Вы можете добавить стратегию размещения хэша в свой модуль приложения.

import { LocationStrategy, HashLocationStrategy } from '@angular/common'; 

@NgModule({ 
imports: [.... ], 
declarations: [...], 
bootstrap: [AppComponent], 
providers: [ 
{ 
    provide: LocationStrategy, 
    useClass: HashLocationStrategy 
} 
] 
}) 
export class AppModule { } 

Эта опция будет работать только для части вашего приложения Angular2, которые живут на

Вашего второго варианта Главной ASP Controller является добавлением маршрутов к вашему ASP контроллеру, которые соответствуют вашим угловым 2 приложению маршрутов и возврат "индекс" Просмотр

public class HomeController : Controller 
{ 
    public IActionResult Index() 
    { 
     return View(); 
    } 

    [ActionName("Angular-Route1")] 
    public IActionResult AngularRoute1() 
    { 
     return View("Index"); 
    } 

    public IActionResult Route2() 
    { 
     return View("Index"); 
    } 
} 
1

Я не имея каких-либо удачи, получая

routes.MapRoute("Default", "{*url}", 
        new { @controller = "App", @action = "RedirectIndex" }); 

работать. Я все еще получаю 404 с любым клиентским маршрутом.

Update:
Разобрался почему всеохватывающий маршрут не работает: у меня был маршрут атрибута определен ([Route("api/RedirectIndex")]) и в то время как обычный маршрут может быть доступен непосредственно с запасным путем он Ждет» огонь. Удаление маршрута атрибута заставило его работать.

Другим решением, которое, кажется, работает так же легко, как всеобъемлющая обработчик маршрута просто создать пользовательский обработчик, который срабатывает в конце трубопровода промежуточного слоя в Configure():

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

}); 

//handle client side routes 
app.Run(async (context) => 
{ 
     context.Response.ContentType = "text/html"; 
     await context.Response.SendFileAsync(Path.Combine(env.WebRootPath,"index.html")); 

}); 

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

Это прекрасно работает даже в сочетании с IIS Rewrite rules (в этом случае выше просто не когда-нибудь уволят

написал сообщение в блоге на эту тему:

+0

Спасибо. Модернизировал мое приложение для ядра .NET, и я весь день бил свою голову, пытаясь заставить решение .NET 4.5 работать для перезаписи. Это окончательно зафиксировало это. – BBlake

Смежные вопросы