All About ASP.NET and ASP.NET Core 2 Hosting BLOG

Tutorial and Articles about ASP.NET and the latest ASP.NET Core

ASP.NET Core Hosting :: How to Set Headers and HTTP Status Codes in ASP.NET Core

clock February 7, 2019 11:36 by author Jervis

I was working on an interesting issue in an ASP.NET Core recently. An external framework was responsible for creating an HTTP Response, and I was only in control of a little component that customized some internal behaviours (via a relevant extensibility point), without being able to influence the final response sent over HTTP.

This is common if you think about extending things like CMS systems or specialized services like for example Identity Server. In those situations, more often than not, the framework would be highly opinionated in what it is trying to do at the HTTP boundaries and as a result, trying to override the HTTP status codes or headers it produces may not be easy.

Let’s have a look at a simple generic workaround.

TL;DR

In ASP.NET Core you can hook a callback to the HTTP response object, which allows you to run arbitrary code just before the response starts getting sent or as soon as it has been sent. This allows you to override status code, headers or even change the response body even if your code is not responsible for flushing the response

// always set the status code to 418
response.OnStarting(() =>
{
    response.StatusCode = 418;
    return Task.CompletedTask;
});

The problem

To illustrate the problem better, let’s have a look at a concrete example – and I think Identity Server is a good choice here.

Identity Server allows you to register your own validators for various authentication grant types – for example client credentials grant, resource owner or even your own custom extension grant.

An implementation of such custom validator could like this:

public class MyResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
    public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        var user = await UserStore.FindAndValidate(context.UserName, context.Password); 

        if (user == null || !user.IsValid())
        {
            // reject as the credentials are incorrect or account invalid
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Invalid username or password.");
            return;
        }        

        if (!user.IsCountrySupported())
        {
            // reject as the country of the user is not allowed
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Country not supported.");
            return;
        }        

        // allow
        context.Result = new GrantValidationResult(user.Id, "password", user.Claims, "idsrv");
    }
}

In other words, we validate the user, and allow the token to be issued if the username and password are correct. If not, we will produce a token request error; in addition to that we also produce a different error if the user credentials are correct but the country is not supported.

This is all nice and fine. We have no touchpoints to the HTTP response here, as Identity Server (or any other framework/service that we might be using) would take care of that for us. We only produce the result that we are mandated to produce by the contract – a GrantValidationResult in this case.

It works well in most situations. However, let’s imagine that we’d like to influence the HTTP status codes being returned from this validation code. At the moment the status codes are hidden from us, and it is the responsibility of Identity Server to produce them.

In our case, the Identity Server would actually be returning 2 different ones:

  • GrantValidationResult(user.Id, “password”, user.Claims, “idsrv”) would obviously produce a 200 and result in a token being sent to the user
  • GrantValidationResult(TokenRequestErrors.InvalidRequest, “{ERROR DESCRIPTION}”) would produce a 400 and convey the error description to the caller in the error_description JSON property of the response (as defined by the spec).

Now let’s imagine the situation, that for the code path of user.IsCountrySupported(), we’d like to use HTTP status code 451 instead. This is allowed by the spec, which states “the authorization server responds with an HTTP 400 (Bad Request) status code (unless specified otherwise)”. However, such status code customization is currently not supported by Identity Server.

Let’s have a look at addressing this via a neat ASP.NET Core feature. Before we get there – in case you don’t agree with this spec interpretation – remember that this is merely an example to illustrate that ASP.NET Core feature.

Wrong way to deal with it

There are several ideas of dealing with this, that come to mind straight away.

One naive approach would be to try to throw an exception, let it bubble up as far as possible and then handle it in a way that you can convert the response to the relevant HTTP status code (perhaps with a global handler registered in your Startup class). This, however, wouldn’t work with Identity Server, as it handles all exceptions in the pipeline on its own, without letting it bubble up. In fact, this would typically be the case with most frameworks or services of that sort, not to mention using exceptions for flow control is iffy at best.

Another approach could be to try to write a middleware component, that runs at the end of HTTP pipeline (so wraps the Identity Server middleware) and use it to change the status code. This seems like a great idea at first, but unfortunately it wouldn’t work.

The reason for that is that ASP.NET Core would flush the headers of the response as soon as the first body write happens, and Identity Server, in its pipeline, would start writing to the body already. This means that even though you can technically (there would be no exception thrown for that) change the status code on the response, or inject some headers into it using a custom middleware that runs at the end of the pipeline, that would have no effect on the response anymore, as it is simply too late. You can actually normally see that on the response object by inspecting the response.HasStarted property – at that moment status code and headers modifications are not possible anymore.

One other idea could be to hijack the response writing completely. Since you can inject IHttpContextAccessor to any class, anywhere in the ASP.NET Core application, you can fairly easily get a hold of the HttpResponse. This allows you to simply write to the HTTP response directly. Such approach could possibly work but it is not very elegant to say the least. It would require you to correctly produce the entire set of headers (also the more esoteric ones like Cache-Control and so on) and the status code correctly and flush it before Identity Server can do that, allowing it to only complete the response by writing the body. This is very error prone and very unmaintainable.

Simple solution

A simple and elegant solution is to leverage a little known feature of ASP.NET Core – the ability to register your own callback on the HttpResponse, that would run as soon as the response is started to be sent (or as soon as its completed).

The following hooks exist on the HttpResponse:

/// <summary>
/// Adds a delegate to be invoked just before response headers will be sent to the client.
/// </summary>
/// <param name="callback">The delegate to execute.</param>
/// <param name="state">A state object to capture and pass back to the delegate.</param>
public abstract void OnStarting(Func<object, Task> callback, object state); 

/// <summary>
/// Adds a delegate to be invoked just before response headers will be sent to the client.
/// </summary>
/// <param name="callback">The delegate to execute.</param>
public virtual void OnStarting(Func<Task> callback) => OnStarting(_callbackDelegate, callback); 

/// <summary>
/// Adds a delegate to be invoked after the response has finished being sent to the client.
/// </summary>
/// <param name="callback">The delegate to invoke.</param>
/// <param name="state">A state object to capture and pass back to the delegate.</param>
public abstract void OnCompleted(Func<object, Task> callback, object state); 

/// <summary>
/// Adds a delegate to be invoked after the response has finished being sent to the client.
/// </summary>
/// <param name="callback">The delegate to invoke.</param>
public virtual void OnCompleted(Func<Task> callback) => OnCompleted(_callbackDelegate, callback);

This means we can simply register a delegate that would change the HTTP Status Code, modify the headers and possibly even meddle with the response body, from any point in the ASP.NET Core application. Then, as soon as the response starts being sent (irrespective to the fact which component or part of the pipeline triggered that), our code would run, allowing us to influence the structure of that response.

It is extremely convenient, as we are able to create de facto extensibility points for 3rd party applications, frameworks or services (like Identity Server), in places where they normally don’t exist.

In our case, the final code looks like this:

public static class HttpResponseExtensions
{
    public static void SetHttpStatusCodeOverride(this HttpResponse response, int httpStatusCode)
    {
        response.OnStarting(() =>
        {
            response.StatusCode = httpStatusCode;
            return Task.CompletedTask;
        });
    }


public class MyResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
   private readonly IHttpContextAccessor _httpContextAccessor;  

   public MyResourceOwnerPasswordValidator(IHttpContextAccessor httpContextAccessor)
   {
       _httpContextAccessor = httpContextAccessor;
   } 

    public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        var user = await UserStore.FindAndValidate(context.UserName, context.Password); 

        if (user == null || !user.IsValid())
        {
            // default 400
            // reject as the credentials are incorrect or account invalid
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Invalid username or password.");
            return;
        }        

        if (!user.IsCountrySupported())
        {
            // overridden to 451
            // reject as the country of the user is not allowed
           _httpContextAccessor.HttpContext.Response.SetHttpStatusCodeOverride(451);
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Country not supported.");
            return;
        }        

        // allow
        context.Result = new GrantValidationResult(user.Id, "password", user.Claims, "idsrv");
    }
}

I hope you will find this technique useful – I used Identity Server as an example, because it actually solves a real world problem here – but I think you could apply this approach in various places where you’d like to have a certain response-based extensibility point and it’s simply not available.



ASP.NET Core Hosting :: How to Implement Action Filters in ASP.NET Core

clock January 28, 2019 08:50 by author Jervis

Filters in .NET offer a great way to hook into the MVC action invocation pipeline. Therefore, we can use filters to extract code which can be reused and make our actions cleaner and maintainable. There are some filters that are already provided by .NET like the authorization filter, and there are the custom ones that we can create ourselves.

There are different filter types:

  • Authorization filters – They run first to determine whether a user is authorized for the current request
  • Resource filters – They run right after the authorization filters and are very useful for caching and performance
  • Action filters – They run right before and after the action method execution
  • Exception filters – They are used to handle exceptions before the response body is populated
  • Result filters – They run before and after the execution of the action methods result.

In this article, we are going to talk about Action filters and how to use them to create a cleaner and reusable code in our Web API’s.

Action Filters Implementation

To create an Acton filter, we need to create a class that inherits either from the IActionFilter interface or IAsyncActionFilter interface or from the ActionFilterAttribute class which is the implementation of the IActionFilterIAsyncActionFilter, and few different interfaces as well:

public abstract class ActionFilterAttribute : Attribute, IActionFilter, IFilterMetadata, IAsyncActionFilter, IResultFilter, IAsyncResultFilter, IOrderedFilter

In our examples, we are going to inherit from the IActionFIlter interface because it has all the method definitions we require.

To implement the synchronous Action filter that runs before and after action method execution, we need to implement OnActionExecuting and OnActionExecuted methods:

namespace ActionFilters.Filters
{
    public class ActionFilterExample : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            // our code before action executes
        } 

        public void OnActionExecuted(ActionExecutedContext context)
        {
            // our code after action executes
        }
    }
}

We can do the same thing with an asynchronous filter by inheriting from IAsyncActionFilter, but we only have one method to implement the OnActionExecutionAsync:

namespace ActionFilters.Filters
{
    public class AsyncActionFilterExample : IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            // execute any code before the action executes
            var result = await next();
            // execute any code after the action executes
        }
    }
}

The Scope of Action Filters

Like the other types of filters, the action filter can be added to different scope levels: Global, Action, Controller.

If we want to use our filter globally, we need to register it inside the AddMvc() method in the ConfigureServices method:

services.AddMvc(
  config =>
  {
     config.Filters.Add(new GlobalFilterExample());
  });

But if we want to use our filter as a service type on the Action or Controller level, we need to register it in the same ConfigureServices method but as a service in the IoC container:

services.AddScoped<ActionFilterExample>();
services.AddScoped<ControllerFilterExample>();

Finally, to use a filter registered on the Action or Controller level, we need to place it on top of the Controller or Action as a ServiceType:

namespace AspNetCore.Controllers
{
    [ServiceFilter(typeof(ControllerFilterExample))]
    [Route("api/[controller]")]
    public class TestController : Controller
    {
        [HttpGet]
        [ServiceFilter(typeof(ActionFilterExample))]
        public IEnumerable<string> Get()
        {
            return new string[] { "example", "data" };
        } 

    }
}

Order of Invocation

The order in which our filters are executed is as follows:

Of course, we can change the order of invocation by adding an additional property Order to the invocation statement:

namespace AspNetCore.Controllers
{
    [ServiceFilter(typeof(ControllerFilterExample), Order=2)]
    [Route("api/[controller]")]
    public class TestController : Controller
    {
        [HttpGet]
        [ServiceFilter(typeof(ActionFilterExample), Order=1)]
        public IEnumerable<string> Get()
        {
            return new string[] { "example", "data" };
        } 

    }
}

Or something like this on top of the same action:

[HttpGet]
[ServiceFilter(typeof(ActionFilterExample), Order=2)]
[ServiceFilter(typeof(ActionFilterExample2), Order=1)]
public IEnumerable<string> Get()
{
    return new string[] { "example", "data" };
}

Improving the Code with Action Filters

If we open the starting project from the AppStart folder from our repository, we can find the MoveController class in the Controllers folder. This controller has an implementation for all the CRUD operations. For the sake of simplicity, we haven’t used any additional layers for our API. 

Our actions are quite clean and readable without try-catch blocks due to global exception handling, but we can improve them even further.

The important thing to notice is that our Movie model inherits from the IEntity interface:

[Table("Movie")]
public class Movie: IEntity
{
    [Key]
    public Guid Id { get; set; }
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
    [Required(ErrorMessage = "Genre is required")]
    public string Genre { get; set; }
    [Required(ErrorMessage = "Director is required")]
    public string Director { get; set; }
}

So let’s start with the validation code from the POST and PUT actions.

Validation with Action Filters

If we look at our POST and PUT actions, we can notice the repeated code in which we validate our Movie model:

if (movie == null)
{
     return BadRequest("Movie object is null");


if (!ModelState.IsValid)
{
     return BadRequest(ModelState);
}

We can extract that code into a custom Action Filter class, thus making this code reusable and the action cleaner.

So let’s do that.

Let’s create a new folder in our solution explorer, and name it ActionFilters. Then inside that folder, we are going to create a new class ValidationFilterAttribute:

using Microsoft.AspNetCore.Mvc.Filters; 

namespace ActionFilters.ActionFilters
{
    public class ValidationFilterAttribute : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {            

        } 

        public void OnActionExecuted(ActionExecutedContext context)
        {            

        }
    }
}

Now we are going to modify the OnActionExecuting method to validate our model:

using ActionFilters.Contracts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Linq; 

namespace ActionFilters.ActionFilters
{
    public class ValidationFilterAttribute : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            var param = context.ActionArguments.SingleOrDefault(p => p.Value is IEntity);
            if(param.Value == null)
            {
                context.Result = new BadRequestObjectResult("Object is null");
                return;
            }            

