Monday, 31 December 2018

Transclusion using ng-content

Understanding Transclusion
Transclusion means the inclusion of the content of one document in another document.


Content Projection in Angular with ng-content
Let’s say you have a home component with a decorator that goes a bit like this:

@Component({
    selector: 'home',
    template: `
      <h1>Heroic Title</h1>
      <p>Something good...</p>
    `
  })

And let’s say you want to be able to do something like this when including the component:

<home>
  <p>Something else</p>
</home>

Then what you would do is use <ng-content></ng-content> like this in your component template:

@Component({
    selector: 'home',
    template: `
      <h1>Heroic Title</h1>
      <p>Something good...</p>
      <ng-content></ng-content>
    `
  })

The result will then be the following:

<h1>Heroic Title</h1>
<p>Something good...</p>
<p>Something else</p>

And with this, you could also place components inside your wrapper component. Here’s how you would, for example, project the myNav component inside the home component:

<home>
  <myNav></myNav>
</home>

You can also use select on ng-content to define what should be included. In this example, only div elements would be included:

@Component({
    selector: 'home',
    template: `
      <h1>Heroic Title</h1>
      <p>Something good...</p>
      <ng-content select="div">
      </ng-content>
    `
  })

And you can use the [attr] syntax to select only elements that have a specific attribute. In the following example, only something like <p intro>…</p> would be included:

@Component({
    selector: 'home',
    template: `
      <h1>Heroic Title</h1>
      <p>Something good...</p>
      <ng-content select="[intro]">
      </ng-content>
    `
  })

Reference: https://alligator.io/https://medium.com/https://codecraft.tv/

Continue Reading →

Monday, 24 December 2018

HTTP - Status Codes

Status codes are issued by a server in response to a client's request made to the server.

S.N.Code and Description
11xx: Informational
It means the request has been received and the process is continuing.
22xx: Success
It means the action was successfully received, understood, and accepted.
33xx: Redirection
It means further action must be taken in order to complete the request.
44xx: Client Error
It means the request contains incorrect syntax or cannot be fulfilled.
55xx: Server Error
It means the server failed to fulfill an apparently valid request.
HTTP status codes are extensible and HTTP applications are not required to understand the meaning of all the registered status codes. Given below is a list of all the status codes.

1xx: Information

MessageDescription
100 ContinueOnly a part of the request has been received by the server, but as long as it has not been rejected, the client should continue with the request.
101 Switching ProtocolsThe server switches protocol.

2xx: Successful

MessageDescription
200 OKThe request is OK.
201 CreatedThe request is complete, and a new resource is created .
202 AcceptedThe request is accepted for processing, but the processing is not complete.
203 Non-authoritative InformationThe information in the entity header is from a local or third-party copy, not from the original server.
204 No ContentA status code and a header are given in the response, but there is no entity-body in the reply.
205 Reset ContentThe browser should clear the form used for this transaction for additional input.
206 Partial ContentThe server is returning partial data of the size requested. Used in response to a request specifying a Range header. The server must specify the range included in the response with the Content-Rangeheader.

3xx: Redirection

MessageDescription
300 Multiple ChoicesA link list. The user can select a link and go to that location. Maximum five addresses  .
301 Moved PermanentlyThe requested page has moved to a new url .
302 FoundThe requested page has moved temporarily to a new url .
303 See OtherThe requested page can be found under a different url .
304 Not ModifiedThis is the response code to an If-Modified-Since or If-None-Matchheader, where the URL has not been modified since the specified date.
305 Use ProxyThe requested URL must be accessed through the proxy mentioned in the Location header.
306 UnusedThis code was used in a previous version. It is no longer used, but the code is reserved.
307 Temporary RedirectThe requested page has moved temporarily to a new url.

4xx: Client Error

