Setting up the new Angular 2 app with Web API and .NET core is easy but can be a bit tricky. The older beta releases of Angular 2 works fine as there are not many files to refer and to work with. When I started using Angular 2 it was in RC1 and the way the files are being referenced in the app is bit different than the older versions of Angular 2. I don’t want to repeat these steps again and again so I put up a Github repo for this seed project. You clone it and hit F5 and you will have your Angular 2 app with Web API.
At the time of writing this post I am using .NET Core version 1.0.0-preview1-002702. The complete seed project is available on GitHub.
Here is how I did it. Select ASP.NET Core Web Application (.NET Core)
. I have installed the new .NET Core RC2. Name the project as you like.
Select the Web API
project template.
After the project creation is successfull. The first thing is to create a Views
folder. The folder structure is like the same like it is for MVC application. This is how the folder structure looks like.
Because its a a Web API project, by default it will not render the views and therefore we have to add some dependencies in project.json
file.
"Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final", "Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0-rc2-final", "Microsoft.AspNetCore.Mvc.WebApiCompatShim": "1.0.0-rc2-final"
The project.json
file is different than that of the older version of the .NET Core. You will see the difference when you see it.
Next we set the routes for the views we have in the Startup.cs
file.
app.UseMvc(routes => { routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); routes.MapWebApiRoute("defaultApi", "api/{controller}/{id?}"); });
The routes are now set and you can run the application and check if you can see the view or not. Once that is set, let start adding the support for Angular. Here is the list of the files which we need to add.
tsconfig.json
file
Add the below code to the file and save it.
{ "compilerOptions": { "target": "es5", "module": "system", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false, "rootDir": "wwwroot", "outDir": "wwwroot", "listFiles": true, "noLib": false, "diagnostics": true }, "exclude": [ "node_modules" ] }
typings.json
file
Add a blank .json file
and name it typings.json
Add below lines to the typings.json
file.
{ "ambientDependencies": { "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654", "jasmine": "registry:dt/jasmine#2.2.0+20160412134438" } }
As per the official Angular documentation, we will stick with NPM
to fulfill the client-side dependencies. Start with adding new npm Configuration File
. The content of the NPM
file is almost the same, but I made few changes as per my requirement. Here is the complete configuration file.
{ "name": "Angular2WebAPI-Seed", "version": "1.0.0", "scripts": { "postinstall": "typings install" }, "license": "ISC", "dependencies": { "@angular/common": "2.0.0-rc.1", "@angular/compiler": "2.0.0-rc.1", "@angular/core": "2.0.0-rc.1", "@angular/http": "2.0.0-rc.1", "@angular/platform-browser": "2.0.0-rc.1", "@angular/platform-browser-dynamic": "2.0.0-rc.1", "@angular/router": "2.0.0-rc.1", "@angular/router-deprecated": "2.0.0-rc.1", "@angular/upgrade": "2.0.0-rc.1", "lodash": "4.12.0", "systemjs": "0.19.27", "es6-shim": "^0.35.0", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.6", "zone.js": "^0.6.12", "angular2-in-memory-web-api": "0.0.7", "bootstrap": "^3.3.6" }, "devDependencies": { "gulp": "3.9.1", "concurrently": "^2.0.0", "typescript": "^1.8.10", "typings": "^0.8.1" } }
Notice the postinstall
section in the npm configuration file. In this section we are installing the types required by our Angular 2 application. Now we can start setting up the Angular stuff in the wwwroot
folder. Create an app
and js
folder inside this folder. Inside app
folder create a new .ts
file (TypeScript file). Here is the folder structure looks like in the wwwroot
folder.
You can see a system.config.js
file is the same as you can see the Angular quickstart guide. I just have map the paths for the dependencies so that can be loaded without any problem. The main.ts
file will be the main bootstrapper and app.component.ts
file is the component file which will render the content on the page. At this point running the application will fail and it will give you several warnings and errors. To resolve that we need to add the references and we can do this easily by using a gulp file. The gulp file will automate the copying of dependencies in the wwwroot
folder and ease our task.
The content of the gulp file in this case looks like this.
///var _ = require('lodash'); var gulp = require('gulp'); var js = [ 'node_modules/zone.js/dist/zone.min.js', 'node_modules/systemjs/dist/system.js', 'node_modules/reflect-metadata/Reflect.js', 'node_modules/es6-shim/es6-shim.min.js' ]; var map = [ 'node_modules/es6-shim/es6-shim.map', 'node_modules/reflect-metadata/reflect.js.map', 'node_modules/systemjs/dist/system.js.map' ]; var folders = [ 'node_modules/@angular/**/*.*', 'node_modules/rxjs/**/*.*' ]; gulp.task('copy-js', function () { _.forEach(js, function (file, _) { gulp.src(file) .pipe(gulp.dest('./wwwroot/js')) }); }); gulp.task('copy-map', function () { _.forEach(map, function (file, _) { gulp.src(file) .pipe(gulp.dest('./wwwroot/js')) }); }); gulp.task('copy-folders', function () { _.forEach(folders, function (folder) { gulp.src(folder, { base: 'node_modules' }) .pipe(gulp.dest('./wwwroot/js')) }); }) gulp.task('default', ['copy-js', 'copy-map', 'copy-folders']);
Notice the very first line in the file above. We want to execute the task on every time before the build is triggered. The gulp file will only be copying the required files to the js
folder and other unnecessary files will not be required. After the task is executed here is the how the final directiry structure will look like under wwwroot
.
Depending on the selector you have in your component, you need to add the selector to your view. In my case the selector is app
, hence add <app></app>
in your Index.cshtml
file.
After you set up the index page, there is one more thing that you have to do is to set the launch URL.
The URL may change and differ as per your API endpoint. Press F5 to run the application.
Previous versions of MVC allows us to write HtmlHelpers which does a pretty good job then and they are doing it now as well. But in MVC 6, the ASP.NET team has introduced TagHelpers.
Parsing Markdown in .NET is way too simple than one can imagine. Thanks to Stackoverflow’s MarkdownSharp and Karlis Gangis’s CommonMark.NET. I use CommonMark.NET as it provides a much faster parsing than other libraries. The blogging platform I use is a custom blogging engine I wrote in MVC4. The post content is saved in HTML which makes my raw HTML way to messy when compared to simple markdown syntax. I have no plans to change the way it is right now, but for the other simple application which is quite similar to notes taking or blogging apps, I would like to save the content in markdown.
I will start with a simple implementation of this custom TagHelper and then then we can look into the other ways to enhance it. Here is how easy it is to create your custom TagHelper.
Create a new class file MarkdownTagHelper.cs
. Inside the file, rename the class name to match the file name or you can change the name way you like. In my case I am keeping the class name as same as the file name.
Pay attention to the name of the custom TagHelper. By design, compiler will remove the word TagHelper from the class name and the rest of the name will become your custom TagHelper name.
The next step is to inherit our class with TagHelpers
class. Every custom TagHelper will inherit this class. Just like the UserControl class when creating a custom user control. The TagHelper provide us two virtual methods, Process
and a ProcessAsync
method which we will be going to override to implement our custom logic for our custom markdown TagHelper. The first parameter is the TagHelperContext
which holds the information about the current tag and the second parameter is TagHelperOutput
object represents the output being generated by the TagHelper. As we need to parse the markdown in our razor view pages, we need to add reference of CommonMark.Net library. Use the below Nuget command to add it to your current project.
Install-Package CommonMark.Net
Till here this is how the code will look like.
So now we have our custom TagHelper that will let us parse the markdown. But to use it in our views we need to opt-in for this TagHelper in the _ViewImports.cshtml
file. To enable your custom TagHelper just type in like this:
@addTagHelper "*, WebApplication1"
Your custom tag helper would have been turned purple in color on the view page. It is similar to the line above it where @addTagHelper
is importing all the TagHelpers from the given namespace. If you are not interested in opting-in for all the TagHelpers in the given namespace then make use of the @removeTagHelper
to disable the TagHelpers you don’t need. For this I want all the tag helpers I have created to be a part of the application and hence the * symbol.
In your view, where you want to use this just type in <markdown>
and inside this tag you should have your markdown. To test it, you can view the any raw file in Github and copy the text. I am using README.md from CommonMark.NET and it rendered perfectly.
Caution: When copy-pasting the markdown code from anywhere to your view make sure that you do not have a whitespace in the front of the line. This is only applicable when you are working with the in-line markdown. Here is the screenshot with comparison.
Hit F5 and see the markdown tag helper in action. Below is the output I get.
This is the simplest of all. Now let’s add some prefix to our custom TagHelper. To add a custom tag prefix to the TagHelper, we just need to pay a visit to _ViewImports.cshtml
file again and add a new line like so:
@tagHelperPrefix "blog-"
After adding the above line in the file, go to the view page where you have used your custom TagHelper and you can notice that the <markdown>
tag isn’t purple anymore. This is because we now have to add a custom tag-prefix that we just defined in the _ViewImports.cshtml
file. Change it from <markdown>
to <blog-markdown>
and it is purple again.
By design, the TagHelper will take <markdown>
as a tag to be processed. But it can be easily ignored by using the HtmlTargetElement
attribute at the top of the class and allow the use of another name rather than <markdown>
. This does not mean that you cannot use <markdown>
but instead you can also use the custom TagHelper with the name specify in this attribute.
Now let’s add some attributes to my markdown TagHelper. Let’s try to add a url attribute which will help user to render the markdown on the view from a remote site like Github. To add an attribute, simply add a new public property of type string and call it url. When you create a public property in the TagHelper
class it is automatically assumed it is an attribute. To make use of this property, my view now simply say this:
<blog-markdown url="https://raw.githubusercontent.com/Knagis/CommonMark.NET/master/README.md"> </blog-markdown>
The url attribute value is being read by the TagHelper which in turn read the whole string of markdown from Github and render the HTML on the page. Let’s focus again on TargetElement attribute for a while. Consider a scenario where you don’t want your custom TagHelper to render or work if the attributes are not passed or missing. This is where HtmlTargetElement
attribute comes into picture. If I don’t want my TagHelper to work if the url
parameter is missing then you can simple write your HtmlTargetElement
attribute like so:
[HtmlTargetElement("markdown", Attributes = "url")]
Notice the Attributes
parameter. The Attributes
parameter allows you to set the name of all the attributes which should be processed by your TagHelper or else the TagHelper will not work. For instance, if I just use the <markdown>
TagHelper but did not pass the url attribute, the TagHelper will not execute and you will see the raw markdown code. My requirement is to have this TagHelper working with or without the use of url
attribute. I can comment out or remove the HtmlTargetElement
attribute or just remove the Attributes
parameter to get going.
Here is the complete MarkdownTagHelper.cs:
using Microsoft.AspNet.Razor.Runtime.TagHelpers; using System; using System.Net.Http; using System.Threading.Tasks; namespace WebApplication1.TagHelpers { //[HtmlTargetElement("markdown", Attributes = "url")] public class MarkdownTagHelper : TagHelper { //Attribute for our custom markdown public string Url { get; set; } private string parse_content = string.Empty; //Stolen from: http://stackoverflow.com/questions/7578857/how-to-check-whether-a-string-is-a-valid-http-url private bool isValidURL(string URL) { Uri uriResult; return Uri.TryCreate(URL, UriKind.Absolute, out uriResult) && (uriResult.Scheme.ToLowerInvariant() == "http" || uriResult.Scheme.ToLowerInvariant() == "https"); } public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (context.AllAttributes["url"] != null) { string url = context.AllAttributes["url"].Value.ToString(); string webContent = string.Empty; if (url.Trim().Length > 0) { if (isValidURL(url)) { using (HttpClient client = new HttpClient()) { webContent = await client.GetStringAsync(new Uri(url)); parse_content = CommonMark.CommonMarkConverter.Convert(webContent); output.Content.SetHtmlContent(parse_content); } } } } else { //Gets the content inside the markdown element var content = await output.GetChildContentAsync(); //Read the content as a string and parse it. parse_content = CommonMark.CommonMarkConverter.Convert(content.GetContent()); //Render the parsed markdown inside the tags. output.Content.SetHtmlContent(parse_content); } } } }
I found the full TagHelper feature in MVC 6 a lot more convenient and powerful. I hope you like it as well.
A super awesome free e-book from our friends at RedGate.
As an enthusiast, I started working with embedded with Netduino. It was fun but at the same time Netduino was not offering that much things that I can do now. For a person like me who has no knowledge of electronics and C/C++, this was a gift. Now here I am using Raspberry PI’s latest version and I have everything I ever wanted on a single piece of hardware.
To get started with Python and Raspberry PI, I looked into the “Hello World” sort of LED blinking example. Using the LCD is the second thing I would like to test and so here it is. Before you start, here are the things you will need.
1 x Raspberry PI 2
LCD with 16x2 display - HD44780
8 x Male-Female jumper wires
5 x Male-Male jumper wires
Here is the simple wiring to connect LCD with your Raspberry PI 2
As you can see from the wiring diagram, the LCD will take up around 6 GPIO pins on your Raspberry PI. If you have some modules plugged in or you are planning to then there are chances that you will fall short of the GPIO pins. To save GPIO pins on your board, you can use MCP23008 or MCP23017 . To keep it simple, I am not using any port expanders for now.
Now comes the code, I have a very little knowledge of Python at the moment. So I am going to stick with what I have read and tested. For controlling the LCD, I am going to use Adafruit’s LCD library which you can get it from Github here. I am going to use Adafruit_CharLCD.py
to control my LCD. The thing to keep in mind is that you cannot use this library out of the box. You have to make a change to set the correct GPIO pins in the __init__
function. Open the file using the below command.
$ sudo nano Adafruit_CharLCD.py
If you are using the same wiring as I am, then change the __init__
function like this
def __init__init(self, pin_rs=26, pin_e=19, pins_db=[13, 6, 5, 11], GPIO=None):
Save the changes and we are good to go. To check if the wiring and the code changes are done properly, execute the below command in the same directory.
$ sudo ./Adafruit_CharLCD_IPclock_example.py
Let’s try displaying some custom messages to the display with this simple program.
from Adafruit_CharLCD import Adafruit_CharLCD lcd = Adafruit_CharLCD() lcd.message("Raspberry PI 2\nLCD Demo")
Here is one more. The program will ask you to enter the string to display.
from Adafruit_CharLCD import Adafruit_CharLCD lcd = Adafruit_CharLCD() #Getting input from user msg = raw_input("Enter message to display\n") #Display it on the LCD lcd.message(str(msg))
The reason I am using Adafruit library to control the display is because it has other useful functions to control LCD. Here is the list of functions that you can try.
clear()
- Clears the LCD and remove text from the memory.
display()/noDisplay()
- Toggle the text visibility on the LCD. Text remains in the memory.
cursor()/noCursor
- Toggle cursor visibility.
blink()/noBlink()
- Toggle cursor blink.
home()
- Take the cursor to the 0,0 position i.e. first column of first row.
setCursor(col, row)
- Set the cursor to the specific position. Use lcd.begin(col, rows)
to set the number of columns and rows your display has.
I hope this will be useful to the people who are just getting started with Raspberry Pi. You can also download the complete source code from Github here.