Using Aurelia CLI 0.32, I have this route config
public configureRouter(config: RouterConfiguration, router: Router): void {
this.router = router;
config.options.pushState = true;
config.options.root = '';
config.map([
{ route: ['', 'home'], name: "home", moduleId: 'home/index', title: 'Main page' },
{ route: 'editroute/:id', name: "editroute", moduleId: 'edit/index', title: 'Edit Page' }
]);
config.fallbackRoute('');
}
Using a link
<a route-href="route: editroute; params.bind: {id:item.id}">Edit ${item.name}</a>
I can navigate to the route. But refreshing the page in the browser causes an error as seen in the screenshot
It is running on asp.net and there is a rewrite rule to support pushstate
<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" />
<add input="{URL}" matchType="Pattern" negate="true" pattern=".*\/((api|signalr)\/.*|loaderio.*)" ignoreCase="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
What am I doing wrong?
Thanks
EDIT: This error only occurs on routes with routeparameters
In order for server-side page refresh to work when you are on deep URL, you have to modify your aurelia_project/aurelia.json to use absolute paths when bundling modules:
{
"build": {
"targets": [
{
// ...
"baseUrl": "/scripts",
"useAbsolutePath": true
}
],
// etc...
Another place, which is maybe not necessary to change, but contains same properties is:
{
"platform": {
// ...
"baseUrl": "/scripts",
"useAbsolutePath": true
}
Also, make sure you test Internet Explorer 11, since it's more picky then other browsers.
Of course, as already mentioned, you will also have to make sure that you use absolute paths for other resources as well (/scripts/vendor-bundle.js, font paths, etc..)
1st step is to try to change relative path to scripts/vendor-bundle.js to absolute /scripts/vendor-bundle.js
If it won't fix your problem - it will at least prevent downloading all the scripts for every route (-:
The rule is at fault. Since your html asks for a script with a relative path - the server looks in "the directory" and there is no file. So it gives up your index.html (or whatever is served # the root of site) instead of the script.
Related
I'm posting this message because I didn't find any workable answer.
I'm developing a web site using Angular 6, Asp.net Core 2.2 and IIS 10.
My problem concerns the routing when directly imputing the address in the Browser url input area. Using the website, inside navigation, everything is working properly.
My website plan is:
/
--> /upload
--> /admin
----> /admin/admincreateuser
----> /admin/manageuserlicencepanel
Here are my settings:
Angular 6
export const appRoutes: Routes = [
{
path: 'upload',
runGuardsAndResolvers: 'always',
canActivate: [AuthGuard],
children: [
{path: '', component: UploadComponent, data: {roles: ['Customer']} },
]
},
{
path: 'admin',
runGuardsAndResolvers: 'always',
canActivate: [AuthGuard],
children: [
{path: '', component: AdminComponent, data: {roles: ['Admin', 'Moderator']}},
{path: 'admincreateuser', component: AdminCreateUserComponent, data: {roles: ['Admin', 'Moderator']}},
{path: 'manageuserlicencepanel', component: ManageUserLicencePanelComponent, data: {roles: ['Admin', 'Moderator']}}}}
]
},
{path: '', component: HomeComponent},
{path: '**', redirectTo: '', pathMatch: 'full'}
];
ASP.Net Core 2.2
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc(routes =>
{
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller="FallbackController", action = "Index"}
);
}
}
FallbackController.cs
public class FallbackController : Controller
{
public IActionResult Index()
{
return PhysicalFile(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "index.html"), "text/HTML");
}
}
This configuration is working properly even on IIS deployement. But it's impossible to input directly the url ( i.e https://www.dzfzx.com/upload ) in the address bar because I get a 404 error.
To solve this I've tried to add URL Rewrite in IIS like this
<system.webServer>
<rewrite>
<rewriteMaps>
<rewriteMap name="^(.*)$" />
</rewriteMaps>
<rules>
<rule name="All routes" stopProcessing="true">
<match url="^(.*)$" />
<action type="Rewrite" url="/" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_URI}" pattern="/api(.*)$" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_URI}" pattern="^api/" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
By implementing that I get directly on home page an error:
Uncaught SyntaxError: Unexpected token <
Notice also that it seems I never fallback in my FallbackController which seems to be not normal.
Have you an idea on how I can make it work ( Direct address bar inputing ) ?
Thanks.
It seems like your configuration is bad. You should direct all requests to index.html, which is angular's index file.
Try this configuration:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes" 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="./index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Deploy an Angular Application to IIS
I'm following this article (the bottom section about using the URL Rewrite). My IIS Express (launched from VS) config file seems to be located C:\Users[usernamehere]\documents\IISexpress\applicationhost.config.
I place the rewrite rule inside the <system.webServer> tag like that article (and a lot of other articles I've read) say to. So it looks like:
<system.webServer>
<rewrite>
<rules>
<rule name="angularjs routes"
stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}"
matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}"
matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}"
pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
... all the other crap that was already there
</system.webServer>
In my VS project I have index.htm off the root and my test views under a Views folder. This is the index.htm and it works when I click the link just fine.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<head>
<base href="/">
<title></title>
<meta charset="utf-8" />
</head>
<body ng-app="myApp">
<p>Main</p>
Red
Green
Blue
<!-- below is where the partial pages will replace -->
<div ng-view></div>
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("/red", {
templateUrl: "Views/red.htm",
controller: "redController"
})
.when("/green", {
templateUrl: "Views/green.htm",
controller: "greenController"
})
.when("/blue", {
templateUrl: "Views/blue.htm",
controller: "blueController"
});
$locationProvider.html5Mode(true);
});
app.controller("redController", function($scope){
//alert("Red");
});
app.controller("blueController", function ($scope) {
//alert("Blue");
});
app.controller("greenController", function ($scope) {
//alert("Green");
});
</script>
</body>
</html>
The problem comes when I try to type in one of those pages direction: ie. http://localhost:60553/red
I get a 404. Which tells me that rewrite rule isn't being hit and doing it's job. Why am I getting a 404 even with that rewrite rule?
I am guessing this is because your Views folder has a web.config that explicitly blocks request to it. That is placed there by default in MVC projects for security reasons.
Note the following code in Views/Web.Config
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
If you comment this out, your code should work.
However, I would advise moving your angular views to a different folder that isn't sort of a de-facto reserved folder for MVC. Change to something like ngView and this code will work. It will be cleaner and clearer that way, and you don't run the risk of exposing your razor code to snooping users.
UPDATE
The above is not the issue, per comments. The issue is that the rewrite rules were not being used from the file mentioned. Move them to web.config if possible - that will avoid setting up global rules that will apply to all iis express apps anyway.
I'm working on the web app using ASP.Net 5 and AngularJS. I have completed it and it works great, but when it was released live I found out it doesn't work in IE9 which is a big part in our company.
I'm using ui-router and I was fallowing Stephen Walter tutorial for the client routing: link here
Unfortunately his method to remove # from the URL works only for IE10+, because IE9 do not support HTML5 History API.
Spend few days on this one already and cannot find what step I have to keep using clean url for the modern browsers but not IE9?
My web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<rewrite>
<rules>
<!--Redirect selected traffic to index -->
<rule name="Index Rule" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600" forwardWindowsAuthToken="true" />
</system.webServer>
</configuration>
My app.js:
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', '$sceDelegateProvider',
function ($stateProvider, $urlRouterProvider, $locationProvider, $sceDelegateProvider) {
$locationProvider.hashPrefix('!').html5Mode({
enabled: true,
requireBase: false
});
$stateProvider
.state('app', {
abstract: true,
url: '',
templateUrl: '/templates/appcontainer.html',
controller: 'indexController'
})
.state('app.stateIndex', {
url: '/',
templateUrl: '/templates/list.html',
controller: 'dashListController'
})
.state('app.stateList', {
url: '/list',
templateUrl: '/templates/list.html',
controller: 'dashListController'
})
.state('app.stateDashboard', {
url: '/dashboard/:id',
templateUrl: '/templates/dashboard.html',
controller: 'dashboardController'
})
});
When I launch it in IE9, a blank page is displayed and when I check the source code index.html is loaded, but the content of <ui-view class="main-view"></ui-view> is not.
what step I have to keep using clean url for the modern browsers but not IE9?
Use a conditional statement in the config block to exclude IE9 from html5Mode via feature detection. For example:
if(!!$window.innerWidth && !$window.matchMedia)
{
$locationProvider.html5Mode({enabled: false, requireBase: false});
$locationProvider.hashPrefix("search");
}
else
{
$locationProvider.html5Mode({enabled: true, requireBase: false});
}
References
angular.js issue 10002: ng-controller on <html> tag fails on IE9
I enabled Html5 mode in angular for my project witch convert my URl from
A: qwe.com/#/products
to
B: qwe.com/products
But the problem is in this case if user trying to directly go to B, server (web api) catch the Url and return not found error so I need a way to catch all not found in server add a # sign to that and redirect to new Url but how should I do it?
Update:
Thanks to #Travis Collins
In Global.asax
private const string ROOT_DOCUMENT = "/index.html";
protected void Application_BeginRequest( Object sender, EventArgs e )
{
string url = Request.Url.LocalPath;
if ( !System.IO.File.Exists( Context.Server.MapPath( url ) ) )
Context.RewritePath( ROOT_DOCUMENT );
}
You need to do the rewrite on your server end for this. This will make the web server still serve your index.html file even when a request comes in for /products or anything else. In IIS for example, you would do this in web.config:
<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>
Lots of other servers are explained here:
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
Alright, so I am hosting an angularjs inside asp.net mvc 5 and are using the html5mode(true) in my angular app to get rid of all hash signs in the url.
Everything works great, however, with my current setup that looks like this:
RouteConfig.cs:
routes.MapRoute(
name: "Default",
url: "app/{angular}",
defaults: new { controller = "Ng", action = "Index", angular= UrlParameter.Optional }
);
So that when I navigate to http://url/app/myangularroute my Ng/Index action returns the view which contains the ng-view container and the angular app is now active and working with the route provided
Now, my problem here is, when I navigate to http://url/app/ it returns a dir listning not allowed error which I cannot understand. Shouldn't my index action be returned as the angular parameter is set to optional?
And can I somehow avoid the "app" completely and still get my angular app to work? I have tried some rewrite rules but that gives me alot of errors because I am making use of the mvc bundling and minification functionality.
I could live with the url being the format it currently is but without the need to provide the optional parameter, like http://url/app/
Also, it's only an angular app, no other mvc view than the index.cshtml wrapper.
This guy seems to get it to work, but I can't see his mvc routes
Try adding this in your web.config sytem.webserver settings.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<system.webServer>
EDIT:
Try changing your RouteConfig.cs, like this:
routes.MapRoute(
name: "Default",
url: "app/{*.}",
defaults: new { controller = "Ng", action = "Index" }
);
EDIT2:
I had completely forgoten about this question, but now I just realized that maybe the problem is that you haven't configured your IIS Server to work with Html5Mode, have a look at this: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
Concretelly this part:
Azure IIS Rewrites:
<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>
I hope that this helps.
This is my solution. I am using ASP.NET MVC + Web API.
ASP.NET MVC always returns the same HTML page for any URL, so AngularJS can take over in $locationProvider.html5Mode(true);
RouteConfig.cs
routes.MapRoute(
name: "Default",
url: "{*anything}",
defaults: new
{
controller = "Home",
action = "Index",
}
);
WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}/{id1}",
defaults: new
{
action = RouteParameter.Optional,
id = RouteParameter.Optional,
id1 = RouteParameter.Optional,
}
);
HomeController.cs
public ActionResult Index()
{
return File("~/index.html", "text/html");
}
Alright, I got it to work.
By doing this:
Remove the "app" route completely, and use the standard route.
Add the rewrite rule
Remove the base href from the layout
Ohh wow, I turned off the bundling and minification, that was actually what made it work in the end. When I turn it on I get an angular error.
I honestly thought I tried this like 10 times without success. It started to show signs of working when I removed the base href.
Old question but still valid, this is my solution :
<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" />
<!--for local dev enviroment-->
<add input="{REQUEST_URI}" pattern="^/(__browserLink)" negate="true" />
<!--if the url does not match a valid file we don't want it to be redirected to the index page-->
<add input="{REQUEST_URI}" pattern="\.(png|jpg|gif|css|js|html)$" negate="true" />
<!--web api route-->
<add input="{REQUEST_URI}" pattern="^/api/" negate="true" />
<!--ASP.NET Web API Help Page-->
<add input="{REQUEST_URI}" pattern="^/Help" negate="true" />
<!--Swagger-->
<add input="{REQUEST_URI}" pattern="^/apimap" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
With my ASP.NET 5 RC site - has WebAPI but not MVC - the solution was to up a default rewrite rule in wwwroot\web.config's system.webserver tag:
<rewrite>
<rules>
<clear />
<rule name="API" stopProcessing="true">
<match url="^(api)(.*)$" />
<action type="None" />
</rule>
<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>
I am facing the same problem, i have set the base href in layout.cshtml ,put the webconfig rewrite rule, when loading the app,In bundle config i have set the all the scripts and css when launch the app ,its not get loaded . unexpected syntax error < is displayed in console.
when i remove the rule and base href and location provider is false , it working fine .
Angular Js Strange issue Ui Router Html5mode enabled page refresh issue in mvc 500 error