MessageDescription
400 Bad RequestThe server did not understand the request.
401 UnauthorizedThe requested page needs a username and a password.
402 Payment RequiredYou can not use this code yet.
403 ForbiddenAccess is forbidden to the requested page.
404 Not FoundThe server can not find the requested page.
405 Method Not AllowedThe method specified in the request is not allowed.
406 Not AcceptableThe server can only generate a response that is not accepted by the client.
407 Proxy Authentication RequiredYou must authenticate with a proxy server before this request can be served.
408 Request TimeoutThe request took longer than the server was prepared to wait.
409 ConflictThe request could not be completed because of a conflict.
410 GoneThe requested page is no longer available .
411 Length RequiredThe "Content-Length" is not defined. The server will not accept the request without it .
412 Precondition FailedThe pre condition given in the request evaluated to false by the server.
413 Request Entity Too LargeThe server will not accept the request, because the request entity is too large.
414 Request-url Too LongThe server will not accept the request, because the url is too long. Occurs when you convert a "post" request to a "get" request with a long query information .
415 Unsupported Media TypeThe server will not accept the request, because the mediatype is not supported .
416 Requested Range Not SatisfiableThe requested byte range is not available and is out of bounds.
417 Expectation FailedThe expectation given in an Expect request-header field could not be met by this server.

5xx: Server Error

MessageDescription
500 Internal Server ErrorThe request was not completed. The server met an unexpected condition.
501 Not ImplementedThe request was not completed. The server did not support the functionality required.
502 Bad GatewayThe request was not completed. The server received an invalid response from the upstream server.
503 Service UnavailableThe request was not completed. The server is temporarily overloading or down.
504 Gateway TimeoutThe gateway has timed out.
505 HTTP Version Not SupportedThe server does not




Continue Reading →

Friday, 14 December 2018

Custom Controller Factory in ASP.NET MVC

When ASP.NET MVC receives a request, it needs to manage how to handle it with a specific controller and the action methods in it. The component that is responsible to map an incoming request to a specific controller and decide which controller to use is controller factory. There is a default controller factory in ASP.NET MVC that maps incoming requests to a controller with a Controller postfix.

        Request  --> Routing System ---> Controller Factory ---> Invoke Controller
The built-in controller factory is the registered controller factory by default and is implemented in DefaultControllerFactory class. Also it’s possible to extend its behavior with minor changes by deriving from this base class.
But in some circumstances you may need to have a fully customized behavior for your controller factories. One common example is when you use Dependency Injection frameworks where you need to use a customized factory. Fortunately, most of the DI frameworks provide such a customized controller factory out of the box, but if you were faced with a case to implement such a factory, you can implement the IControllerFactory interface and register your own custom controller factory.
IControllerFactory is an interface with two methods:
  • CreateController: Getting the RequestContext instance and the string value of controller name, returns the controller to be used.
  • ReleaseController: Gets a controller instance and releases this controller.
Implementation of a controller factory is comparatively easy, and can be done with less amount of work to be done.
In this post I implement a basic controller factory that loads controllers based on the user’s language, so a specific controller can be loaded for a specific language. In this sample application, I define the type name of controllers in web configuration file based on a pattern that corresponds to a specific culture, and implement a controller factory that loads the appropriate controllers group based on the client’s preferences.
First I define my type patterns in my configuration file as application settings. Here I have two cultures: if the user uses Farsi, then the Farsi controllers will be loaded, otherwise the default English language will be used.
<appSettings>
  <add key="EnglishControllerTypePattern" value="IControllerFactorySample.Controllers.En.{0}"/>
  <add key="FarsiControllerTypePattern" value="IControllerFactorySample.Controllers.Fa.{0}"/>
</appSettings>

Now I write my controller factory by implementing the IControllerFactory interface and its two methods.
using System;
using System.Configuration;
using System.Web.Mvc;
using System.Web.Routing;
 
namespace IControllerFactorySample.ControllerFactories
{
    public class CustomControllerFactory : IControllerFactory
    {
        #region IControllerFactory Members
 
        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            if (string.IsNullOrEmpty(controllerName))
                throw new ArgumentNullException("controllerName");
 
            string language = requestContext.HttpContext.Request.Headers["Accept-Language"];
 
            string controllerType = string.Empty;
 
            if (language == "fa-IR")
                controllerType = string.Format
                    (ConfigurationManager.AppSettings["FarsiControllerTypePattern"], controllerName);
            else
                controllerType = string.Format
                    (ConfigurationManager.AppSettings["EnglishControllerTypePattern"], controllerName);
 
            IController controller = Activator.CreateInstance(Type.GetType(controllerType)) as IController;
 
            return controller;
        }
 
        public void ReleaseController(IController controller)
        {
            if (controller is IDisposable)
                (controller as IDisposable).Dispose();
            else
                controller = null;
        }
 
