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 Handle Multipart Request with JSON and File Uploads in ASP.NET Core

clock May 15, 2019 09:29 by author Jervis

Suppose we’re writing an API for a blog. Our "create post" endpoint should receive the title, body, tags and an image to display at the top of the post. This raises a question: how do we send the image? There are at least 3 options:

Embed the image bytes as base64 in the JSON payload, e.g.

{
    "title": "My first blog post",
    "body": "This is going to be the best blog EVER!!!!",
    "tags": [ "first post", "hello" ],
    "image": "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
}

This works fine, but it’s probably not a very good idea to embed an arbitrarily long blob in JSON, because it could use a lot of memory if the image is very large.

Send the JSON and image as separate requests. Easy, but what if we want the image to be mandatory? There’s no guarantee that the client will send the image in a second request, so our post object will be in an invalid state.

Send the JSON and image as a multipart request.

The last approach seems the most appropriate; unfortunately it’s also the most difficult to support… There is no built-in support for this scenario in ASP.NET Core. There is some support for the multipart/form-data content type, though; for instance, we can bind a model to a multipart request body, like this:

public class MyRequestModel
{
    [Required]
    public string Title { get; set; }
    [Required]
    public string Body { get; set; }
    [Required]
    public IFormFile Image { get; set; }


public IActionResult Post([FromForm] MyRequestModel request)
{
    ...
}

But if we do this, it means that each property maps to a different part of the request; we’re completely giving up on JSON.

There’s also a MultipartReader class that we can use to manually decode the request, but it means we have to give up model binding and automatic model validation entirely.

Custom model binder

Ideally, we’d like to have a request model like this:

public class CreatePostRequestModel
{
    [Required]
    public string Title { get; set; }
    [Required]
    public string Body { get; set; }
    public string[] Tags { get; set; }
    [Required]
    public IFormFile Image { get; set; }
}

Where the TitleBody and Tags properties come from a form field containing JSON and the Image property comes from the uploaded file. In other words, the request would look like this:

POST /api/blog/post HTTP/1.1
Content-Type: multipart/form-data; boundary=AaB03x  

--AaB03x
Content-Disposition: form-data; name="json"
Content-Type: application/json  

{
    "title": "My first blog post",
    "body": "This is going to be the best blog EVER!!!!",
    "tags": [ "first post", "hello" ]
}
--AaB03x
Content-Disposition: form-data; name="image"; filename="image.jpg"
Content-Type: image/jpeg  

(... content of the image.jpg file ...)
--AaB03x

Fortunately, ASP.NET Core is very flexible, and we can actually make this work, by writing a custom model binder.

Here it is:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json; 

namespace TestMultipart.ModelBinding
{
    public class JsonWithFilesFormDataModelBinder : IModelBinder
    {
        private readonly IOptions<MvcJsonOptions> _jsonOptions;
        private readonly FormFileModelBinder _formFileModelBinder; 

        public JsonWithFilesFormDataModelBinder(IOptions<MvcJsonOptions> jsonOptions, ILoggerFactory loggerFactory)
        {
            _jsonOptions = jsonOptions;
            _formFileModelBinder = new FormFileModelBinder(loggerFactory);
        } 

        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException(nameof(bindingContext)); 

            // Retrieve the form part containing the JSON
            var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);
            if (valueResult == ValueProviderResult.None)
            {
                // The JSON was not found
                var message = bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(bindingContext.FieldName);
                bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, message);
                return;
            } 

            var rawValue = valueResult.FirstValue; 

            // Deserialize the JSON
            var model = JsonConvert.DeserializeObject(rawValue, bindingContext.ModelType, _jsonOptions.Value.SerializerSettings); 

            // Now, bind each of the IFormFile properties from the other form parts
            foreach (var property in bindingContext.ModelMetadata.Properties)
            {
                if (property.ModelType != typeof(IFormFile))
                    continue; 

                var fieldName = property.BinderModelName ?? property.PropertyName;
                var modelName = fieldName;
                var propertyModel = property.PropertyGetter(bindingContext.Model);
                ModelBindingResult propertyResult;
                using (bindingContext.EnterNestedScope(property, fieldName, modelName, propertyModel))
                {
                    await _formFileModelBinder.BindModelAsync(bindingContext);
                    propertyResult = bindingContext.Result;
                } 

                if (propertyResult.IsModelSet)
                {
                    // The IFormFile was sucessfully bound, assign it to the corresponding property of the model
                    property.PropertySetter(model, propertyResult.Model);
                }
                else if (property.IsBindingRequired)
                {
                    var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName);
                    bindingContext.ModelState.TryAddModelError(modelName, message);
                }
            } 

            // Set the successfully constructed model as the result of the model binding
            bindingContext.Result = ModelBindingResult.Success(model);
        }


    }
}

