Friday, 7 December 2018

CORS in Express

CORS in Express using TypeScript

A quick walkthrough on configuring CORS in your Express app using TypeScript and the cors middleware.

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the first resource was served.

My use case for CORS is an Angular application that is making REST requests to an API running in Express.js. I’ll be using TypeScript, which will be compiled to ES2015 (ES6) compatible JavaScript that will be executed in Node.js.

Getting Started
We’ll be using Express to serve up some awesome content. I will assume that you have already installed:
  1. Node.js
  2. npm - The node package manager
  3. An Express app
First, let’s install our dependencies. I’ll be using the cors middleware. So, let’s install that package as well as the TypeScript definitions:

$ npm install cors --save

Setting it up
Let’s dive into the server.js file where we will be enabling and configuring CORS in our Express app:

Simple Usage (Enable All CORS Requests)
var express = require('express')

var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})


Enable CORS for a Single Route
var express = require('express')
var cors = require('cors')
var app = express()

app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

Configuring CORS
const corsOptions  = {
  allowedHeaders: ["Origin", "X-Requested-With", "Content-Type", "Accept", "X-Access-Token"],
  credentials: true,
  methods: "GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE",
  origin: API_URL,
  preflightContinue: false
};


app.get('/products/:id', cors(corsOptions), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for only example.com.'})
}
Continue Reading →

Http streams with RxJS

Combining multiple Http streams with RxJS Observables
A best practice, indeed, is keeping all the stream manipulation logic inside our service and return the Observable, that can be subscribed by the controller.

Here is a basic example of service with an Http call:
@Injectable()
export class AuthorService {
 
  constructor(private http: Http){}
 
  get(id: number): Observable<any> {
    return this.http.get('/api/authors/' + id)
      .map((res: any) => res.json());
  }
}

The controller should call the service, like this:
@Component({
  selector: 'app-author',
  templateUrl: './author.component.html'
})
export class AuthorComponent implements OnInit {
 
  constructor(private authorService: AuthorService) {}
 
  ngOnInit() {
    this.authorService.get(1).subscribe((data: any) => {
      console.log(data);
    });
  }
 
}
 
/* Will return:
 
{
  id: 1,
  first_name: 'Daniele',
  last_name: 'Ghidoli'
}
 
*/

Ok, now let’s see something more advanced!

Combining Observables in parallel
Imagine that you want to get the data of an author and his books, but in order to get the books you need to call a different endpoint, such as /authors/1/books. You should make the two calls and combine them in one response.

In order to do that, we can use the forkJoin RxJS operator, which is similar to the old $q.all() from Angular 1 and lets you execute two or more Observables in parallel:

getAuthorWithBooks(id: number): Observable<any> {
  return Observable.forkJoin([
    this.http.get('/api/authors/' + id).map(res => res.json()),
    this.http.get('/api/authors/' + id + '/books').map(res => res.json())
  ])
  .map((data: any[]) => {
    let author: any = data[0];
    let books: any[] = data[1];
    return author.books = books;
  });
}
 
/* Will return:
 
{
  id: 1,
  first_name: 'Daniele',
  last_name: 'Ghidoli'
  books: [{
    id: 10,
    title: 'Awesome book',
    author_id: 1
  }, 
  ...
  ]
}
 
*/

As you can see from the example, forkJoin returns an Array with the results of the joined Observables. We can compose them as we need, in order to return just one object.

Combining Observables in series
What if we need, for example, to get the author info from a book? We should get the book data first and, only when we get it, we can call the authors endpoint with the author id.

In this case we’ll have to use the flatMap RxJS operator, which is similar to the usual map RxJS operator. The difference is that lets you chain two Observables, returning a new Observable:

getBookAuthor(id: number): Observable<any> {
  return this.http.get('/api/books/' + id)
    .map((res: any) => res.json())
    .flatMap((book: any) => {
      return this.http.get('/api/authors/' + book.author_id)
        .map((res: any) => res.json());
    });
}
 
/* Will return:
 
{
  id: 1,
  first_name: 'Daniele',
  last_name: 'Ghidoli'
}
 
*/

In this case, what we will get is just the author info. What if we want also the book object? As before, we have to compose our objects:

getBookWithAuthor(id: number): Observable<any> {
  return this.http.get('/api/books/' + id)
    .map((res: any) => res.json())
    .flatMap((book: any) => {
      return this.http.get('/api/authors/' + book.author_id)
        .map((res: any) => {
          let author = res.json();
          book.author = author;
          return book;
        });
    });
}
 
/* Will return:
 
{
  id: 10,
  title: 'Awesome book',
  author_id: 1
  author: {
    id: 1,
    first_name: 'Daniele',
    last_name: 'Ghidoli'
  }
}
 
*/

Combining Observables in series and in parallel
What if now we would like to do the same (getting the book with its author), but for multiple books at once? We can combine forkJoin and flatMap:

getBooksWithAuthor(): Observable<any[]> {
  return this.http.get('/api/books/')
    .map((res: any) => res.json())
    .flatMap((books: any[]) => {
      if (books.length > 0) {
        return Observable.forkJoin(
          books.map((book: any) => {
            return this.http.get('/api/authors/' + book.author_id)
              .map((res: any) => {
                let author: any = res.json();
                book.author = author;
                return book;
              });
          });
        );
      }
      return Observable.of([]);
    });
}
 
/* Will return:
 
[{
  id: 10,
  title: 'Awesome book',
  author_id: 1
  author: {
    id: 1,
    first_name: 'Daniele',
    last_name: 'Ghidoli'
  }
},
{
  id: 11,
  title: 'Another awesome book',
  author_id: 2
  author: {
    id: 2,
    first_name: 'Jeff',
    last_name: 'Arese'
  }
}]
 
*/

It seems complicated, but it’s quite easy: after getting the list of books, we use the flatMap, in order to merge the previous call with the result of the forkJoin, that is called only if we have some books, otherwise we just return an Observable containing an empty array (line 17).

Maybe you are wondering why we are using the forkJoin here, since there is just a call. But, if you look better, there will be as much calls as many books we get. In fact, at line 7 we are looping on the books array with the Array.map function, which is not the same as the map RxJS Operator!

Then, for each author call we combine our objects and we return the book, which is what we want. Easy!

Another example can be getting author and editor info for a single book:

getBookWithDetails(id: number): Observable<any> {
  return this.http.get('/api/books/' + id)
    .map((res: any) => res.json())
    .flatMap((book: any) => {
      return Observable.forkJoin(
         Observable.of(book),
         this.http.get('/api/authors/' + book.author_id).map((res: any) => res.json()),
         this.http.get('/api/editors/' + book.editor_id).map((res: any) => res.json())
      )
        .map((data: any[]) => {
          let book = data[0];
          let author = data[1];
          let editor = data[2];
          book.author = author;
          book.editor = editor;
          return book;
        });
    });
}
 
 
/* Will return:
 
{
  id: 10,
  title: 'Awesome book',
  author_id: 1,
  editor_id: 42
  author: {
    id: 1,
    first_name: 'Daniele',
    last_name: 'Ghidoli'
  }, 
  editor: {
    id: 42,
    name: 'Universe Editor'
  }
}
 
*/

As we can see, the forkJoin return an array with the result of each Observable, that we can compose in order to return the final object. Note that we are forkJoining the book object itself, converting it in an Observable thanks to the of RxJS operator, so that we can access it in the following map.

Including the operators
The last thing I would like to share with you (maybe should have been the first!): don’t forget to include the RxJS operators you are using. You can import all at once by using:

import 'rxjs/Rx';

But it’s better to import just the operators you are actually using. In our case:

import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';

Note: we have to import the mergeMap operator, as it’s needed by flatMap to work.



Continue Reading →

Wednesday, 21 November 2018

WCF Service as Windows Service

Host a WCF Service in a Managed Windows Service

This topic outlines the basic steps required to create a Windows Communication Foundation (WCF) service that is hosted by a Windows Service. The scenario is enabled by the managed Windows service hosting option that is a long-running WCF service hosted outside of Internet Information Services (IIS) in a secure environment that is not message activated. 

The service code includes a service implementation of the service contract, a Windows Service class, and an installer class. The service implementation class, CalculatorService, is a WCF service. The CalculatorWindowsService is a Windows service. To qualify as a Windows service, the class inherits from ServiceBase and implements the OnStartand OnStop methods. In OnStart, a ServiceHost is created for the CalculatorService type and opened. In OnStop, the service is stopped and disposed. The host is also responsible for providing a base address to the service host, which has been configured in application settings. The installer class, which inherits from Installer, allows the program to be installed as a Windows service by the Installutil.exe tool.