        #endregion
    }
}

In the CreateController function, I detect the client’s language using the HTTP headers of the request, and load the appropriate type name based on the user’s culture. Then I use reflection APIs to load the type and create an instance of the controller to be returned. Note that this implementation doesn’t mandate the Controller postfix for controller names, so rather than defining my Home controller as HomeController class, I just can use Home name. I have defined my controllers in Fa and En sub-folders inside Controllers folder, so my controller factory can load them based on the type name patterns. Besides, in the ReleaseController method, I dispose the controller as expected.
The third and last step is to add this controller factory as the default factory to ASP.NET MVC. This can be done in Global.asax and its Application_Start method where I use ControllerBuilder.SetControllerFactory to add my factory type as the default controller factory to ASP.NET MVC.
using System.Web.Mvc;
using System.Web.Routing;
using IControllerFactorySample.ControllerFactories;
 
namespace IControllerFactorySample
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );
 
        }
 
        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
 
            ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
        }
    }
}
As you see, building a controller factory is very straightforward and you can get it done in a few simple steps. If I run the application and set my preferred language to Farsi, then Farsi controllers will be used to serve the requests, otherwise English controllers will be loaded.



Continue Reading →

Thursday, 13 December 2018

ASP.NET MVC extensibility points

13 ASP.NET MVC extensibility points you must know

One of the main design principles ASP.NET MVC has been designed with is extensibility. Everything (or most of) in the processing pipeline is replaceable so, if you don’t like the conventions (or lack of them) that ASP.NET MVC uses, you can create your own services to support your conventions and inject them into the main pipeline.

In this post I’m going to show 13 extensibility points that every ASP.NET MVC developer should know, starting from the beginning of the pipeline and going forward till the rendering of the view.

1. RouteConstraint
Usually you could put some constrains on url parameters using regular expressions, but if your constrains depend on something that is not only about the single parameter, you can implement the IRouteConstrains’s method and put your validation logic in it.

One example of this is the validation of a date: imagine an url that has year, month and date on different url tokens, and you want to be able to validate that the three parts make a valid date.
Link 1Link 2

2. RouteHandler
Not really specific to ASP.NET MVC, the RouteHandler is the component that decide what to do after the route has been selected. Obviously if you change the RouteHandler you end up handling the request without ASP.NET MVC, but this can be useful if you want to handle a route directly with some specific HttpHanlders or even with a classic WebForm.
ReadMore: IRoutehandler asp.net mvc

3. ControllerFactory
The controller factory is the component that, based on the route, chooses which controller to instantiate and instantiate it. The default factory looks for anything that implements IController and whose name ends with Controller, and than create an instance of it through reflection, using the parameter-less constructor.

But if you want to use Dependency Injection you cannot use it, and you have to use a IoC aware controller factory: there are already controller factory for most of the IoC containers. You can find them in MvcContrib or having a look at the Ninject Controller Factory.

4. ActionInvoker
ActionInvoker is responsible for invoking the action based on it’s name. The default action invoker looks for the action based on the method name, the action name and possibly other selector attributes. Then it invokes the action method together with any filter defined  and finally it executes the action result.

If you read carefully you probably understood that most of the execution pipeline is inside the logic of the default ControllerActionInvoker class. So if you want to change any of these conventions, from the action method’s selection logic, to the way http parameters are mapped to action parameters, to the way filters are chosen and executed, you have to extend that class and override the method you want to change.

A good example of this, is the NinjectActionInvoker I developed to allow injection of dependencies inside filters.

5. ActionMethodSelectorAttribute
Actions, with the default action invoker, are selected based on their name, but you can finer tune the selection of actions implementing your own Method Selector. The framework already comes with the AcceptVerbs attribute that allows you to specify to which HTTP Verb an action has to respond to.

A possible scenario for a custom selector attribute is if you want to choose one action or another based on languages supported by the browser or based on the type of browser, for example whether it is a mobile browser or a desktop browser.

6. AuthorizationFilter
These kind of filters are executed before the action is executed, and their role is to make sure the request is “valid”.

There are already a few Authorization filters inside the framework, the most “famous” of which is the Authorize attribute that checks whether the current user is allowed to execute the action. Another is the the ValidateAntiForgeryToken that prevents CSRF attacks. If you want to implement your own authorization schema, the interface you have to implement is IAuthorizationFilter. An example could be the hour of the day.