            if(!context.ModelState.IsValid)
            {
                context.Result = new BadRequestObjectResult(context.ModelState);
            }
        } 

        public void OnActionExecuted(ActionExecutedContext context)
        {          
        }
    }
}

Next, let’s register this action filter in the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
       services.AddDbContext<MovieContext>(options =>
           options.UseSqlServer(Configuration.GetConnectionString("sqlConString"))); 

       services.AddScoped<ValidationFilterAttribute>(); 

       services.AddMvc();
}

Finally, let’s remove that validation code from our actions and call this action filter as a service:

[HttpPost]
[ServiceFilter(typeof(ValidationFilterAttribute))]
public IActionResult Post([FromBody] Movie movie)
{
     _context.Movies.Add(movie);
     _context.SaveChanges(); 

     return CreatedAtRoute("MovieById", new { id = movie.Id }, movie);


[HttpPut("{id}")]
[ServiceFilter(typeof(ValidationFilterAttribute))]
public IActionResult Put(Guid id, [FromBody]Movie movie)
{
    var dbMovie = _context.Movies.SingleOrDefault(x => x.Id.Equals(id));
    if (dbMovie == null)
    {
        return NotFound();
    } 

    dbMovie.Map(movie); 

    _context.Movies.Update(dbMovie);
    _context.SaveChanges(); 

    return NoContent();
}

Excellent.

This code is much cleaner and more readable now without the validation part. And furthermore, the validation part is now reusable as long as our model classes inherit from the IEntity interface, which is a quite common behavior.

If we send a POST request for example with the invalid model we will get the BadRequest response:

Dependency Injection in Action Filters

If we take a look at our GetById, POST and PUT actions, we are going to see the code where we fetch the move by id from the database and check if it exists:

var dbMovie = _context.Movies.SingleOrDefault(x => x.Id.Equals(id));
if (dbMovie == null)
{
     return NotFound();
}

That’s something we can extract to the Action Filter class as well, thus making it reusable in all the actions.

Of course, we need to inject our context in a new ActionFilter class by using dependency injection.

So, let’s create another Action Filter class ValidateEntityExistsAttribute in the ActionFilters folder and modify it:

using System.Linq; 

namespace ActionFilters.ActionFilters
{
    public class ValidateEntityExistsAttribute<T> : IActionFilter where T: class, IEntity
    {
        private readonly MovieContext _context; 

        public ValidateEntityExistsAttribute(MovieContext context)
        {
            _context = context;
        } 

        public void OnActionExecuting(ActionExecutingContext context)
        {
            Guid id = Guid.Empty; 

            if (context.ActionArguments.ContainsKey("id"))
            {
                id = (Guid)context.ActionArguments["id"];
            }
            else
            {
                context.Result = new BadRequestObjectResult("Bad id parameter");
                return;
            } 

            var entity = _context.Set<T>().SingleOrDefault(x => x.Id.Equals(id));    
            if(entity == null)
            {
                context.Result = new NotFoundResult();
            }
            else
            {
                context.HttpContext.Items.Add("entity", entity);
            }
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
        }
    }
}

We’ve created this Action Filter class to be generic so that we could reuse it for any model in our project. Furthermore, if we find the entity in the database, we store it in HttpContext because we need that entity in our action methods and we don’t want to query the database two times (we would lose more than we gain if we double that action).

Now let’s register it:

services.AddScoped<ValidateEntityExistsAttribute<Movie>>();

And let’s modify our actions:

[HttpGet("{id}", Name = "MovieById")]
[ServiceFilter(typeof(ValidateEntityExistsAttribute<Movie>))]
public IActionResult Get(Guid id)
{
    var dbMovie = HttpContext.Items["entity"] as Movie; 

    return Ok(dbMovie);
}
[HttpPut("{id}")]
[ServiceFilter(typeof(ValidationFilterAttribute))]
[ServiceFilter(typeof(ValidateEntityExistsAttribute<Movie>))]
public IActionResult Put(Guid id, [FromBody]Movie movie)
{
    var dbMovie = HttpContext.Items["entity"] as Movie; 

     dbMovie.Map(movie); 

     _context.Movies.Update(dbMovie);
     _context.SaveChanges(); 

     return NoContent();


[HttpDelete("{id}")]
[ServiceFilter(typeof(ValidateEntityExistsAttribute<Movie>))]
public IActionResult Delete(Guid id)
{
    var dbMovie = HttpContext.Items["entity"] as Movie; 

     _context.Movies.Remove(dbMovie);
     _context.SaveChanges(); 

     return NoContent();
}

Awesome.

Now our actions look great without code repetition, try-catch blocks or additional fetch request towards the database.

Conclusion

Thank you for reading this article. We hope you have learned new useful things.

As we already said, we always recommend using Action Filters because they give us reusability in our code and cleaner code in our actions as well.



ASP.NET Core Hosting :: How to Add Custom Processing to Request in ASP.NET

clock January 22, 2019 08:57 by author Jervis

When a request comes in to your ASP.NET site, it's routed through a series of message handlers (in ASP.NET Web API) or modules (in ASP.NET MVC), each of which performs some operation on the request. After a request is processed (presumably, by one of your Controllers), the response from your request goes through those handlers or modules again on its way back to the client.

Putting code in a handler or module allows you to perform some operation on every inbound request or outbound response. So, for example, if you want to customize security for your site, a good way to do that is to add your own module or handler to this chain. Alternatively, if you wanted to check data leaving your Web API site for "sensitive" information, a module or handler would be a good choice for that task, also.

The Limitations of ASP.NET Modules

Of the two technologies, ASP.NET MVC's HttpModules are the most limited. In many ways, modules are legacy technology dating from the beginnings of ASP.NET. However, this is the only option if you really do want to process every request to your site (including, for example, requests for image files and CSS files). You can even use HttpModules in Web API application.

The problem here is that the methods in a module are passed an HttpApplication object that has Context, Request and Response properties. These properties give you access to information about the request being made to your site and the response your site is returning. These are the same objects you have access to in your Controllers and, as in your Controllers, most of the properties on these objects are read-only. So, in an HttpModule you're limited to reading the incoming request or response or adding/removing headers on them.

Creating an HttpModule

Creating a module is a bit of a pain, also. First, you need to declare a class that implements the IHttpModule interface and give it a property called ModuleName that returns the name of your class as a string. You'll also need a Dispose method. Here's the start of a typical module:

public class GenericHttpModule : IHttpModule
{
  public String ModuleName
  {
    get
    {
      return "GenericHttpModule";
    }
  }
  public void Dispose() { }

Your next step is to add the Init method, which returns nothing but accepts an HttpApplication object. In this method, to process incoming requests, you need to wire up a method of your own to the HttpApplication object's BeginRequest method; if you want to process the outbound Response, you'll wire up your method to the object's EndRequest method. Here's an Init method that does both:

public void Init(HttpApplication application)
{
  application.BeginRequest += (new EventHandler(Inbound));
  application.EndRequest += (new EventHandler(Outbound));
}

The signatures of both the BeginRequest and EndRequest methods are the same: The methods are passed two parameters, one of type object and one of type EventArgs. The first parameter is the interesting one because it holds a reference to the HttpApplication object that holds the Context, Request and Response properties. The two methods I would need to work with the code in my Init method would look like this:

private void Inbound(Object source, EventArgs e)
{
  HttpApplication application = (HttpApplication)source;
  // ... process inbound request ...
}
private void Outbound(Object source, EventArgs e)
{
  HttpApplication application = (HttpApplication)source;
  // ... process outbound request ...            
}

You have one final thing to do: To have ASP.NET actually use your module, you need to tell your application about it. You do that in your web.config file with an add element, inside its modules element (IIS 7.0) or its httpModules element (IIS 6.0/IIS 7.0 running in Classic mode). The add element must reference both the name of your class and its type. This element would tie my sample module into the chain in IIS 7.0 (and would do the same in the httpModules element):

<modules> <add name="GenericHttpModule" type="HttpModulesAPI.GenericHttpModule"/>

The Basics of Handlers

Creating an ASP.NET Web API handler is, comparatively speaking, much simpler.

First, you must create a class that inherits from DelegatingHandler. Once you've done that, you override your class's SendAsync method. When a request hits your site, your SendAsync method will be passed the incoming request as an HttpRequestMessage. You have more flexibility here than you do with modules: you can add or remove headers or replace the message's content.

When you've done whatever you want with the incoming request, you call the base class's SendAsync method, passing the request message (there's also a cancellation token involved but I'll ignore it for simplicity's sake). Calling the base SendAsync method passes the request on to the next handler in the chain and, eventually, to your controller.

After your Controller has processed your request, the response message will be returned back through the chain of handlers as an HttpResponseMessage object. That means that your call to the base SendAsync method will, eventually, return the response from your Controller to your handler. Again, you can add or remove headers or replace the message's Content before returning the message to the ASP.NET process that called your delegating handler in the first place. Eventually, that response message will be delivered to the client that made the original request.

Here's the skeleton of a typical handler:

public class GenericMessageHandler : DelegatingHandler
{
  protected async override System.Threading.Tasks.Task<HttpResponseMessage>
          SendAsync(HttpRequestMessage request,
          System.Threading.CancellationToken cancellationToken)
  {
    //...work with HttpRequestMessage...
    HttpResponseMessage resp = await base.SendAsync(request, cancellationToken);
    //...work with HttpReqponseMessage
    return resp;
  }
}

And, in fact, you don't have to call the base SendAsync method at all -- there's nothing stopping you from creating an HttpResponseMessage in your SendAsync method and returning that.

Adding Your Handler to the Pipeline

To have your application use your handler, go to your App_Start folder, open the WebApiConfig file and add your new handler class to the config parameter's MessageHandlers class. This code, for example, adds my handler to the pipeline:

config.MessageHandlers.Add(new GenericMessageHandler());

But I have to be honest here: My experience has been that (outside of security) there are very few operations that I want to perform on every request to my ASP.NET Web API site. As a result, my typical handler begins with a bunch of If statements that check to see if this is a request that my handler should work with. In those scenarios, ASP.NET Web API gives me alternative: I can add the relevant handler just to the specific routes where it's needed.

To do that, I go to ASP.NET Web API's WebApiConfig file in the App_Start folder and add a fifth parameter to the MapHttpRoute method used to define routes (to use this parameter, you must provide a value for the constraints parameter on the method, even if all you provide is null). The handler parameter allows me to specify a DelegatingHandler to be used in processing requests and responses in that route. Here's an example with my GenericMessageHandler added to a route that grabs requests for my Customer controller (as this code shows, to tie my handler into the processing pipeline I also have to set its InnerHandler property to HttpControllerDispatcher):

config.Routes.MapHttpRoute(
                name: "CustomerApi",
                routeTemplate: "api/Customer/{id}",
                defaults: new { id = RouteParameter.Optional },
                constraints: null,                            
                handler: new GenericMessageHandler(){InnerHandler = new HttpControllerDispatcher(config) }
            );

I can, of course, selectively add this handler to multiple routes.

So if you want to add processing to every request that your site gets (or even just some of them), then you don't have to add code to every Controller or Action method in your project. You can, instead, bundle that code into either a module (for ASP.NET MVC) or a handler (for ASP.NET Web API).



ASP.NET Core Hosting :: 5 Reasons to Use ASP.NET Core

clock January 9, 2019 08:33 by author Jervis

When it comes to web application development, there are multiple technologies available to choose from. There are open-source technologies like Java & PHP, and then, there is closed-source technology ASP.NET MVC.

While millions of web developers use ASP.NET MVC to build web applications, but the latest ASP.NET Core framework offers far more benefits than the ASP.NET MVC for web application development.

ASP.NET Core is an open-source, cross-platform framework developed by both the Microsoft and its community. Basically, it is a complete reform of ASP.NET that combines MVC structure and Web API into a single framework.

Why Use ASP.NET Core for Web Application Development?

ASP.NET Core is an emerging, robust, and feature-rich framework that provides features to develop super-fast APIs for web apps.

Let’s take a look at the elements that make ASP.NET Core a right choice for Enterprise app development

1 — The MVC Architecture

Back in the days of the classic ASP.NET, developers had to worry about IsPostBack & ViewState. But with MVC, web application development has become more natural and the workflow also more efficient. In addition, the latest ASP.NET Core framework further helps in developing web APIs & web applications testable in better way, by achieving a clear separation of concerns.

In simple terms, ASP.NET Core makes it easier for developers to code, compile, and test something in either model, view, or the controller.

2 — Razor Pages

Razor Pages is a new element of ASP.NET Core that makes programming page-focused scenarios more productive. In technical terms, Razor Pages is a page-based coding model that makes building web UI easier.

If you’ve ever worked on ASP.NET MVC framework before, then you already know that the controller classes are filled with a large amount of actions. And not only that, but they also grow as the new things are added.

With Razor Pages, each web page becomes self-contained with its View component, and the code is also organized well together.

3 — Provides Support for Popular JavaScript Frameworks

Unlike ASP.NET MVC, the new .NET Core framework provides build-in templates for two most popular JavaScript frameworks — Angular & React (plus Aurelia).

The JavaScriptServices in the new ASP.NET Core provides an infrastructure that developers need to develop client-side apps using the above mentioned JavaScript frameworks.

The JavaScriptServices basically aims to eliminate underlying plumbing to allow developers start coding applications sooner, making it possible to build feature-rich front-end web applications.

4 — Improved Collaboration & Cross-Platform Support

ASP.NET Core is a cross-platform framework, meaning the apps build using this framework can run on Windows, Linux, and Mac Operating systems. In addition, the developers are also free to choose their development OS as well.

In simple terms, your developers can work across Linux, MacOS, or Windows and they can still collaborate on the same project. This is possible with unified experience offered by the Visual Studio IDE.

In short, the ASP.NET Core framework has the capacity to build & run web applications on Windows, Linux, and Mac OS.

5 — In-Built Dependency Injection Support

ASP.NET Core framework provides an in-built dependency injection, meaning you do not need rely on third-party frameworks like Ninject or AutoFactor anymore.

Dependency Injection is basically a pattern that can help developer distinguish the different pieces of their apps. Before the release of ASP.NET Core, the only way to get Dependency injection in any application was by using the above mentioned frameworks (Ninject, AutoFactor). But in ASP.NET Core, the dependency injection is treated as a first-class citizen. What this means is that developers are no longer limited to web applications, and they can leverage new libraries in more event-driven apps such as AWS Lambda or Azure Functions.

Overall, the dependency injection in the ASP.NET Core framework improves the testability and extensibility of web applications. 



ASP.NET Core Hosting :: How to Use StructureMap with ASP.NET Core

clock January 8, 2019 10:26 by author Jervis

This example shows how to use Structuremap dependency injection framework with ASP.NET Core instead of framework-level dependency injection.

ADDING STRUCTUREMAP TO ASP.NET CORE PROJECT

For Structuremap support in ASP.NET Core application we need two NuGet packages

  • StructureMap - core StructureMap package
  • StructureMap.Microsoft.DependencyInjection - adds support for ASP.NET Core

These packages are enough for getting StructureMap up and running.

DEMO SERVICES

For demo purposes let's define primitive messaging service interface and couple of implementations.

public interface IMessagingService
{
    string GetMessage();
}

public class BuiltInDiMessagingService : IMessagingService
{
    public string GetMessage()
    {
        return "Hello from built-in dependency injection!";
    }
}

public class StructuremapMessagingService : IMessagingService
{
    public string GetMessage()
    {
        return "Hello from Structuremap!";
    }
}

We need two implementations to demonstrate how built-in dependency injection is replaced by StructureMap.

DEFINING STRUCTUREMAP REGISTRY

StructureMap uses registry classes for defining dependencies. Direct definitions are also supported but for more complex applications we will write registries anyway. Here is our registry class.

public class MyStructuremapRegistry : Registry
{
    public MyStructuremapRegistry()
    {
        For<IMessagingService>().LifecycleIs(Lifecycles.Container)
                                .Use<StructuremapMessagingService>();
    }
}

ATTACHING STRUCTUREMAP TO ASP.NET CORE APPLICATION

StructureMap is attached to ASP.NET Core when application is starting up. We have to make three updates to ConfigureServices() method of StartUp class:

  • initialize and configure StructureMap container
  • make ConfigureServices return IServiceProvider
  • return IServiceProvider by StructureMap

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddTransient<IMessagingService, BuiltInDiMessagingService>();

    var container = new Container();

    container.Configure(config =>
    {
        config.AddRegistry(new MyStructuremapRegistry());
        config.Populate(services);
    });

    return container.GetInstance<IServiceProvider>();
}

Notice that there is also dependecy definition for framework-level dependency injection. Let's see which implementation wins.

TRYING OUT STRUCTUREMAP WITH ASP.NET CORE 2.0

Let's make some minor updates to Home controller and Index view to get message from injected service and display it on home page of sample application.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ASPNETCoreTemplate.Services;
using Microsoft.AspNetCore.Mvc;

namespace ASPNETCoreTemplate.Controllers
{
    public class HomeController : Controller
    {
        private readonly IMessagingService _messagingService;

        public HomeController (IMessagingService messagingService)
        {
            _messagingService = messagingService;
        }

        public IActionResult Index()
        {
            ViewData["Message"] = _messagingService.GetMessage();

            return View();
        }

        public IActionResult Error()
        {
            return View();
        }
    }
}



ASP.NET Core 2 Hosting :: How to Fix Error 502.5 When Deploy Your ASP.NET Core

clock November 7, 2018 08:25 by author Jervis

I decide to make this tutorial as most of our users also experience same problem when deploying their ASP.NET Core application.

I recently hit this problem after manually modifying the web.config file. Fortunately, the problem is easy to fix.

In this post, we see two different causes of this error, two different solutions for the first cause, a solution for the second cause, and learn what needs to be in web.config for ASP.NET Core to operate.

The Error

Here is a screenshot of the HTTP Error 502.5 - Process Failure error. You'll see this, in your browser, when making a request to your ASP.NET Core application, after deployment, if you have this issue.

Why do I get the error?

 

The HTTP Error 502.5 - Bad Gateway and HTTP Error 502.5 - Process Failure error messages occur in ASP.NET Core when IIS fails to execute the dotnet process.

I've seen this error happen for two different reasons:

  • .NET Core Runtime is not installed
  • web.config file has not been transformed

How to Fix This Error?

This is very simple and easy to fix this issue. What you need to make sure is that your hosting provider support or already installed the latest ASP.NET Core on their hosting environment.

1. Install Latest .NET Core Runtime

You can download the latest .NET Core runtime from Microsoft's .NET download page.

For Windows, you'll usually want the latest .NET Core runtime (currently v2.1.1), as highlighted in the following screenshot:

This will get you the Windows Hosting Bundle Installer, which will install both the x86 and x64 runtimes on Windows Server.

2. Publish a Self-Contained Deployment

If you don't want to install the .NET Core Runtime. An alternative for .NET Core web applications is to publish them in the Self-Containeddeployment mode, which includes the required .NET Runtime files alongside your application.

You can select this option from the advanced publish settings screen in Visual Studio: 

If you go with this option, you'll also need to choose a target runtime: win-x86, win-x64, osx-x64, or linux-x64. Because self-contained deployments are not portable.

3. Transform your web.config file

Another reason for this error to occur is when you deploy an untransformed web.config file. This is likely to be your issue if you had a previously working web application and merely deployed a new version of it.

ASP.NET Core Web Config

In ASP.NET Core applications, the web.config file contains a handler that directs requests to the AspNetCoreModule and an aspNetCoreelement that defines and configures the ASP.NET Core process to execute your web application.

Here is a minimal web.config file for an ASP.NET Core application:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 
<system.webServer>
   
<handlers>
     
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
   
</handlers>
   
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="true"
       
stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
 
</system.webServer>
</configuration>

Note that it's possible that you don't have a web.config file in your ASP.NET Core project. If you do not, one will be generated for you when publishing the project, as IIS and IIS Express require a web.config file when hosting an ASP.NET Core web app.

The Issue

The untransformed web.config contains the variables %LAUNCHER_PATH% and %LAUNCHER_ARGS% rather than the correct paths. When IIS tries to run ASP.NET Core, it uses %LAUNCHER_PATH% and %LAUNCHER_ARGS% rather than the correct path and arguments.

To fix the HTTP Error 502.5 in ASP.NET Core, you need to transform the web.config and replace the untransformed web.config file on the IIS web server.

How do I transform web.config?

This transformation takes place when you choose to publish your web application. The transformed web.config ends up in the published output folder. Therefore, you simply need to publish your web application and copy the resulting web.config file onto the server.

In a transformed web.config file, the aspNetCore element will look something like this:

<aspNetCore processPath="dotnet" arguments=".\MyApplication.dll" stdoutLogEnabled="true"
    stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />

%LAUNCHER_PATH% has been replaced by dotnet and %LAUNCHER_ARGS% has been replaced by the path to the main web application dll .\MyApplication.dll.



ASP.NET Core Hosting - ASPHostPortal :: API Project ASP.NET Core

clock September 25, 2018 09:26 by author Jervis

In this post, we are going to write about what we consider to be the best practices while developing the .NET Core Web API project. How we can make it better and how to make it more maintainable.

Startup Class and the Service Configuration

In the Startup class, there are two methods: the ConfigureServices method for registering the services and the Configure method for adding the middleware components to the application’s pipeline.

So, the best practice is to keep the ConfigureServices method clean and readable as much as possible. Of course, we need to write the code inside that method to register the services, but we can do that in more readable and maintainable way by using the Extension methods.

For example, let’s look at the wrong way to register CORS:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials());
    });
}    