To use it, just apply this attribute to the CreatePostRequestModel class above:

[ModelBinder(typeof(JsonWithFilesFormDataModelBinder), Name = "json")]}
public class CreatePostRequestModel

This tells ASP.NET Core to use our custom model binder to bind this class. The Name = "json" part tells our binder from which field of the multipart request it should read the JSON (this is the bindingContext.FieldName in the binder code).

Now we just need to pass a CreatePostRequestModel to our controller action, and we’re done:

[HttpPost]
public ActionResult<Post> CreatePost(CreatePostRequestModel post)
{
    ...
}

This approach enables us to have a clean controller code and keep the benefits of model binding and validation. It messes up the Swagger/OpenAPI model though, but hey, you can’t have everything!



ASP.NET Core Hosting :: How to Access HttpContext Outside of Framework Components in ASP.NET Core

clock March 13, 2019 08:44 by author Jervis

When developing web applications with ASP.NET, it is common to end up in situations where you require access to HttpContext. This wouldn’t be anything special, but outside of the context of framework level APIs such as controllers, middleware and so on (which would always give you a way to fetch the current HttpContext), it can be tricky.

While generally speaking, HttpContext could be passed around as a regular dependency to the logical components that require it, that solution is often impractical.

Let’s have a look at how you can get a hold of HttpContext in ASP.NET Core.

HttpContextAccessor

ASP.NET Core provides a convenience interface, IHttpContextAccessor (and it’s default implementation, HttpContextAccessor) in order to simplify accessing HttpContext. It must be registered at application startup inside the IServicesCollection and once it’s there, the framework will make sure that you can inject it anywhere you need, and use it to access the current instance of HttpContext.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

HttpContextAccessor under the hood

So how does it work? Consider piece of code you can find in any ASP.NET Core template:

    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .Build(); 

            host.Run();
        }
    }

It provides the launch point of your application. This is going to start the server and boostrap all the necessary services, including building up the request processing pipeline from your Startup class.

Internally, in the process of that bootstrapping, that code will wire in the relevant server (Kestrel) and will create an instance of HostingApplication and pass into it an implementation of IHttpContextFactory (more on that later).

HostingApplication is an implementation of IHttpApplication which exposes three methods:

    public interface IHttpApplication<TContext>
    {
        /// <summary>
        /// Create a TContext given a collection of HTTP features.
        /// </summary>
        /// <param name="contextFeatures">A collection of HTTP features to be used for creating the TContext.</param>
        /// <returns>The created TContext.</returns>
        TContext CreateContext(IFeatureCollection contextFeatures); 

        /// <summary>
        /// Asynchronously processes an TContext.
        /// </summary>
        /// <param name="context">The TContext that the operation will process.</param>
        Task ProcessRequestAsync(TContext context); 

        /// <summary>
        /// Dispose a given TContext.
        /// </summary>
        /// <param name="context">The TContext to be disposed.</param>
        /// <param name="exception">The Exception thrown when processing did not complete successfully, otherwise null.</param>
        void DisposeContext(TContext context, Exception exception);
    }

The server that we are using (say, Kestrel), on each incoming request, will use the above interface to call CreateContext and later on ProcessRequestAsync.

The former method is where IHttpContextFactory will be used to initialize HttpContext instance, and that instance will live throughout the lifetime of the HTTP request. The default implementation of IHttpContextFactory will look into the DI container, and check if IHttpContextAccessor is there. If it is, then it will “share” its HttpContext instance with the accessor.

The HttpContextAccessor will then store the HttpContext using System.Runtime.Remoting.Messaging.CallContext on desktop CLR and using System.Threading.AsyncLocal when built against .NET Standard.

If the accessor is not registered in the DI, then of course the context will not be saved anywhere. This is really important – and I have seen some questions already about that. If you just manually create an instance of HttpContextAccessor (which some people try), it will have no relationship to the HttpContextFactory or HttpContext, and the context will always be null. The accessor is merely a shortcut with a getter and setter, while all the logic of associating the HttpContext with the accessor instance is in HttpContextFactory.