7. ActionFilter
Action Filters are executed before and after an action is executed. One of the core filters is the OutputCache filter, but you can find many other usages for this filter. This is the most likely extension point you are going to use, as, IMHO, it’s critical to a good componentization of views: the controller only has to do its main stuff, and all the other data needed by the view must be retrieved from inside action filters.

8. ModelBinder
The default model binder maps HTTP parameters to action method parameters using their names: a http parameter named user.address.city will be mapped to the City property of the Address object that itself is a property of the method parameter named user. The DefaultModelBinder works also with arrays, and other list types.

But it can be pushed even further: for example you might use it to convert the id of the person directly to the Person object looking up on the database. This approach is explained better in the following post Timothy Khouri (aka SingingEels): Model Binders in ASP.NET MVC. The code is based on the preview 5, but the concept remains the same.

9. ControllerBase
All controllers inherit from the base class Controller. A good way to encapsulate logic or conventions inside your actions is to create you own layer supertype and have all your controllers to inherit from it.

10. ResultFilter
Like the ActionFiters, the ResultFilters are execute before and after the ActionResult is executed. Again, the OutputCache filter is an example of a ResultFilter. The usual example that is done to explain this filter is logging. If you want to log that a page has been returned to the user, you can write a custom RenderFilter that logs after the ActionResult has been executed.

11. ActionResult
ASP.NET MVC comes with many different kind of results to render views, to render JSON, plain text, files and to redirect to other actions. But if you need some different kind of result you can write your own ActionResult and implement the ExecuteResult method. For example, if you want to send a PDF file as result you could write your own ActionResult that use a PDF library to generate the PDF. Another possible scenario is the RSS feed: read more about how to write a RssResult in this post.

Look at implementing a custom action result when the only peculiarity is how the result is returned to the user.

12. ViewEngine
Probably you are not going to write your own view engine, but there are a few that you might consider using instead of the default WebForm view engine. The most interesting one, IMHO, is Spark.

But if you really want to write your own view engine, have a look at this post by Brad Wilson: Partial Rendering & View Engines in ASP.NET MVC

13. HtmlHelper
Views must be very dumb and thin, and they should only have html markup and calls to HtmlHelpers. There should be no code inside the views, so helpers come very handy for extracting the code from the view and putting it into something that is testable. As Rob Conery says: “If there's an IF, make a Helper”.

What is an HtmlHelper? Basically it’s just an extension method of the HtmlHelper class, but that’s the only requirement.

You can read more about how HtmlHelpers are a great way to encapsulate code for view on Rob’s post: Avoiding Tag Soup.



Continue Reading →

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 Component.

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
Add the following using statements to Service.cs.

using System.ComponentModel; using System.ServiceModel; using System.ServiceProcess; using System.Configuration; using System.Configuration.Install;

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 n1double n2);
    [OperationContract]
    double Subtract(double n1double n2);
    [OperationContract]
    double Multiply(double n1double n2);
    [OperationContract]
    double Divide(double n1double n2);
}

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 n1double n2)
    {
        double result = n1 + n2;
        return result;
    }

    public double Subtract(double n1double n2)
    {
        double result = n1 - n2;
        return result;
    }

    public double Multiply(double n1double n2)
    {
        double result = n1 * n2;
        return result;
    }

    public double Divide(double n1double n2)
    {
        double result = n1 / n2;
        return result;
    }
}

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());
    }
 }

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();
}

Override the OnStop method closing the ServiceHost as shown in the following code.

protected override void OnStop()
{
    if (serviceHost != null)
    {
        serviceHost.Close();
        serviceHost = null;
    }
}

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);
    }
}

Remove the Service class that was generated when you created the project.

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 hosthttp://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>

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

ADFS (1) ADO .Net (1) Ajax (1) Angular (47) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (49) CD (1) CI (2) CloudComputing (2) Coding (8) CQRS (1) CSS (2) Design_Pattern (7) DevOps (4) DI (3) Dotnet (10) DotnetCore (19) Entity Framework (4) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) Lamda (3) Linq (10) microservice (4) Mongodb (1) MVC (46) NodeJS (8) React (10) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (3) UI (1) UnitTest (2) WCF (14) Web Api (16) Web Service (1) XMl (1)

Dotnet Guru Archives