Even though this way will work just fine, and will register CORS without any problem, imagine the size of this method after registering dozens of services.

That’s not readable at all.

The better way is to create an extension class with the static method: 

public static class ServiceExtensions
{
    public static void ConfigureCors(this IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials());
        });
    }
}

And then just to call this extended method upon the IServiceCollection type:

public void ConfigureServices(IServiceCollection services)
{
    services.ConfigureCors();
}

Project Organization

We should always try to split our application into smaller projects. That way we are getting the best project organization and separation of concerns (SoC). The business logic related to our entities, contracts, accessing the database, logging messages or sending an email message should always be in a separate .NET Core Class Library project.

Every small project inside our application should contain a number of folders to organize the business logic.

Here is just one simple example how a complete project should look like: 

Environment Based Settings

While we develop our application, that application is in the development environment. But as soon as we publish our application it is going to be in the production environment. Therefore having a separate configuration for each environment is always a good practice.

In .NET Core, this is very easy to accomplish.

As soon as we create the project, we are going to get the appsettings.json file and when we expand it we are going to see the appsetings.Development.json file:

All the settings inside this file are going to be used for the development environment.

We should add another file appsettings.Production.json, to use it in a production environment:

The production file is going to be placed right beneath the development one.

Data Access Layer

In many examples and different tutorials, we may see the DAL implemented inside the main project and instantiated in every controller. This is something we shouldn’t do.