And that’s basically how it works.

Injecting HttpContextAccessor

With all that set up, we could inject IHttpContextAccessor wherever we require access to the current instance of HttpContext. This of course means that your own components that rely on it, should be registered in/resolved from the IoC container too.

public class MyService
{
    private readonly IHttpContextAccessor _accessor; 

    public MyService(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    } 

    public void DoWork()
    {
        var context = _accessor.HttpContext;
        // continue with context instance
    }
}

Mimicking HttpContext.Current

One of the most infamous relicts of System.Web that is missing in ASP.NET Core is the static access to the current HttpContext.

I bet there is not a single ASP.NET developer, that, over the years, has not seen tons of programs, logic and extensions developed based on the magic and omnipresence of HttpContext.Current.

Now, trying to build your code around HttpContext.Current is really not a good idea, but I guess if you are migrating an enterprise type of app, with a lot of HttpContext.Current sprinkled around the business logic it may provide some temporary relief in terms of porting the application.

Our modern day HttpContext.Current would rely on resolving the context from IHttpContextAccessorand could look like this:

namespace System.Web
{
    public static class HttpContext
    {
        private static IHttpContextAccessor _contextAccessor; 

        public static Microsoft.AspNetCore.Http.HttpContext Current => _contextAccessor.HttpContext; 

        internal static void Configure(IHttpContextAccessor contextAccessor)
        {
            _contextAccessor = contextAccessor;
        }
    }
}

Notice, how we even placed it in System.Web namespace so that any potential migration you have is a bit easier.

We just need to add the code that will call into Configure as early as we can in the processing pipeline and pass in the IHttpContextAccessor. This can be achieved with two extension methods:

    public static class StaticHttpContextExtensions
    {
        public static void AddHttpContextAccessor(this IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        } 

        public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app)
        {
            var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
            System.Web.HttpContext.Configure(httpContextAccessor);
            return app;
        }
    }

The first one would be called from within ConfigureServices in your Startup and simply register the accessor in the DI. We have already established that this is necessary for the default IHttpContextFactory to share its instance of HttpContext correctly.

The second would be called from within Configure in your Startup, and it will make sure that our custom HttpContext.Current gets fed its IHttpContextAccessor so that it can work properly too.

And that’s it. Here is my Startup class which sets up the table for the static HttpContext.Current.

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpContextAccessor();
        } 

        public void Configure(IApplicationBuilder app)
        {
            app.UseStaticHttpContext();
            app.UseMvc();
        }
    }

And this is the rewritten example from above.

using System.Web; 

public class MyService
{
    public void DoWork()
    {
        var context = HttpContext.Current;
        // continue with context instance
    }
}

However, please think twice before going down that road.



ASP.NET Core MVC Hosting :: Dependency Injection Into Actions in ASP.NET Core MVC 2.1

clock March 4, 2019 10:15 by author Jervis

In this tutorial, we will see configuration about dependency injection into actions in ASP.NET Core MVC 2.1

The basic idea

Just in case what we are trying to achieve here is not obvious yet, here is an extremely basic layout of the problem. Let’s imagine having two separate services, with two separate implementations.

public interface IHelloService
{
    string SayHello();
}
public class HelloService : IHelloService
{
    public string SayHello() => "Hello";


public interface IGoodbyeService
{
    string SayGoodbye();


public class GoodbyeService : IGoodbyeService
{
    public string SayGoodbye() => "Bye";
}

For the sake of completeness, let’s also include a basic request DTO. It’s not needed at all, but I want to have it just to be able to illustrate that injecting dependencies as parameters will not interfere with regular binding process.

public class RequestDto
{
    public string Name {get; set;}
}

We’d like to consume them in a controller, but rather than doing this

public class GreetController : ApiController
{
    private readonly IHelloService _helloService;
    private readonly IGoodbyeService _goodbyeService; 

    public GreetController(IHelloService helloService, IGoodbyeService goodbyeService)
    {
        _helloService = helloService;
        _goodbyeService = goodbyeService;
    } 

    [HttpPost("hello")]
    public string Post(RequestDto input)
        => _helloService.SayHello() + " " + input.Name;        

