I'm working on a project where i want to build a REST Api and an angular2 Frontend in one project with VS2015 as a MVC/Webapi Project.
Project settings and folder structure:
In my VS solution i created a new ASP.NET Web Application project using following settings:
In the root of my project i added a new folder called Public
where the whole frontend source will be.
For my angular2 Frontend i'm using angular/angular2-seed as a starting point.
In my Public
Folder the actual webapp will therefore be in another folder called dist
and might look like this:
while my VS solution looks like this:
My Goal:
Now, when running an IIS server at http://localhost/
i want to achieve that
- my REST Api will be targeted at
http://localhost/api/...
(just for information, not really a problem at this point) - every other route will be targeting at my
index.html
located in the folder/Public/dist/
now to the tricky parts:
- i want the URL to be pretty, so in my browsers addressbar it should show
http://localhost/
while every other segment should be handled by the router of my angular2 application. For example i have a componentdashboard
sohttp://localhost/dashboard
should be routed to myindex.html
file by IIS where angular2 router will kick in to show the corresponding.html
file of the component. - i don't want to relocate parts of my frontend code / markup to another file (for example to create a
Index.cshtml
inViews/Home
or something like that - at last, i don't want the frontend developer (me ^^) ever worry again about where my app is put in whatever envorinment which means i don't want to touch the
<base href>
tag in myindex.html
which should always look like this<base href="/">
. I don't know if this is possible, but i definitely don't want to put/public/dist/
there.
What i've tried so far:
Now just starting the project would end up in a messed up behaviour, because i had to navigate manually to http://localhost/public/dist/
which will then open my app and navigate to something like http://localhost/public/dist/dashboard
. A refresh would break it, cause this route wouldn't be found.
First real approach was to use url mapping as suggested here in an answer: How can I configure a route for WebApiConfig to redirect some requests to static html page?
<urlMappings enabled="true">
<add url="~/" mappedUrl="~/Public/dist/index.html" />
</urlMappings>
Well, didn't work. Okay it routed to the app by itself, but the URL still looked ugly and some more stuff was broken.
After that i tried the RouteConfig
which looked then like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "publicOverride",
url: "{*.}",
defaults: new { controller = "Public", action = "Index" }
);
}
}
In my PublicController
i tried several methods to return my index.html for example
public ActionResult Index()
{
var result = new FilePathResult("~/Public/dist/index.html", "text/html");
return result;
}
This would work if i change the <base>
tag to <base href="/Public/dist/">
which i don't want and the url would still be http://localhost/Public/dist/dashboard
. At least, in this case, refreshing would work.
I tried to change the site options in my IIS directly to point at public/dist
for this case, but this would break again the app regarding refreshing and navigating directly to something like http://localhost/dashboard
doesn't work as well.
After that i played around with several other things which could have helped, but actually didn't. For example in this question: How to route EVERYTHING other than Web API to /index.html i tried all answers, and the solution for the OP (in the edit section) as well. Yelling, throwing away computers, smashing in keyboards and screens didn't help either.
Any way to accomplish this?
**EDIT - Current Solution **
I've duplicated my index.html
as Index.cshtml
(in a Views/Home/ Folder), corrected the paths (so that each script included and the base tag has /Public/dist/
at the start) and created a HomeController which will return this View.
In my angular2 project i set the base tag to <base href="/public/dist">
, so manipulating the index.html / .cshtml is something i have to live with, i guess.
Now an important step was to add APP_BASE_HREF
to the angular2 bootstrap
function as well but with /
as the value:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
ROUTER_PROVIDERS,
provide(APP_BASE_HREF, { useValue: '/' })
]).catch(err => console.error(err));
This will get rid of the behaviour that all my urls started with http://localhost/public/dist/...
instead of starting at http://localhost/
.