Routing IIS - Angular - Asp.Net Core - asp.net

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

Related

Routing issue in Aurelia with route params

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.

Can't add rewrite rules to web.config .net core

I have created a new web project with .net core.
The default web config looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>
When I open this config file I get a warning stating:
The element 'system.webServer' has invalid child element 'aspNetCore'.
But it let's me build and run my project.
My project is an angular application, so I want to add html5mode.
To do this, I should be able to add my rewrite rules:
<rewrite>
<rules>
<!-- AngularJS Html5model -->
<rule name="AngularJS Html5model" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
The problem is, as soon as I add my rules to my web.config file, like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<rewrite>
<rules>
<!-- AngularJS Html5model -->
<rule name="AngularJS Html5model" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>
My application stops working. It's like it can't figure out what is a static file or not. Any static file can't be found now.
Looking at the rule, it statics that any file should be redirected to "/".
Does anyone know how to fix this issue?
It appears that this is a known error and won't be fixed until the end of this year. There is a workaround though.
I needed to add a RouteBuilder to my Startup class:
var routeBuilder = new RouteBuilder(app);
routeBuilder.MapGet("{*anything}", context =>
{
context.Response.Redirect("/index.html");
return Task.FromResult(0);
});
var routes = routeBuilder.Build();
app.UseRouter(routes);
This won't work by itself, you need to add the:
services.AddRouting();
to the ConfigureServices method.
here is my Startup class in its entirety:
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRouting();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseDefaultFiles();
app.UseStaticFiles();
// Set up our images
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), #"images")),
RequestPath = new PathString("/images")
});
var routeBuilder = new RouteBuilder(app);
routeBuilder.MapGet("{*anything}", context =>
{
context.Response.Redirect("/index.html");
return Task.FromResult(0);
});
var routes = routeBuilder.Build();
app.UseRouter(routes);
}
}

Controller Action being executed by css and map files

i'm trying to integrate angularjs html5mode with my asp.net mvc application. i've done numerous searches and they pretty much all say add the following to your web.config
<modules runAllManagedModulesForAllRequests="true"/>
<rewrite>
<rules>
<rule name="AngularJS Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_URI}" pattern="api/" ignoreCase="true" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
For the most part everything is working as expected except now i notice that some file requests are triggering my controller action method to fire. for example, if i do a view source and click on any of the .css links my controller action gets executed. i'm sure there are more as well because when i add a break point it is being called multiple times.
here is my route config:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "App", action = "Index", id = UrlParameter.Optional }
);
here is an example of a url that calls my controller action
http://localhost:63952/app/assets/css/style.css
any help would be great!

How to enable $locationProvider.html5Mode for modern browser only?

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

asp.net mvc hosting angular app with html5mode and routing

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

Resources