    [HttpPost("bye")]      
    public string Post(RequestDto input)
        => _goodbyeService.SayGoodbye() + " " + input.Name;
}

I would want to see the following setup:

[Route("api/[controller]")]
[ApiController]
public class GreetController : ApiController
{
    [HttpPost("hello")]
    public ActionResult<string> Post(RequestDto input, IHelloService svc)
        => svc.SayHello() + " " + input.Name;        

    [HttpPost("bye")]      
    public ActionResult<string> Post(RequestDto input, IGoodbyeService svc)
        => svc.SayGoodbye() + " " + input.Name;
}

Note that the [ApiController] and ActionResult<T> were introduced in ASP.NET Core 2.1. They will actually impact the discussion, but more on that later.

Injection into actions

As I mentioned earlier, contrary to i.e. ASP.NET Web API, where we needed to override some internal components to make this, the basic scenario laid out here works out of the box in ASP.NET Core. The only caveat is that you have to decorate the parameter that you’d like to inject (resolve from the DI container) with a [FromServices] attribute.

[HttpPost("hello")]
public ActionResult<string> Post(RequestDto input, [FromServices]IHelloService svc)
     => svc.SayHello() + " " + input.Name;

We could finish the discussion here, as the goal is pretty much achieved. For example, I could issue a following request

curl -X POST \
  https://localhost:5001/api/greet/hello \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
"name":"jervis"
}'

and then get the following response:

Hello jervis

However, it is still possible to get rid of the [FromServices] attribute by establishing a reasonable convention. For example, we could easily detect at application startup, when the application model is composed, if a parameter is an interface, and if that’s the case, we would resolve it from the container.

In the past, in ASP.NET Core 2.0, this could be achieved by building an IApplicationModelConvention, registering it, iterating over all discovered controller, then over their actions and then over their parameters, and inspecting those. Then, marking the parameters we’d want to resolve from the DI container with a BindingSource.Services.

This would partially work in ASP.NET Core 2.1 too, however only if you wouldn’t use the new ApiControllerAttribute feature. That feature would validate whether your actions doesn’t inject more than one unannotated complex parameter into an action (which is essentially what we are doing) and throw an exception if that’s the case. That validation happens before our convention would run. The reason for this is that the ApiControllerAttribute feature is implemented as an IApplicationModelProvider which does similar stuff too IApplicationModelConvention – but providers run before the conventions do. So to address that we’d implement a custom provider instead.

public class ActionDependencyModelProvider : IApplicationModelProvider
{
    public int Order => -901; 

    public void OnProvidersExecuted(ApplicationModelProviderContext context)
    {
    } 

    public void OnProvidersExecuting(ApplicationModelProviderContext context)
    {
        foreach (var controllerModel in context.Result.Controllers)
        {
            foreach(var actionModel in controllerModel.Actions)
            {
                foreach(var parameterModel in actionModel.Parameters)
                {
                    if (parameterModel.ParameterType.IsInterface)
                    {
                        parameterModel.BindingInfo = new BindingInfo()
                        {
                            BindingSource = BindingSource.Services
                        };
                    }
                }
            }
        }
    }
}

Two implementation notes here – I used the Order value of -901 – that’s because the provider responsible for ApiControllerAttribute uses the value -900 and we’d want to run before it. Another thing is that we check for a parameter being an interface to resolve it from the DI container. Of course you are free to establish your own convention here (especially as it’s perfectly reasonable to have non-interface based dependencies). For example you could have a simple convention that 1st parameter would be bound from body and next ones from the container, or a convention where the assembly from which the Type comes dictates whether it’s a request model or a dependency, or simply some naming convention.

You’d just have to register this provider at startup, and that’s it. In our case the Startup registrations now look like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IHelloService, HelloService>();
    services.AddSingleton<IGoodbyeService, GoodbyeService>(); 

    services.TryAddEnumerable(
        ServiceDescriptor.Transient<IApplicationModelProvider, ActionDependencyModelProvider>());
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

And that’s it – you can now use your dependencies exactly as we defined it earlier:

[Route("api/[controller]")]
[ApiController]
public class GreetController : ApiController
{
    [HttpPost("hello")]
    public ActionResult<string> Post(RequestDto input, IHelloService svc)
        => svc.SayHello() + " " + input.Name;        