When we work with DAL we should always create it as a separate service. This is very important in the .NET Core project because when we have DAL as a separate service we can register it inside the IOC (Inversion of Control) container. The IOC is the .NET Core’s built-in feature and by registering a DAL as a service inside the IOC we are able to use it in any controller by simple constructor injection:

public class OwnerController: Controller
{
    private IRepository _repository;
 
    public OwnerController(IRepository repository)
    {
        _repository = repository;
    }
}

Controllers

The controllers should always be as clean as possible. We shouldn’t place any business logic inside it.

So, our controllers should be responsible for accepting the service instances through the constructor injection and for organizing HTTP action methods (GET, POST, PUT, DELETE, PATCH…): 

public class OwnerController: Controller
{
    private ILoggerManager _logger;
    private IRepository _repository;
 
    public OwnerController(ILoggerManager logger, IRepository repository)
    {
        _logger = logger;
        _repository = repository;
    }
 
    [HttpGet]
    public IActionResult GetAllOwners()
    {           
    }
 
    [HttpGet("{id}", Name = "OwnerById")]
    public IActionResult GetOwnerById(Guid id)
    {          
    }
 
    [HttpGet("{id}/account")]
    public IActionResult GetOwnerWithDetails(Guid id)
    {
    }
 
    [HttpPost]
    public IActionResult CreateOwner([FromBody]Owner owner)
    {       
    }
 
