asp.net mvc hosting angular app with html5mode and routing - asp.net

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

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.

ASP.NET Bundle AngularJS

I have an Empty mvc template with Angular client (plain html/js/css) with the following structure.
To achieve bundling and minification, I did the steps from this article.
My RegisterBundles method has the following rules:
public static void RegisterBundles(BundleCollection bundles)
{
//bundles.Add(new ScriptBundle("~/bundles/js").IncludeDirectory(
// "/App/","*.js", true));
bundles.Add(new StyleBundle("~/bundles/styles.css").Include(
"/Content/*.css"));
bundles.Add(new ScriptBundle("~/bundles/app.js").Include(
"~/App/app.modules.js")
.IncludeDirectory("~/App/Components/", "*Module.js", true)
.IncludeDirectory("~/App/Components/", "*Service.js", true)
.IncludeDirectory("~/App/Components/", "*Controller.js", true));
}
To link these bundles, I put this into Index.html:
<link href="/bundles/styles.css" rel="stylesheet"/>
<script src="/bundles/app.js" type="text/javascript" language="text/javascript"></script>
Update
I updated the Rewrite rule in the web.config file
<system.webServer>
<httpErrors errorMode="Detailed" />
<asp scriptErrorSentToBrowser="true"/>
<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" />
<add input="{REQUEST_URI}" negate="true" pattern="^/bundles/styles$" ignoreCase="true"/>
<add input="{REQUEST_URI}" negate="true" pattern="^/bundles/app$" ignoreCase="true"/>
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
And I still don't get the bundle. I get 404 not found and this
It appeared that I didn't have the "Bundle module" in IIS (IIS => Your website => Modules), and ALSO the issue with WebGrease package in angular project. So the solution was:
1. In Package manager console execute: Update-package webgrease
2. In web.config make sure to have section:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="BundleModule"/>
<add name="BundleModule" type="System.Web.Optimization.BundleModule"/>
</modules>
</system.webServer>

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!

Modify and redirect for not found URl in web api

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

URL Rewrite Default Document Web Page to SEO URL

I have started using ASP.NET Routing for my site. I have been registering routes via the Application_Start() in my Global.asax file.
i.e.
routes.MapPageRoute("ROUTE-ABOUT", "about", "~/About.aspx");
routes.MapPageRoute("ROUTE-CONTACT", "contact", "~/Contact.aspx");
//etc...
This is working perfectly for the About and Contact pages.
What I Want:
My home page is Home.aspx and what I wanted to do is rewrite anyone that visits
http://localhost/mysite.com/Home.aspx
to
http://localhost/mysite.com/Home
What I've Tried
I have my site running in my local IIS v7.5 on my machine (full
administrator privileges).
I have added the following to my Web.config
Web.config
<rewrite>
<rules>
<rule name="HOMETOSEO" stopProcessing="true">
<match url="Home\.aspx" />
<action type="Redirect" url="home" appendQueryString="false" />
</rule>
</rules>
</rewrite>
Thanks in advance
After hours of trying to get this to work I eventually managed to get it working using the following entry in the Web.config and Application_Start() of the Global.asax file:
Web.config
<rewrite>
<rules>
<rule name="default" enabled="true" patternSyntax="ECMAScript" stopProcessing="false">
<match url="(.*)Home\.aspx" ignoreCase="true" />
<action type="Redirect" url="home" appendQueryString="false" />
</rule>
<rule name="lower" enabled="true" patternSyntax="ECMAScript" stopProcessing="true">
<match url="[A-Z]" ignoreCase="false" />
<action type="Redirect" url="{ToLower:{URL}}" />
</rule>
</rules>
</rewrite>
Global.asax
protected void Application_Start(object sender, EventArgs e)
{
//...
BuildStaticRoutes(RouteTable.Routes);
//...
}
public void BuildStaticRoutes(RouteCollection routes)
{
//...
routes.MapPageRoute("ROUTE-HOME", "home", "~/Home.aspx");
//...
}
If you are using IIS v7.5 you can add this in web.config
<system.webServer>
<rewrite>
<rules>
<rule name="HOMETOSEO" stopProcessing="true">
<match url="^Home" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="Home.aspx" />
</rule>
</rules>
</rewrite>
</system.webServer>
When you type http://mysite.com/Home, it will display http://mysite.com/Home.aspx. Is that what you are after or the other way around?
You can do it using a custom route by inheriting from RouteBase - so in your case it would look something like this
public class HomeRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
if (httpContext.Request.Url.ToString().ToLower().Contains("home.aspx"))
{
httpContext.Response.Status = "301 Moved Permanently"; //Optional 301 redirect
httpContext.Response.RedirectLocation = "Home";
httpContext.Response.End();
}
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
And then in you register routes you would have
routes.Add("HomeUrl", new HomeRoute());
So that any request to /Home.aspx would automatically redirect to /Home - obviously with a bit of extra work you could make this a bit more generic for any .aspx request.

Resources