    [HttpPost("bye")]      
    public ActionResult<string> Post(RequestDto input, IGoodbyeService svc)
        => svc.SayGoodbye() + " " + input.Name;
}



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 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 :: 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 Hosting :: How to Setup URL Redirection

clock November 15, 2018 07:07 by author Jervis

We have so many clients asking about this issue. So, we decide to write this tutorial and hope this information can help other people too. In this review, we will write simple tutorial about how to setup http/https redirection in IIS.

There are lots of routing options accessible in ASP.NET but still it comes a time when you need to manipulate a URL and manipulating it outside a code comes handy. When this happens, the best you can do id to use IIS Rewrite Module. Transforming various URL’s out of code enables you to do various things including performing redirections for archive or transferred content without interfering with the code, you can easily implement SEO optimizations and tweaks quickly and easily without code and many more. Below is a collection of useful IIS rewrite rules that will help you understand IIS rewrites.

Useful IIS Rewrite Rules

Adding www Prefix

This is a basic rule that adds prefix “www” to any URL you need. This is a requirement for SEO.

Redirection from Domain 1 to Domain 2

This rule comes handy when you change the name of your site or may be when you need to catch and alias and direct it to your main site. If the new and the old URLs share some elements, then you could just use this rule to have the matching pattern together with the redirect target being.

HTTPS/HTTP Redirection

Redirecting users from HTTP to HTTPS is one of the reasons that you need to apply useful IIS rewrite rules. It can lead to conditional statements while looking for dev/test mode in your code. This rules allows you to handle the redirection without much statements which is tidier.

There is a pair of rules in this case each for one of the two ways. In both the rules, a check is performed to verify that the protocol used is http/https. The rules work on the same URL patterns or the similar lists of pages to match. For the redirect to HTTP, it is not about matching the pages; it is a reverse of the first rule and usually have a number of .NET/site paths that are excluded.

Setup Redirection Using IIS

Above steps is to setup URL redirection via your code. But, if you manage your own server, you can also setup redirection via IIS. The following is the steps

1. Download and install the “URL Rewrite” module.

2. Open the “IIS Manager” console and select the website you would like to apply the redirection to in the left-side menu:



3. Double-click on the “URL Rewrite” icon.

4. Click “Add Rule(s)” in the right-side menu.

5. Select “Blank Rule” in the “Inbound” section, then press “OK”:

6. Enter any rule name you wish.

7. In the “Match URL” section:

- Select “Matches the Pattern” in the “Requested URL” drop-down menu 
- Select “Regular Expressions” in the “Using” drop-down menu 
- Enter the following pattern in the “Match URL” section: “(.*)” 
- Check the “Ignore case” box

 

 

8. In the “Conditions” section, select “Match all” under the “Logical Grouping” drop-down menu and press “Add”.

9. In the prompted window:

- Enter “{HTTPS}” as a condition input 
- Select “Matches the Pattern” from the drop-down menu 
- Enter “^OFF$” as a pattern 
- Press “OK”

10. In the “Action” section, select “Redirect” as the action type and specify the following for “Redirect URL”:

https://{HTTP_HOST}/{R:1}

11. Check the “Append query string” box.

12.Select the Redirection Type of your choice. The whole “Action” section should look like this:

 

NOTE: There are 4 redirect types of the redirect rule that can be selected in that menu: 

- Permanent (301) – preferable type in this case, which tells clients that the content of the site is permanently moved to the HTTPS version. Good for SEO, as it brings all the traffic to your HTTPS website making a positive effect on its ranking in search engines. 
- Found (302) – should be used only if you moved the content of certain pages to a new place *temporarily*. This way the SEO traffic goes in favour of the previous content’s location. This option is generally not recommended for a HTTP/HTTPS redirect. 
- See Other (303) – specific redirect type for GET requests. Not recommended for HTTP/HTTPS. 
- Temporary (307) – HTTP/1.1 successor of 302 redirect type. Not recommended for HTTP/HTTPS.

13. Click on “Apply” on the right side of the “Actions” menu.

The redirect can be checked by accessing your site via http:// specified in the URL. To make sure that your browser displays not the cached version of your site, you can use anonymous mode of the browser.

The rule is created in IIS, but the site is still not redirected to https://

Normally, the redirection rule gets written into the web.config file located in the document root directory of your website. If the redirection does not work for some reason, make sure that web.config exists and check if it contains the appropriate rule.

To do this, follow these steps:

1. In the sites list of IIS, right-click on your site. Choose the “Explore” option:

 

2. “Explore” will open the document root directory of the site. Check if the web.config file is there.

3. The web.config file must have the following code block:

<configuration> 
<system.webServer> 
<rewrite> 
<rules> 
<rule name="HTTPS force" enabled="true" stopProcessing="true"> 
<match url="(.*)" /> 
<conditions> 
<add input="{HTTPS}" pattern="^OFF$" /> 
</conditions> 
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /> 
</rule> 
</rules> 
</rewrite> 
</system.webServer> 
</configuration>

4. If the web.config file is missing, you can create a new .txt file, put the aforementioned code there, save and then rename the file to web.config.

 

 



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 4.5 Hosting - ASPHostPortal :: Timeout in Regular Expressions ASP.NET 4.5

clock December 10, 2015 21:07 by author Jervis

Regular expressions are common forms of parsing a document and get meaning. It has been very popular and most of the people do use it regularly to solve their complex problems.

Lets start by the new Regex Api introduced with the framework. The improvement that has been made is minor yet handy at certain cases. The Regex class of .NET 4.5 supports Timeout. Lets take a look how to work with it.

Lets try to write a simplest RegEx validator to look into it. 

Try
{
    Regex regexpr =
new Regex("[A-Z ]{10}", RegexOptions.Singleline, TimeSpan.FromMilliseconds(1));
    Match mch = regexpr.Match(
"ABHISHEK SUR");
   
if (mch.Success)
        Console.WriteLine(
"Match found");
   
else
        Console.WriteLine(
"Not matched");

}
catch (RegexMatchTimeoutException ex)
{
    Console.WriteLine(
"Regex Timeout for {1} after {2} elapsed. Tried pattern {0}", ex.Pattern, ex.Message, ex.MatchTimeout);
}
catch (ArgumentOutOfRangeException ex)
{
    Console.WriteLine(ex.ToString());
}
finally
{
    Console.ReadKey(
true);
}

Here in the code you can see I simply check a string with a Regular expression. It eventually finds success as Pattern matches the string. Now this code is little different than what we have been doing for last few years. The constructor overload of Regex now supports a Timespan seed, which indicates the timeout value after which the Regular expression validator would automatically generate a RegexMatchTimeoutException. The Match defined within the Regex class can generate timeout after a certain time exceeds.