    [HttpPut("{id}")]
    public IActionResult UpdateOwner(Guid id, [FromBody]Owner owner)
    {         
    }
 
    [HttpDelete("{id}")]
    public IActionResult DeleteOwner(Guid id)
    {        
    }
}

Actions

Our actions should always be clean and simple. Their responsibilities include handling HTTP requests, validating models, catching errors and returning responses: 

[HttpPost]
public IActionResult CreateOwner([FromBody]Owner owner)
{
    try
    {
        if (owner.IsObjectNull())
        {
            return BadRequest("Owner object is null");
        }
 
        if (!ModelState.IsValid)
        {
            return BadRequest("Invalid model object");
        }
 
        _repository.Owner.CreateOwner(owner);
 
        return CreatedAtRoute("OwnerById", new { id = owner.Id }, owner);
    }
    catch (Exception ex)
    {
        _logger.LogError($"Something went wrong inside the CreateOwner action: {ex}");
        return StatusCode(500, "Internal server error");
    }
}

Our actions should have IActionResult as a return type in most of the cases (sometimes we want to return a specific type or a JsonResult…). That way we can use all the methods inside .NET Core which returns results and the status codes as well.

The most used methods are:

  • OK => returns the 200 status code
  • NotFound => returns the 404 status code
  • BadRequest => returns the 400 status code
  • NoContent => returns the 204 status code
  • Created, CreatedAtRoute, CreatedAtAction => returns the 201 status code
  • Unauthorized => returns the 401 status code
  • Forbid => returns the 403 status code
  • StatusCode => returns the status code we provide as input 

Handling Errors Globally

In the example above, our action has its own try-catch block. This is very important because we need to handle all the errors (that in another way would be unhandled) in our action method. Many developers are using try-catch blocks in their actions and there is absolutely nothing wrong with that approach. But, we want our actions to be clean and simple, therefore, removing try-catch blocks from our actions and placing them in one centralized place would be an even better approach.

.NET Core gives us an opportunity to implement exception handling globally with a little effort by using built-in and ready to use middleware. All we have to do is to add that middleware in the Startup class by modifying the Configure method:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 {
     app.UseExceptionHandler(config =>
     {
         config.Run(async context =>
         {
             context.Response.StatusCode = 500;
             context.Response.ContentType = "application/json";
 
             var error = context.Features.Get<IExceptionHandlerFeature>();
             if (error != null)
             {
                 var ex = error.Error;
 
                 await context.Response.WriteAsync(new ErrorModel()
                 {
                     StatusCode = 500,
                     ErrorMessage = ex.Message
                 }.ToString(); //ToString() is overridden to Serialize object
             }
         });
     });
 
     app.UseMvc();
}

We can even write our own custom error handlers by creating custom middleware: 

public class CustomExceptionMiddleware
{
    //constructor and service injection
 
    public async Task Invoke(HttpContext httpContext)
    {
        try
        {
            await _next(httpContext);
        }
        catch (Exception ex)
        {
            _logger.LogError("Unhandled exception ...", ex);
            await HandleExceptionAsync(httpContext, ex);
        }
    }
   
    //additional methods
}

After that we need to register it and add it to applications pipeline: 

public static IApplicationBuilder UseCustomExceptionMiddleware(this IApplicationBuilder builder)
{
    return builder.UseMiddleware<CustomExceptionMiddleware>();
}

Using ActionFilters to Remove Duplicated Code

Filters in ASP.NET Core allows us to run some code prior to or after the specific stage in a request pipeline. Therefore, we can use them to execute validation actions that we need to repeat in our action methods.

When we handle a PUT or POST request in our action methods, we need to validate our model object as we did in the Actions part of this article. As a result, that would cause the repetition of our validation code, and we want to avoid that (Basically we want to avoid any code repetition as much as we can).

We can do that by using the ActionFilters. Instead of validation code in our action: 

if (!ModelState.IsValid)
{
  // bad request and logging logic
}

We can create our filter: 

public class ModelValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState); // returns 400 with error
        }
    }
}