Construct the service and provide the hosting code

  1. Create a new Visual Studio Console app project called WcfAsWindows.
  2. Rename Program.cs to Service.cs.
  3. Change the namespace to Microsoft.ServiceModel.Samples.
  4. Add references to the following assemblies:
    • System.ServiceModel.dll
    • System.ServiceProcess.dll
    • System.Configuration.Install.dll
  5. Add the following using statements to Service.cs.

    using System.ComponentModel; using System.ServiceModel; using System.ServiceProcess; using System.Configuration; using System.Configuration.Install;
  6. Define the ICalculator service contract as shown in the following code.

    // Define a service contract. [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")] public interface ICalculator { [OperationContract] double Add(double n1, double n2); [OperationContract] double Subtract(double n1, double n2); [OperationContract] double Multiply(double n1, double n2); [OperationContract] double Divide(double n1, double n2); }
  7. Implement the service contract in a class called CalculatorService as shown in the following code.

    // Implement the ICalculator service contract in a service class. public class CalculatorService : ICalculator { // Implement the ICalculator methods. public double Add(double n1, double n2) { double result = n1 + n2; return result; } public double Subtract(double n1, double n2) { double result = n1 - n2; return result; } public double Multiply(double n1, double n2) { double result = n1 * n2; return result; } public double Divide(double n1, double n2) { double result = n1 / n2; return result; } }
  8. Create a new class called CalculatorWindowsService that inherits from the ServiceBase class. Add a local variable called serviceHost to reference the ServiceHost instance. Define the Main method that calls ServiceBase.Run(new CalculatorWindowsService)

    public class CalculatorWindowsService : ServiceBase { public ServiceHost serviceHost = null; public CalculatorWindowsService() { // Name the Windows Service ServiceName = "WCFWindowsServiceSample"; } public static void Main() { ServiceBase.Run(new CalculatorWindowsService()); } }
  9. Override the OnStart(String[]) method by creating and opening a new ServiceHost instance as shown in the following code.

    // Start the Windows service. protected override void OnStart(string[] args) { if (serviceHost != null) { serviceHost.Close(); } // Create a ServiceHost for the CalculatorService type and // provide the base address. serviceHost = new ServiceHost(typeof(CalculatorService)); // Open the ServiceHostBase to create listeners and start // listening for messages. serviceHost.Open(); }
  10. Override the OnStop method closing the ServiceHost as shown in the following code.

    protected override void OnStop() { if (serviceHost != null) { serviceHost.Close(); serviceHost = null; } }
  11. Create a new class called ProjectInstaller that inherits from Installer and that is marked with the RunInstallerAttribute set to true. This allows the Windows service to be installed by the Installutil.exe tool.

    // Provide the ProjectInstaller class which allows // the service to be installed by the Installutil.exe tool [RunInstaller(true)] public class ProjectInstaller : Installer { private ServiceProcessInstaller process; private ServiceInstaller service; public ProjectInstaller() { process = new ServiceProcessInstaller(); process.Account = ServiceAccount.LocalSystem; service = new ServiceInstaller(); service.ServiceName = "WCFWindowsServiceSample"; Installers.Add(process); Installers.Add(service); } }
  12. Remove the Service class that was generated when you created the project.
  13. Add an application configuration file to the project. Replace the contents of the file with the following configuration XML.
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.serviceModel>    <services>
          <!-- This section is optional with the new configuration model
               introduced in .NET Framework 4. -->
          <service name="Microsoft.ServiceModel.Samples.CalculatorService"
                   behaviorConfiguration="CalculatorServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
              </baseAddresses>
            </host>
            <!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/ServiceModelSamples/service  -->
            <endpoint address=""
                      binding="wsHttpBinding"
                      contract="Microsoft.ServiceModel.Samples.ICalculator" />
            <!-- the mex endpoint is exposed at http://localhost:8000/ServiceModelSamples/service/mex -->
            <endpoint address="mex"
                      binding="mexHttpBinding"
                      contract="IMetadataExchange" />
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="CalculatorServiceBehavior">
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="False"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>
  14. Right click the App.config file in the Solution Explorer and select Properties. Under Copy to Output Directoryselect Copy if Newer.
This example explicitly specifies endpoints in the configuration file. If you do not add any endpoints to the service, the runtime adds default endpoints for you. In this example, because the service has a ServiceMetadataBehavior set to true, your service also has publishing metadata enabled. For more information about default endpoints, bindings, and behaviors, see Simplified Configuration and Simplified Configuration for WCF Services.

Install and run the service

Build the solution to create the WcfAsWindows.exe executable.

Open Developer Command Prompt (Administration mode) for Visual Studio and navigate to the project directory. Type installutil bin\WcfAsWindows.exe at the command prompt to install the Windows service.



Type services.msc at the command prompt to access the Service Control Manager (SCM). The Windows service should appear in Services as "WCFWindowsServiceSample". The WCF service can only respond to clients if the Windows service is running. To start the service, right-click it in the SCM and select "Start", or type net start WCFWindowsServiceSample at the command prompt.


If you make changes to the service, you must first stop it and uninstall it. 
To uninstall the Windows service type installutil /u bin\service.exe at the command prompt.

Download the complete project click here



Continue Reading →

Topics

ADO .Net (2) Ajax (1) Angular Js (17) Angular2 (26) ASP .Net (14) Azure (1) Breeze.js (1) C# (49) CloudComputing (1) CMS (1) CSS (2) Design_Pattern (3) DI (3) Dotnet (21) Entity Framework (3) ExpressJS (4) Html (3) IIS (1) Javascript (6) Jquery (8) Lamda (3) Linq (11) Mongodb (1) MVC (48) NodeJS (7) RDLC (1) Report (1) Sql Server (29) SSIS (3) SSRS (2) UI (1) WCF (13) Web Api (9) Web Service (1) XMl (1)