 You can specify Regex.InfiniteMatchTimeout to specify that the timeout does not occur. The value of InfiniteMatchTimeout is -1ms internally and you can also use Timespan.Frommilliseconds(-1) as value for timespan which will indicate that the Regular expression will never timeout which being the default behavior of our normal Regex class. Regex also supports AppDomain to get default value of the Timeout. You can set timeout value for "REGEX_DEFAULT_MATCH_TIMEOUT" in AppDomain to set it all the way through the Regular expressions being used in the same AppDomain. Lets take a look how it works.

Try
{
    AppDomain.CurrentDomain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromMilliseconds(2));

    Regex regexpr = new Regex("[A-Z ]{10}", RegexOptions.Singleline);
    Match mch = regexpr.Match("ABHISHEK SUR");
    if (mch.Success)
        Console.WriteLine("Match found");
    else
        Console.WriteLine("Not matched");

}
catch (RegexMatchTimeoutException ex)
{
    Console.WriteLine("Regex Timeout for {1} after {2} elapsed. Tried pattern {0}", ex.Pattern, ex.Message, ex.MatchTimeout);
}
catch (ArgumentOutOfRangeException ex)
{
    Console.WriteLine(ex.ToString());
}
finally
{
    Console.ReadKey(true);
}

Now this works exactly the same as the previous one. Here the Regex constructor automatically checks the AppDomain value and applies it as default. If it is not present, it will take -1 as default which is Infinite TImeout and also if explicitely timeout is specified after the default value from AppDomain, the Regex class is smart enough to use the explicitly set value only to itself for which it is specified. The Regex Constructor generates a TypeInitializationException if appdomain value of Timespan is invalid. Lets check the internal structure.

This is the actual code that runs in background and generates the timeouts. In fact while scanning the string with the pattern, there is a call to CheckTimeout which checks whether the time specified is elapsed for the object. The CheckTimeout throws the exception from itself.

