Reputation: 2991
I am currently using Angular version 1.6.4.
To solve the hashbang
issue I was having, where all of my URL's were in this format:
http://localhost:8885/#/hotels/holiday-inn
My app.js
including the router (using ui-router
):
$urlRouterProvider.otherwise('/');
$locationProvider.hashPrefix('');
$locationProvider.html5Mode(true);
$stateProvider
.state('index', {
url: '/',
templateUrl: 'index.html',
controller: 'hotelController'
})
.state('login', {
url: '/hotel/:name',
templateUrl: 'views/hotel.html',
controller: 'hotelController'
});
My ui-view
is located in Index.cshtml
(I've previously had everything in _Layout.cshtml
but moved everything to Index.cshtml
):
<!DOCTYPE html>
<html ng-app="hotelScheduler">
<head>
<meta charset="utf-8" />
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Application</title>
<link href="~/css/bootstrap.min.css" rel="stylesheet" />
<script src="~/lib/angular/angular.min.js"></script>
<script src="~/lib/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="~/js/app.js"></script>
<script src="~/js/hotelController.js"></script>
</head>
<body>
<div ui-view>
</div>
</body>
</html>
Now I'm having a different problem. If I access http://localhost:8885/hotel/holiday-inn
, I get a 404
.
Why is this happening?
Additional troubleshooting:
If I access http://localhost:8885/#/hotel/
, it shows index.html
rather than views/hotel.html
and changes the address to http://localhost:8885/#%2Fhotel%2F
. (I understand this is the work of otherwise
in the routing, but why does it work with a URL with which starts a hashbang?)
I've been asking around and looking online and people suggest the rest is done through C#'s MapRoute
or Server Side Code.
How would I do this via either option? If I were to do this Server Side, how do I do this via ASP.Net Core and Visual Studio?
Here's my current MapRoute
:
app.UseMvc(config =>
{
config.MapRoute(
name: "Default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "App", action = "Index" }
);
});
ANOTHER EDIT: Based on commented suggestions and https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode, I've tried adding this code to my web.config for a server rewrite:
<system.webServer>
<rewrite>
<rules>
<rule name="Main Rule" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
But now, absolutely everything just redirects to the root/home page: localhost:8885/
.
Any help?
Upvotes: 3
Views: 1462
Reputation: 143
I was facing similar issue with AngulaJS SPA, I could resolve with the following code:
Startup.cs
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
{
context.Request.Path = "/index.html";
await next();
}
})
.UseDefaultFiles(new DefaultFilesOptions { DefaultFileNames = new List<string> { "index.html" } })
.UseStaticFiles()
.UseMvc();
Index.html
<base href="/" />
and while referencing static files under wwwroot folder use a forward slash
<script src="/app.js"></script>
<script src="/app/services/auth.service.js"></script>
app.js
$stateProvider
.state('home', {
url: '/',
templateUrl: '/index.html',
controller: 'HomeController',
controllerAs: "vm"
});
$locationProvider.html5Mode({
enabled: true,
requireBase: true
});
$urlRouterProvider.otherwise('/stores');
url rewrite in web.config does not work anymore with latest ASP.NET core, you can remove that code from web.config.
if you are using MVC, you can try with the following code, though I haven't
app.UseStaticFiles()
.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}");
routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
});
Upvotes: 1
Reputation: 6366
<base>
tag to be present.via the docs:
If you configure $location to use html5Mode (history.pushState), you need to specify the base URL for the application with a tag or configure $locationProvider to not require a base tag by passing a definition object with requireBase:false to $locationProvider.html5Mode():
The fix is to update your $locationProvider
code to this:
$locationProvider.html5Mode({
enabled: true,
requireBase: true
});
And then, inside of your <head>
, set your <base>
accordingly.
The most common pattern is /
, but your application might requires assets to be accessed from a different folder.
<head>
<base href="/">
...
</head>
Or, if you want to be clever, like https://plnkr.co does for bootstrapping Angular plunks:
<head>
<script>document.write('<base href="' + document.location + '" />');</script>
</head>
Upvotes: 1