This article will show how to create an Angular web application using Angular CLI to manage the build process and dependency management, using WebPack. The latest version of Angular at this time of this article is 4.0.1. Using this technique you can integrate Angular into a new or existing Asp.Net MVC web application. Your application can either be a full Angular SPA-only application or it may also include some MVC routed pages. This sample will also use Asp.Net MVC Web API to create the REST layer data endpoints called by the Angular typescript services. All of this will be hosted in a single web application that you can deploy to any IIS-based server or to an Azure cloud service role.
These directions have also been verified with Visual Studio 2015 Community Edition.
You can certainly have an all Angular application, and there is nothing wrong with that. But there are plenty of reasons to have both in a single application. Many websites have a number of static pages and those pages may have common headers and footers easily managed with master layouts in MVC. Those layouts may have data rendered on the server, or cached in a CDN. Some projects manage this by putting the Angular app in a virtual directory sub-path of the primary domain.
Maybe you want a way to manage multiple separate SPA applications under one deployed application. You can do this by combining multiple Angular CLI SPA apps into one MVC app at build time and then deploying the combined app as one.
The most common scenario may be that you already have an Asp.Net MVC web application now, and you want to phase in an Angular CLI SPA application over time, moving a page at a time from an MVC route into the SPA application.
You can also easily accomplish this using SystemJS by following my previous Angular article series.
In my last Angular series the sample project used SystemJS in an Asp.Net MVC web application project. The series discovered some annoyances with the structure of SystemJS. First you had to remember to add new dependencies to the bootrapping code in the main cshtml razor view hosting your Angular app; and second your templateUrl and CssUrl file references in components had to take into account where the view template would be at run-time (dist folder) instead of where its relative location during development.
Angular CLI (command line interface) manages your Angular code build for development and the AOT (ahead of time) production build, manages registering all dependencies on the page automatically, helps you follow organizational guidelines with the generator CLI commands and a lot more.
What is the downside? Its a great tool for WebStorm or VS Code, but its not meant to be part of an Asp.Net MVC web application. We need to do a couple things to integrate it into the Visual Studio ecosystem. Hopefully this will be smoother in future versions, and for now this article will show you how to do the initial setup to smooth out this hopefully temporary rough edge.
The root of the problem is that Angular CLI wants to handle the entire build process and serving the app inside Express web server when in development mode. The Visual Studio ‘run’ button also does this for web applications and class libraries needed by your web application. CLI cannot manage the build of your server side C#.Net code. Visual Studio runs in IIS Express or full IIS, while Angular development mode wants to run in Express.
As noted earlier, Angular and Visual Studio both want to manage their own build process. So our solution is to let them, and combine the results mid-way. We’re going to build the Angular CLI project first, then copy the few build output files into a folder of the Asp.Net MVC web application and then Visual Studio can perform it’s build as usual and then run the project. Simple.
Ok, so the concept is easy enough, but now lets get into the detail of what kind of projects you should create. If you already have an Asp.Net MVC application, you can skip ahead to the creation of the Angular CLI project.
My first step is to create a new solution with a class library project. Be sure to keep “Create directory for solution” checked. Add it to Git source control, and build the business layer. I’m not going to walk through this step in any more detail, but you can check out the sample project.
This step will be nothing new for anyone currently developing with Asp.Net MVC. You should add a new project to the solution, I recommend template “Asp.Net Web Application (.Net Framework)”.
On the second step of the project wizard, select your type of authentication you want included with the app, and also check the box to add “Web API”, since in this example that will serve as the REST service used by the Angular CLI project.
This step uses the CLI — command line interface. The best way I’ve found to do this is via a normal windows command prompt, NOT the Visual Studio 2017 command prompt.” The Visual Studio variety does not respect your system PATH setting and thus ‘npm’ won’t be available to you.
Start by creating a Visual Studio project to hold the CLI generated project. Use ‘Add Project’ and pick ‘Asp.Net Web Application’ just like the MVC project first step, but on step 2 just select the ‘Empty’ template (not MVC or Web API). We will fill this project folder with the CLI generated content. The sample project is named ‘candor-sample-ng-cli’.
Prerequisite alert: For the next step you need to download and install NodeJS / NPM if you don’t have it already. Version 6.9 or later should work, but I have the latest Node 6.10.2 / NPM 3.10.10 at the time of this writing. I used the Windows MSI installer. Go get it here:
https://nodejs.org/en/download/
Once Node is installed, make sure you have the Angular CLI installed globally. This is done once per developer machine, not a per project step. I ran it from my solution folder, but it could be from any folder. After running this command you’ll see NPM output with dependency packages being installed
C:\Users\you\Documents\GitHub\sample-ng2-mvc> npm install -g @angular/cli@latest
Verify the CLI is installed by checking the CLI help command. After running this command you’ll see all the types of code you can generate and the options for each one.
C:\Users\you\Documents\GitHub\sample-ng2-mvc> ng --help ... ng new<options...> Creates a new directory and a new Angular app. --dry-run (Boolean) (Default: false) Run through without making any changes. aliases: -d, --dryRun --verbose (Boolean) (Default: false) Adds more details to output logging. aliases: -v, --verbose --link-cli (Boolean) (Default: false) Automatically link the `@angular/cli` package. aliases: -lc, --linkCli --skip-install (Boolean) (Default: false) Skip installing packages. aliases: -si, --skipInstall --skip-git (Boolean) (Default: false) Skip initializing a git repository. aliases: -sg, --skipGit --skip-tests (Boolean) (Default: false) Skip creating spec files. aliases: -st, --skipTests --skip-commit (Boolean) (Default: false) Skip committing the first commit to git. aliases: -sc, --skipCommit --directory (String) The directory name to create the app in. aliases: -dir <value>, --directory <value> --source-dir (String) (Default: src) The name of the source directory. aliases: -sd <value>, --sourceDir <value> --style (String) (Default: css) The style file default extension. aliases: --style <value> --prefix (String) (Default: app) The prefix to use for all component selectors. aliases: -p <value>, --prefix <value> --routing (Boolean) (Default: false) Generate a routing module. aliases: --routing --inline-style (Boolean) (Default: false) Should have an inline style. aliases: -is, --inlineStyle --inline-template (Boolean) (Default: false) Should have an inline template. aliases: -it, --inlineTemplate ... rest clipped for brevity
Now to create a new CLI project in your solution, run the ‘new’ command. This will fill in the Visual Studio generated project folder with the CLI structure.
C:\Users\you\Documents\GitHub\sample-ng2-mvc>ng new candor-sample-ng-cli --routing --skip-git --directory candor-sample-ng-cli
Since our project solution is already under Git source control, we can use the skip-git flag to tell the CLI not to generate a new Git repo for the project. The directory option will generate the CLI project in our existing Visual Studio project folder since the name of that folder is supplied.
The output shows the files created relative to the output directory specified.
installing ng create .editorconfig create README.md create src\app\app-routing.module.ts create src\app\app.component.css create src\app\app.component.html create src\app\app.component.spec.ts create src\app\app.component.ts create src\app\app.module.ts create src\assets\.gitkeep create src\environments\environment.prod.ts create src\environments\environment.ts create src\favicon.ico create src\index.html create src\main.ts create src\polyfills.ts create src\styles.css create src\test.ts create src\tsconfig.app.json create src\tsconfig.spec.json create src\typings.d.ts create .angular-cli.json create e2e\app.e2e-spec.ts create e2e\app.po.ts create e2e\tsconfig.e2e.json create karma.conf.js create package.json create protractor.conf.js create tsconfig.json create tslint.json Installing packages for tooling via npm. Installed packages for tooling via npm. Project 'candor-sample-ng-cli' successfully created.
The last 2 lines of the output take some time since they are downloading lots of packages over the internet, so just be patient and wait for it to complete. Your experience may vary if you have ‘Yarn’ package manager installed. If you wish the CLI to install packages via Yarn and configure Yarn at project setup, then you need to tell the CLI to do so by default on creation of new packages. If you wish to do that the command is as follows (to be run before ng new), and Yarn must be installed first.
C:\Users\you\Documents\GitHub\sample-ng2-mvc>ng set --global packageManager=yarn
Now you can switch over to Visual studio and include all of these generated files into the project. But do not include the node_modules folder, since those are restored by other developers using the ‘npm install’ command or by using Visual Studio’s package restore menu item.
You should now ‘serve’ the CLI project and make sure it runs.
C:\Users\you\Documents\GitHub\sample-ng2-mvc>cd candor-sample-ng-cli C:\Users\you\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli>ng serve ** NG Live Development Server is running on http://localhost:4200 ** Hash: bec42c6bef317950e4ef Time: 8356ms chunk {0} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 158 kB {4} [initial] [rendered] chunk {1} main.bundle.js, main.bundle.js.map (main) 4.92 kB {3} [initial] [rendered] chunk {2} styles.bundle.js, styles.bundle.js.map (styles) 9.77 kB {4} [initial] [rendered] chunk {3} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.64 MB [initial] [rendered] chunk {4} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry] [rendered] webpack: Compiled successfully.
As the instructions note, the app is now running and you can open it at http://localhost:4200/. Open it and you will see “Loading…” and then “app works.” To quit the server to enter further commands, press CTRL-C. You’ll be asked if you want to terminate batch job. Type ‘Y’ and press enter to confirm.
The serve command does not generate a build, rather you need to run the build command to do this.
C:\Users\you\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli>ng build Hash: 7125a86fd8201d4b0de4 Time: 7496ms chunk {0} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 158 kB {4} [initial] [rendered] chunk {1} main.bundle.js, main.bundle.js.map (main) 4.9 kB {3} [initial] [rendered] chunk {2} styles.bundle.js, styles.bundle.js.map (styles) 9.77 kB {4} [initial] [rendered] chunk {3} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.34 MB [initial] [rendered] chunk {4} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry] [rendered]
You will now have a dist folder in your project containing an index.html and a few script files with source maps. This is all you need to run the application. Don’t check in the ‘dist’ folder into source control and don’t include it in the Visual Studio project.
Now that we have the CLI project, the next step is to get the build output and package it into the main MVC application.
Open your project properties to the ‘Build Events’ tab. For the “Pre-build event command line” enter an xcopy command.
xcopy /I /E /Y "$(SolutionDir)candor-sample-ng-cli\dist" "$(ProjectDir)Scripts\NgApp"
This is a good start, but it only copies files, and doesn’t rebuild the Angular CLI project each time. Let’s add the ‘ng build’ command before the copy, and some echo statements so we know what happened afterwards.
echo "cd $(SolutionDir)candor-sample-ng-cli" &&^ cd "$(SolutionDir)candor-sample-ng-cli" &&^ echo "building candor-sample-ng-cli" &&^ ng build &&^ echo 'copy files' &&^ xcopy /I /E /Y "$(SolutionDir)candor-sample-ng-cli\dist" "$(ProjectDir)Scripts\NgApp"
This will produce output in the output window of Visual Studio each time you build the project. To be clear, this build script goes in the build process of the MVC web project and not the CLI container MVC app. This makes more sense since that is the web application to run in Visual Studio.
Note, if you have an error here about not finding the path specified, you may have your solution (.sln) file in the wrong location. In the sample project I had to move the solution file to the root, out of the Candor.Sample\ directory in order for this script to work. Normally solution files are at the root below all the project folders and this will work fine. Be sure when creating a brand new project that you keep “Create directory for solution” checked.
1>------ Build started: Project: Candor.Sample.MvcWeb, Configuration: Debug Any CPU ------ 1> "cd C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli" 1> "building candor-sample-ng-cli" 1> Hash: [1m7125a86fd8201d4b0de4[39m[22m 1> Time: [1m7325[39m[22mms 1> chunk {[1m[33m0[39m[22m} [1m[32mpolyfills.bundle.js, polyfills.bundle.js.map[39m[22m (polyfills) 158 kB {[1m[33m4[39m[22m}[1m[33m [initial][39m[22m[1m[32m [rendered][39m[22m 1> chunk {[1m[33m1[39m[22m} [1m[32mmain.bundle.js, main.bundle.js.map[39m[22m (main) 4.9 kB {[1m[33m3[39m[22m}[1m[33m [initial][39m[22m[1m[32m [rendered][39m[22m 1> chunk {[1m[33m2[39m[22m} [1m[32mstyles.bundle.js, styles.bundle.js.map[39m[22m (styles) 9.77 kB {[1m[33m4[39m[22m}[1m[33m [initial][39m[22m[1m[32m [rendered][39m[22m 1> chunk {[1m[33m3[39m[22m} [1m[32mvendor.bundle.js, vendor.bundle.js.map[39m[22m (vendor) 2.34 MB[1m[33m [initial][39m[22m[1m[32m [rendered][39m[22m 1> chunk {[1m[33m4[39m[22m} [1m[32minline.bundle.js, inline.bundle.js.map[39m[22m (inline) 0 bytes[1m[33m [entry][39m[22m[1m[32m [rendered][39m[22m 1> 'copy files' 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\favicon.ico 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\index.html 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\inline.bundle.js 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\inline.bundle.js.map 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\main.bundle.js 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\main.bundle.js.map 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\polyfills.bundle.js 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\polyfills.bundle.js.map 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\styles.bundle.js 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\styles.bundle.js.map 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\vendor.bundle.js 1> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli\dist\vendor.bundle.js.map 1> 12 File(s) copied 1> 0% compiling 10% building modules 0/1 modules 1 active ...-mvc\candor-sample-ng-cli\src\main.ts ... 1> Candor.Sample.MvcWeb -> C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\Candor.Sample.MvcWeb\bin\Candor.Sample.MvcWeb.dll ========== Build: 1 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========
–Update May 3– A problem with xcopy in the MVC web application is that any changes to the CLI project while the MVC project is running won’t be reflected in the MVC project. Depending on your team workflow this may or may not be a problem.
You can move the xcopy command to the CLI project in the packages.json file. Create a new task for copy, and another to distribute a build to the MVC app.
"name": "candor-sample-ng-cli", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", "copy": "xcopy \"dist\" \"..\\Candor.Sample.MvcWeb\\Scripts\\NgApp\" /i /s /r /y /c", "dist": "npm run build && npm run copy" },
You can run this on the command line as:
C:\Users\you\Documents\GitHub\sample-ng2-mvc>npm run dist > candor-sample-ng-cli@0.0.0 dist C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli > npm run build && npm run copy > candor-sample-ng-cli@0.0.0 build C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli > ng build Hash: ba16068dcc4018b1b749 Time: 13856ms chunk {0} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 158 kB {4} [initial] [rendered] chunk {1} main.bundle.js, main.bundle.js.map (main) 27 kB {3} [initial] [rendered] chunk {2} styles.bundle.js, styles.bundle.js.map (styles) 60.1 kB {4} [initial] [rendered] chunk {3} vendor.bundle.js, vendor.bundle.js.map (vendor) 3.55 MB [initial] [rendered] chunk {4} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry] [rendered] > candor-sample-ng-cli@0.0.0 copy C:\Users\mlang\Documents\GitHub\sample-ng2-mvc\candor-sample-ng-cli > xcopy "dist" "..\Candor.Sample.MvcWeb\Scripts\NgApp" /i /s /r /y /c dist\favicon.ico dist\index.html dist\inline.bundle.js dist\inline.bundle.js.map dist\main.bundle.js dist\main.bundle.js.map dist\polyfills.bundle.js dist\polyfills.bundle.js.map dist\styles.bundle.js dist\styles.bundle.js.map dist\vendor.bundle.js dist\vendor.bundle.js.map dist\assets\logo.png 13 File(s) copied
This is much faster than stopping Visual Studio, rebuilding and then run again and waiting for the same build and xcopy time. Its not instantaneous, since it takes a little time for the CLI build to run.
Now that the CLI build is available in the MVC web application, you can now reference it on a page. Lets do this by creating a new MVC view and controller action. The view is a copy of the generated index.html with a small tweak to file paths.
// /Controllers/HomeController.cs //Your typical default HomeController.cs with attribute routing and a few new routes [RoutePrefix("")] public class HomeController : Controller { [Route("")] public ActionResult Index() { return View("NgApp"); } [Route("trip")] [Route("location")] [Route("person")] public ActionResult AppBookmarkableRoutes() { return View("NgApp"); } [Route("about")] public ActionResult About() { ViewBag.Message = "Your application description page."; return View(); } [Route("contact")] public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); } }
The index route and the new routes to be used in the Angular app all reference the same new view to render the Angular app. If your routing isn’t working, check that your RouteConfig has enabled attribute routing.
// /AppStart/RouteConfig.cs public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapMvcAttributeRoutes(); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
The new view file is a copy of the index.html with only the paths of the script files changed to reflect where we copied them.
<!-- /Views/Home/NgApp.cshtml --> { Layout = null; } <!doctype html> <html> <head> <meta charset="utf-8"> <title>CandorSampleNgCli</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-root>Loading...</app-root> <script type="text/javascript" src="~/Scripts/NgApp/inline.bundle.js"></script> <script type="text/javascript" src="~/Scripts/NgApp/polyfills.bundle.js"></script> <script type="text/javascript" src="~/Scripts/NgApp/styles.bundle.js"></script> <script type="text/javascript" src="~/Scripts/NgApp/vendor.bundle.js"></script> <script type="text/javascript" src="~/Scripts/NgApp/main.bundle.js"></script> </body> </html>
You should be able to run the MVC application now and see your app.
The app content and features still need to be developed. But you can now edit your app in the CLI project using Visual Studio and press the ‘Run’ button in VS and see your app run. If you prefer you can also run ‘ng serve’ on the command line to run the CLI project directly such as for debugging any routing issues.
The biggest issue remaining would be creation of the production build. When Angular CLI builds for production it doesn’t generate as many script files and it embeds some more content in the index.html file. Instead of hand-jamming the production bits into place when you deploy, you may want to update the script that copies the index.html contents into the NgApp.cshtml file, or maybe just copy the files into the root folder of the MVC web app and then the contents don’t need to be modified when moving into the NGApp.cshtml.
See the followup to this project, How To Create Dynamic Menu And Page Title With Angular Material and CLI
How to create dynamic menu and page title with Angular Material and CLI
Full source of the Sample project:
https://github.com/michael-lang/sample-ng2-mvc/
Angular CLI
https://github.com/angular/angular-cli
Post/Pre build events in Visual Studio to copy files
http://stackoverflow.com/questions/11001822/copy-files-from-one-project-to-another-using-post-build-event-vs2010
Alternative: “Running Multiple Websites in a Windows Azure Web Role”
http://www.wadewegner.com/2011/02/running-multiple-websites-in-a-windows-azure-web-role/
Prerequisite: Node Installation
https://nodejs.org/en/download/
Great article and really helpful. Thanks Michael !
At first, I thought I had failed to get this right somehow, but it worked perfectly once I stopped trying to use Internet Explorer. (For reference – I saw the error “Unable to get property ‘apply’ of undefined or null reference”.)
It looks this is an issue that several people have had with Angular CLI & IE 11, so I’m off to look at “polyfills.ts” now.
Thanks that would be great. I did not know you can have mvc and Angular2 application as 2 projects and you can still work your application. Does this affect angular2 routing using the Candor.Sample.MvcWeb.?
This article is excellent! I was able to get my Angular + WebAPI environment working when previous attempts had gone very poorly. Thanks for sharing!
What did you need to do differently to get it to work with webAPI? Exactly the same but with webAPI instead of mvc?
The second problem with SystemJS is no longer an issue. They now have a file called systemjs-angular-loader.js which you can include in your SystemJS configuration. It supports component relative templateUrls and styleUrls.
Could you provide any suggestion regarding handling lazy module loading feature of angular/routes using this approach?
This is great! May I know if typescript debugging will work while running in visual studio?
Good article. I’m not using MVC but my main project is a web application with Web API. The problem is, the build process does not take place in the Web API project unless I make a change in that project or explicitly tell it to rebuild, i.e. F5 sees no changes in the Web API project and so the build does not happen, and consequently no pre-build to build and copy my Angular CLI app. Is there any way to hook the build and copy into the debug process?
Thanks very much for your excellent article. I have it all working but it is painfully slow to build and now I have to do it after each and every change. SystemJs seemed to do it so much faster and also I was able to make changes to the ts and html files while debugging in VS, all that was required was an F5 on the browser. Now each change requires a rebuild (so the new files are in NgApp) which slows down development. Maybe I’m doing something wrong or you have some suggestions to speed up the build.
Great work, Michael. I haven’t tried your steps yet, but I had mucked around with a different approach and concluded something along the lines of what you’ve written was the best bet. I’ll give it a shot here shortly, but from what I’ve read and what others have posted, it seems like you’ve hit the nail on the head–at least until the ng-cli is enhanced a bit to allow a custom server, among other things.
Visual Studio 2017. Angular cli
After this steps you can run your Asp.net MVC +Angular project also for prod. Because index.html will change links of scripts.
Structure of steps.
1.File for change
2. Description what need to do with file in the first point.
3. new code example
1. YourProjectName\.angular-cli.json
2. to do: change
3.
“outDir”: “./Scripts/app/”,
“deployUrl”: “./Scripts/app/”,
1. YourProjectName\package.json
2. to do: Add new code to package.json
3.
“scripts”: {
“ng”: “ng”,
“start”: “ng serve”,
“build”: “ng build”,
“test”: “ng test”,
“lint”: “ng lint”,
“e2e”: “ng e2e”,
“copy”: “xcopy \”Scripts\\app\\index.html\” \”Views\\Home\\NgApp.cshtml\” /i /s /r /y /c”,
“dist”: “npm run build && npm run copy”,
“distProd”: “ng build –prod && npm run copy”
},
1. YourProjectName\src\index.html
2. to do: add “layout” as first statement at the beginning. I know this step is looked strange, but it will be dynamicaly View for Asp.net MVC. ))) package.json will copy this file.
3.
@{
Layout = null;
}
1. Specify Pre-Build Events
2. to do: Right click on YourProjectName -> Properties -> build events -> Pre-build event command line box
And add text
3.
if $(ConfigurationName) == Debug (
npm run dist
) ELSE (
npm run distProd
)
I forgot a little step for [1. Specify Pre-Build Events]
Close and open Visual Studio after changing [Pre-build event command line box]. It’s important for apply changes.
So it looks as though images are not being loaded in the MVC project after the Angular application has been build and copied to the NgApp folder. Images that are used in CSS for example, as background images work fine. Those images are bundled by webpack and the load OK. I’m noticing that images associated with img tags in the html are not bundled and MVC is unable to serve them up. In the sample application {{appName}} the logo.png gives a 404.
I really like this approach and the image problem so far is my only blocker.
Thanks!
Stephen
Are your images in /src/assets in your CLI project? Is your MVC project expecting content to be served from /Content? If yes and yes, just add another script to your package.json, e.g. “copyAssets”: “xcopy \”.\\src\assets\” \”..\\YourMVCProject\\Content\” /i /s /r /y /c
I had the same problem—literally if you just copypasta the “copy” script and modify it to copy over images, you’ll be straight!
Great work, Michael! PlZ i have a problem in routes “http://localhost:4200/home ” it works even i refrech the page but when i move to “http://localhost:16408/home” and i refrech the page i had a problem “Server error in application ‘/’. The resource can not be found” PLZ how i can solve it ??
Excellent article helped a lot! I am confused on one thing though, how is the mvc project able to pick up the component directive in the NgApp cshtml file? When i try to use another directive from a new component i have created it does not show. Do i need to do something with the routing in the home controller?
Hy
I m using angular with vs code it is working on localhost:3000 it works when open it works but not working class component plz anybody can help to solve this problem?
Still getting the SystemJS error, ReferenceError: System is not defined when running SampleAngular2Mvc from your git repository https://github.com/michael-lang/sample-ng2-mvc/
Thumbs up. Thanks
Nice try and indeed I’m thinking more or less on the same direction also. Thus one thing I would like to point out, in addition to the index.chtml twist, is that if bootstrap is included in the Angular project, the glyphicon will get mess up as they are generated into the dist folder, with other script and/or generated css assuming the relative location of glyphicon font set is at the root directory of the site from the point of view of Angular..
Great great post!! One question … I’m trying to deploy the application to IIS. I publish through a folder profile, then move the folder to a server path, generate my application pool with “No managed code”, open the application in the browser but nothing appears. Install the “.NET Core Windows Server Hosting Bundle” but it still does not display anything. What am I missing ??
I ended up with 3 projects, the mocking project (library) the MVC and the AngularCLI. But your repo states 4 projects, how come?
How to deploy to azure? since both technologies have their own way of building the app
Thanks in advance,
Hi Michael,
really good tutorial. But I still having a problem.
I am trying to use this layout ( https://github.com/bonnici/light-bootstrap-dashboard-angularcli ) but Icouldn’t put it to work. It is always having some problems. Could you help me to setup it?
@Michael – Wondering if you could instead have everything in the MVC project, and have 2 folders – one for the CLI based code and another the target of the outDir (normally ‘dist’) in angular-cli.json? The only issue with that way is then the CLI folder would get deployed when you publish the mvc app. A way around that would be to manually edit the project file and use the “ExcludeFoldersFromDeployment ” setting see reference: https://stackoverflow.com/questions/6104818/ms-visual-studio-how-to-exclude-certain-project-folders-from-publishing. This is what Im trying now. Also, supposedly this process of using CLI gets a little easier with .net core, but thats next on my list.
I’ve looked through the existing comments but didn’t see anyone suggesting the following approach (if I simply overlooked it, then I apologize for reposting).
I have setup the two projects as explained, but instead of using an “npm run dist” command everytime I change files in the Angular project I instead simply set the “outDir” of the .angular-cli.json file to “../MyMVCApp/Scripts/NgApp”. This way whenever “ng build” runs it simply builds directly into my MVC app, eliminating the need for xcopy. Also, it lets me use “ng build –watch” so it automatically builds the newest files into my MVC app whenver I change the source files (without running “npm run dist”) without having to set up gulp-watch or similar.
I have only tested it in a simple dummy example. Have anyone else tried it on a larger scale or have some feedback as to whether there might be some caveats i have overlooked when developing a real app that goes through CI and eventually goes to production?
What if I want to use NPM package manager instead of Yarn package manager?
I have tried your demo but in this, If I make any changes in Angular file then my browser is not auto refresh and also the changes are not reflected in the browser when I manually refresh it and one more question, Can I call MVC controller from angular service?
Hello, Thank you for the awesome tutorial !! I want to ask sometimes this function didn’t work ( “copy”: “xcopy \”dist\” \”..\\Candor.Sample.MvcWeb\\Scripts\\NgApp\” /i /s /r /y /c”,
“dist”: “npm run build && npm run copy”)
At the beginning, it works very well and then after 2 weeks for example if I change something in Angular project and copy to Asp.net project I can’t find what I changed.
Do you any idea, please
It’s possible to change the `dist` folder location in the `.angular-cli.json` file that will eliminate the need of xcopy.