The Constructor sets DefaultMatchTimeout when the object is created taking it from AppDomain data elements.

If you read MSDN thoroughly, it suggests to use Timeouts when specifying the Regular expressions. If the pattern is supplied from external or you are not sure about the pattern that needs to be applied to the string, it is always recommended to use Timeouts. Basically you should also specify a rational limit of AppDomain regex default to ensure no regular expression can ever hang your application.

This is a small tip on the new Regex enhancements introduced with .NET 4.5 recently.  

 



ASP.NET Hosting Tips - ASPHostPortal :: SQLParameters in ASP.NET C#

clock November 16, 2015 22:10 by author Jervis

SqlParameter represents a parameter to a SqlCommand and optionally its mapping to DataSet columns. Parameter names are not case sensitive. 

To initialize a new instance of SqlParameter class, we can use many constructors such as SqlParameter(), SqlParameter(String, SqlDbType), SqlParameter(String, Object), SqlParameter(String, SqlDbType, Int32), SqlParameter(String, SqlDbType, Int32, String). 

SqlParameter() constructor initialize a new instance of SqlParameter class. Sqlparameter(String, SqlDbType) constructor require parameter name and data type. SqlParameter(String, Object) constructor require parameter name and a value of the new SqlParameter. SqlParameter(String, SqlDbtype, Int32) constructor require parameter name, SqlDbType and size. SqlParameter(String, SqlDbtype, Int32, String) constructor require parameter name , SqlDbType, size and the source column name. 

SqlParameter class have many useful properties such as CompareInfo, DbType, Direction, IsNullable, Offset, ParameterName, Precision, Scale, Size, SourceColumn, SqlDbType, SqlValue, TypeName, Value, XmlSchemaCollectionName etc. 

ParameterName property get or set the SqlParameter name. SqlDbType property get or set the SqlDbType (SQL Server specific data type) for the parameter. SqlDbType enumeration values are BigInt, Binary, Bit, Char, Date, DateTime, Decimal, Float, Image, Int, Money, Real, Text, Time, Timestamp etc. SqlParameter Size property get or set the maximum size in bytes of the data within the column. Direction property get or set a value that indicate whether the parameter is input only, output only, bidirectional or a stored procedure return value parameter. Value property get or set the value of parameter. 

The following c# example source code describe you more about SqlParameter in ASP.NET. 

Create a web form name SqlParameterExample.aspx. Now add a GridView control. We populate the GridView control with SqlDataSource Data. But here we filter the data by SqlParameter. In this example we select the NorthWind database Products table data and filter it with SqlParameter product name. The source code of SqlParameterExample.aspx is here.

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Configuration" %>

<!DOCTYPE html>

<script runat="server">
    protected void Page_Load(object sender, System.EventArgs e) {
        if (!Page.IsPostBack) {
            SqlConnection MyConnection;
            SqlCommand MyCommand;
            SqlDataReader MyReader;
            SqlParameter ProductNameParam;

            MyConnection = new SqlConnection();
            MyConnection.ConnectionString = ConfigurationManager.ConnectionStrings["AppConnectionString1"].ConnectionString;

            MyCommand = new SqlCommand();
            MyCommand.CommandText = "SELECT * FROM PRODUCTS WHERE PRODUCTNAME = @PRODUCTNAME";
            MyCommand.CommandType = CommandType.Text;
            MyCommand.Connection = MyConnection;

            ProductNameParam = new SqlParameter();
            ProductNameParam.ParameterName = "@PRODUCTNAME";
            ProductNameParam.SqlDbType = SqlDbType.VarChar;
            ProductNameParam.Size = 25;
            ProductNameParam.Direction = ParameterDirection.Input;
            ProductNameParam.Value = "CHAI";

            MyCommand.Parameters.Add(ProductNameParam);

            MyCommand.Connection.Open();
            MyReader = MyCommand.ExecuteReader(CommandBehavior.CloseConnection);

            GridView1.DataSource = MyReader;
            GridView1.DataBind();

            MyCommand.Dispose();
            MyConnection.Dispose();
        }
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>SqlParameter example: how to use SqlParameter in asp.net</title>
</head>
<body>
   
<form id="form1" runat="server">
   
<div>
       
<asp:GridView ID="GridView1" runat="server">
       
</asp:GridView>
   
</div>
   
</form>
</body>
</html>

 



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