And register it in the Startup class in the ConfigureServices method: 

services.AddScoped<ModelValidationAttribute>();

Now, we can use that filter with our action methods.

Microsoft.AspNetCore.All Meta-Package

This meta-package contains all of the AspNetCore packages, EntityFrameworkCore packages, SignalR package (from version 2.1) and the supporting packages required for running the framework. It is pretty convenient when starting a new project because we don’t have to manually install and reference all the packages we might need.

Of course, your machine needs to have the .NET Core runtime installed on it in order to use the AspNetCore meta-package.

Routing

In the .NET Core Web API projects, we should use Attribute Routing instead of Conventional Routing. That’s because Attribute Routing helps us match the route parameter names with the actual parameters inside the action methods. Another reason is the description of the route parameters. It is more readable when we see the parameter with the name “ownerId” than just “id”.

We can use the [Route] attribute on top of the controller and on top of the action itself: 

[Route("api/[controller]")]
public class OwnerController: Controller
{
     [Route("{id}")]
     [HttpGet]
     public IActionResult GetOwnerById(Guid id)
     {
           
     } 
}

There is another way to create routes for the controller and actions: 

[Route("api/owner")]
public class OwnerController: Controller
{
     [HttpGet("{id}")]
     public IActionResult GetOwnerById(Guid id)
     {
           
     } 
}

There are different opinions which way is better, but we would always recommend the second way, and this is something we always use in our projects.

When we talk about the routing we need to mention the route naming convention. We can use descriptive names for our actions, but for the routes/endpoints, we should use NOUNS and not VERBS.

The few wrong examples: 

[Route("api/owner")]
public class OwnerController : Controller
{
    [HttpGet("getAllOwners")]
    public IActionResult GetAllOwners()
    {
    }
 
    [HttpGet("getOwnerById/{id}"]
    public IActionResult GetOwnerById(Guid id)
    {       
    }
}

The good examples: 

[Route("api/owner")]
public class OwnerController : Controller
{
    [HttpGet]
    public IActionResult GetAllOwners()
    {
    }
 
    [HttpGet("{id}"]
    public IActionResult GetOwnerById(Guid id)
    {         
    }
}

Logging

If we plan to publish our application to production, we should have a logging mechanism in place. Log messages are very helpful when figuring out how our software behaves in a production.

.NET Core has its own logging implementation by using the ILoggerinterface. It is very easy to implement it by using Dependency Injection feature: 

public class TestController: Controller
{
    private readonly ILogger _logger;
 
    public TestController(ILogger<TestController> logger)
    {
        _logger = logger;
    }
}

Then in our actions, we can utilize various logging levels by using the _logger object.

.NET Core supports logging API that works with a variety of logging providers. Therefore, we may use different logging providers to implement our own logging logic inside our project.

The NLog is the great library to use for implementing our own custom logging logic. It is extensible, supports structured logging and very easy to configure. We can log our messages in the console window, files or even database. 

CryptoHelper

We won’t talk about how we shouldn’t store the passwords in a database as a plain text and how we need to hash them due to security reasons. That’s out of the scope of this article. There are various hashing algorithms all over the internet, and there are many different and great ways to hash a password.

But if need the library that provides support to the .NET Core’s application and that is easy to use, the CryptoHelper is quite a good library.

This library is available for installation through the NuGet and its usage is quite simple:

using CryptoHelper;
 
// Method for hashing the password
public string HashPassword(string password)
{
    return Crypto.HashPassword(password);
}
 
// Method to verify the password hash against the given password
public bool VerifyPassword(string hash, string password)
{
    return Crypto.VerifyHashedPassword(hash, password);
}

Content Negotiation

By default .NET Core Web API returns a JSON formatted result. In most of the cases, that’s all we need.

But what if the consumer of our Web API wants another response format, like XML for example?

For that, we need to create a server configuration to format our response in the desired way: 

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(config =>
    {
        // Add XML Content Negotiation
        config.RespectBrowserAcceptHeader = true;
        config.InputFormatters.Add(new XmlSerializerInputFormatter());
        config.OutputFormatters.Add(new XmlSerializerOutputFormatter());
    });
}

Sometimes the client may request a format that is not supported by our Web API and then the best practice is to respond with the status code 406 Not Acceptable. That can be configured inside our ConfigureServices method as well: 

config.ReturnHttpNotAcceptable = true;

We can create our own custom format rules as well.

Using JWT

JSON Web Tokens (JWT) are becoming more popular by the day in the web development. It is very easy to implement JWT Authentication is very easy to implement due to the .NET Core’s built-in support. JWT is an open standard and it allows us to transmit the data between a client and a server as a JSON object in a secure way.

We can configure the JWT Authentication in the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
     services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
       .AddJwtBearer(options =>
       {
          options.TokenValidationParameters = new TokenValidationParameters
          {
             //Configuration in here
          };
       });
}

In order to use it inside the application, we need to invoke this code in the Configure method:

app.UseAuthentication();

We may use JWT for the Authorization part as well, by simply adding the role claims to the JWT configuration 

Conclusion

In this article, our main goal was to familiarize you with the best practices when developing a Web API project in .NET Core. Some of those could be used in other frameworks as well, therefore, having them in mind is always helpful.

If you find that something is missing from the list, don’t hesitate to add it in a comment section.

Thank you for reading the article and I hope you found something useful in it.



ASP.NET Core 2 Hosting - How to Publish ASP.NET Core 2

clock February 13, 2018 07:34 by author Jervis

This tutorial will show you how to publish ASP.NET Core on IIS. The following is steps by steps to deploy .net Core.

Program class in asp.net core 2.0 contains a method that is called “CreateDefaultBuilder”. It is responsible for setting up everything for your application related to hosting, manage server, IIS integration, create directory etc.

public class Program {  
    public static void Main(string[] args) {  
        BuildWebHost(args).Run();  
    }  
    public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args).UseStartup < Startup > ().Build();  
}

Just go through with CreateDefaultBuilder method's actual definition using F12 in Visual Studio, you can read the comment which specifies its tasks.

The deployment is not the same as Asp.Net, there are a few more components required to host your asp.net core 2.0 application on IIS. Before deploying, you have to install a bundle which is required to host Asp.Net Core 2.0 application on IIS and that is .Net Core Windows Server Hosting. This bundle will install .Net Core Runtime which provides all the required libraries on runtime, .Net Core Library and Asp.Net Core Module.

If you are still using Asp.Net Core 1.x then you can find out the “.Net Core Windows Server Hosting” bundle using the following link and install it.

Here we are using Asp.Net Core 2.0 application to deploy it on IIS, so we are going to download .Net Core Windows Server Hosting bundle from following link and install it with our system.

When it is in progress, you can see it is installing three main components: .Net Core Runtime, .Net Core Library and Asp.Net Core Module. As you can see in the following image, Microsoft .Net Core Runtime is being installed.

Warning

Please make sure you have restarted your system before moving to the next step after the installation of “Microsoft .Net Core Windows Server Hosting” bundles.

For this demonstration, we are using the same Asp.Net Core 2.0 application which we have created in previous article. To learn how to create First application in Asp.Net Core 2, please refer to following article.

First Application In ASP.NET Core MVC 2.0

Let’s move to Visual Studio 2017 version 15.3 which provides .Net Core 2 features.  Open the Asp.Net Core 2.0 application which we have created in last article. Open the solution explorer and right click to project and choose Publish option for publishing this web application.

It will open a new windows as following, which provide us three different options to publish our web application and these options are “Azure”, “IIS,FTP” and “Folder”. So, here are choosing “Folder” to publish our web content”. You have to provide the destination path where you would like to publish web application and then click to “Publish”.

It will start publishing content on selected folder as following image shown. Once everything will fine, it will show Publish Successes message.

Now it’s time to create a new website inside the IIS Manager, to open IIS Manager, just type “inetmgr” in “Search Program and files” in start menu. It will open IIS Manager for you as following image shown where you can manage you application.

Just right click to “Sites” and choose “Add Web Site..”.

In next window, you have to define you “Site Name”, physical path where you have published you application earlier and host name to find on web browser as below image. Don’t change Port and anything else and just click to OK.

Now we are almost done but need to change the “Application Pools” for this site. Click to application pools from the left panel and choose you pools as “asp.netcore2.com” and double click on that. Now you can edit you “Application Pool” for this website. From this window, you have to changes “.Net Framework  version” or “.Net CLR version” with “No Managed Code” and OK. 

Last thing, what you need to do, just make one entry about your application inside the host file, which is located on the following location. You have to add one more entry as we have done for asp.netcore2.com which directly points to localhost IP address.

C:\Windows\System32\drivers\etc

The time has come to run the application on the browser, so open any browser and just type asp.netcore2.com and press enter. Wow… you will get the following screen, which means the application has successfully hosted on IIS.



ASP.NET Core 1.0 Hosting - ASPHostPortal :: Publish Your First ASP.NET Core Project

clock October 7, 2016 20:37 by author Jervis

Here are simple tutorial how to build your ASP.NET Core application. It’s just simple steps and you can follow it easily.

Install .NET Core First

First, please make sure you install .NET Core SDK for Windows

With that installed, it’s time to build your first application.

Open up a command prompt (or use the in-built terminal in Visual Studio Code) and start by creating a folder for your application, then initialising it.

mkdir CoreApp
cd CoreApp
dotnet new

When you run the dotnet command for the first time you’ll see some information about how .NET Core collects usage data and initially populates a local package cache. Once you’ve seen this message you won’t see it again on the same machine.

Project.json and Program.cs File

One of the most striking things about getting started with .NET Core is that you don’t end up with lots of files and dependencies right out of the gate, just the minimum you need for an empty web site.

In fact, all you’ll be left with is a project.json and Program.cs file.

At this point, this is just a .net Core app (not web) which prints “Hello World” to the console.

If you take a look at project.json you’ll see the minimum dependencies your new .net core app needs to run.

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0"
        }
      },
      "imports": "dnxcore50"
    }
  }
}

When you create a new .net core application like this, it’s dependencies are not downloaded automatically. To do that, you simply need to issue a new command to restore the dependencies and then to run the app.

dotnet restore
dotnet run

Launch the Application

So your app just compiled and launched. It looks suspiciously like a console application, because it is a console application.

Up until now, everything you’ve done has resulted in a minimal .net core console application.

So how do you turn it into a web site?

Well you need to update project.json to tell it to add the Kestrel HTTP server as a dependency.

Kestrel is a lightning fast cross-platform web server which can be used to self-host your web application. In other words, you can tell your new web app that Kestrel is a dependency and then run your site on it without relying on IIS or IIS Express.

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0"
        },
        "Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
      },
      "imports": "dnxcore50"
    }
  }
}

You’ve added a dependency so now you need to download that dependency using the restore command.

dotnet restore

Incidentally, in case you’re wondering where donet restore is restoring packages to, the default location is %userprofile%\.nuget\packages

Next up, you’ll need to create a Startup.cs file. This will define how incoming web requests should be handled.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; 

namespace ConsoleApplication {
    public class Startup{
        public void Configure(IApplicationBuilder app){
            app.Run(context => {
                return context.Response.WriteAsync("Hello world");
            });
        }
    }
}

This is about as simple as it comes, you simply tell your app to always return a response and write the text “Hello world” to it (for any request to your web application).

At this point, you haven’t told your app to start Kestrel (to start accepting web requests). You can do that by updating Program.cs.

using System;
using Microsoft.AspNetCore.Hosting; 

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!"); 

            var host = new WebHostBuilder()
            .UseKestrel()
            .UseStartup<Startup>()
            .Build(); 

            host.Run();
        }
    }
}

Should you wish, you can happily delete Console.WriteLine("Hello World!") as you’ve replaced it with something far more useful, you’ve told Core to launch Kestrel using the Startup class you just created.

Go ahead and run your app.

dotnet run

You’ll see a message telling you that your app is up and running and where you can access it.

Hosting environment: Development
Content root path: C:\Users\Jervis\CoreApp\bin\Debug\netcoreapp1.0
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

Hit http://localhost:5000 in a browser!

 



Cheap ASP.NET 4.5 Hosting

We’re a company that works differently to most. Value is what we output and help our customers achieve, not how much money we put in the bank. It’s not because we are altruistic. It’s based on an even simpler principle. "Do good things, and good things will come to you".

Success for us is something that is continually experienced, not something that is reached. For us it is all about the experience – more than the journey. Life is a continual experience. We see the Internet as being an incredible amplifier to the experience of life for all of us. It can help humanity come together to explode in knowledge exploration and discussion. It is continual enlightenment of new ideas, experiences, and passions


Author Link

 photo ahp banner aspnet-01_zps87l92lcl.png

 

Corporate Address (Location)

ASPHostPortal
170 W 56th Street, Suite 121
New York, NY 10019
United States

Tag cloud

Sign in