Types Of Fliters In Net Core

 

Hello everybody,

today I want to make a short document about filters in .Net Core.

There are by default four types of filters:

  1. Filters that implement IAuthorizationFilter which allow us to implement OnAuthorization method which allow us to add custom security logic.
  2. Filters that implement IActionFilter has two methods: OnActionExecuting, OnActionExecuted. Those two methods executed before and after action executing.
  3. Filters that implement IExceptionFilter has method OnException, which allows to handle exceptions.
  4. Filters that implement IResultFilter has two methods: OnResultExecuting, OnResultExecuted.

Filters can be applied at controller or at action level. That gives following distinction in their lifetime, if some filter is applied at Controller level, then it will be executed at each action of a controller, which means some filter can make additional workload on your code.

Below goes example of creating filter, which by default generates exception:

public class HasApprovedFilter : AttributeIAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        throw new NotImplementedException();
    }
}

That filter is useless, but take note of class Attribute. 

General convention of IAuthorizationFilter is like this: in case if Authorization is correct, then method returns void, if not, we need to set result value on the context object.

No Comments

Add a Comment
 

 

How To Add Database Context To Filter In Net Core 2 0

 

Hello everybody,

today I want to write a short description on how to add database context to IAuthorizationFilter.

Imagine that you have following filter:

public class HasApprovedFilter : AttributeIAuthorizationFilter
{
    private SomeDbContext _context;
    public HasApprovedFilter(SomeDbContext context)
    {
        this._context = context;
    }
 
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.User;
        if (!user.Identity.IsAuthenticated)
        {
            return;
        }
 
        var userAdd = _context.;
 
        //var um = context.HttpContext.RequestServices.GetService();
    }
}

As you can see, that filter requires in constructor SomeDbContext. How to add pass it to this filter?

Basically you'll need two steps:

1. At Startup class, in method ConfigureServices add following line:

services.AddScoped<HasApprovedFilter>();

right before line services.AddMvc();

2. At needed controller or Action of controller you can make like this:

[ServiceFilter(typeof(HasApprovedFilter))]
public class HistoryController : Controller

such approach will allow you to have access to database at Filter level. 

Summary

ServiceFilter is entity which takes care about connecting your filter to dependency injection container. You can use it in order to pass not only DataBaseContext, but some other staff.

No Comments

 

Add a Comment
 

 

Net Core Tag Helpers

 

Hello everybody,

today I want to describe some .Net core tag helpers that you can use in order to create your web pages. There are plenty of already implemented tag helpers that can simplify your life as a developer.

Here is the list of already made:

  1. Anchor
  2. Cache
  3. Distributed
  4. Environment
  5. Form
  6. FormAction
  7. Img
  8. Input
  9. Label
  10. Link
  11. Option
  12. Script
  13. Select
  14. TextArea
  15. ValidationMessage
  16. ValidationSummary

It is not a complete list, but I suppose those 16 elements help you to grasp how wide it's functionality.

Anchor Tag Helper

Consider following declaration:

<a asp-controller='Presenter' asp-action='Presentation' asp-route-id=@Model.PresenterID>Presenter ID@Model.PresenterID</a>

List of Anchor tag helper attributes:

Anchor tag helper attribue Meaning
asp-controller Points to mvc controller ( for example Home or Account ). Word controller should be ommited
asp-action Points to view in controller ( for example index ). BTW, if you will write index, then only controller will be generated
asp-route Create routing between method of controller and name parameter of Rout Attribute. See image below table for visual explantion.
asp-route-{value}

Allows to generate urls with parameters. For example

<a asp-controller='Presenter' asp-action='Detail' asp-route-id=@Model.PresenterId>PresenterId@Model.PresenterId</a>
with following controller:

       [Route("Presenter/{id:string}")]
       public IActionResult Detail(string id)
       {

will generate following html:

<a href="Presenter/20">PresenterId: 20</a> 

In case if in model.PresenterId will be value 20

But if you change previous controller like this:

[Route("Presenter")]
       public IActionResult Detail(string id)
       {

then generated html will be like

<a href="Presenter?id=20">PresenterId: 20</a>

You can have as many as you want/need -{value} in your anchor tag

asp-all-route-data

Imagine situation that you don't know all your attributes for some reason. With asp-all-route-data you can genrate those attributes dynamically. Like this:

@{
    var prsenters = 
        new Dictionary<stringstring>
        {
            {"id""20"},
            {"presenter1""RobMartin"},
            {"presenter2""MartinFowler"}
        };
}
 
<a asp-route="presenters" asp-all-route-data="prsenters">Presenters</a>

and controller declared like this

       [Route("Presenter/{id:string}", Name = "presenters")]
       public IActionResult Presenters(string id)
       {

will give you following html output:

<a href="/presenters/20?presenter1=RobMarting&amp&amp;presenter2=MartinFowler"

asp-fragment Allows to define bookmarks in html which is possible to navigate.
asp-area

Allows you to add addional navigation.

 

asp-protocol Sets the protocol. Values can be http or https. If attribute asp-protocol is defined that full domain will be included in url. 

I recommend always to use asp-controller with asp-action in order not to confuse other developers and yourself later with questionmark what will be generated as outcome.

asp-route explanation. Imagine that you wrote following code in your cshtml view:

<a asp-route='presenterdetails'>Presentations</a>

According to traditional rules you may be puzzled how .Net core will be able to bind your anchor tag with contoller? Most probably somehow via asp-route. And you are correct. Take a look at following controller method declaration:

[Route("/Presenter/Presentations", Name = "presenterdetails")]
public IActionResult Presentations()
{
    return View();
}

.Net core will be able to bind your anchor to exact method via relationship asp-route <-> Name

or in the picture form:

Environment Tag Helper

Tag Environment allows you to render different content depending from environment at which you code works currently. For example you can use minimized jquery at production environment and not minimized jquery at development environment. 

Samples of declarations can be like this:

<environment names='Development'>
     <script
         src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.2.6/jquery.js">
     </script>
</environment>
 
<environment names='Staging,Production'>
      <script
           src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js">
      </script>
</environment>

and during development you will have option of deguggable js, while at production your pages will be reactive as well.

Cache Tag Helper

As it's name says Cache tag helper is intended for caching.

It can look like this:

<Cache expires-after="@TimeSpan.FromSeconds(15)">
    Cached time: @DateTime.Now
</Cache>

Presented declaration will create some html code that will remain unchanged 15 seconds. If you have some piece of code that generates some output inside of Cache tag, it will be preserved there for 15 seconds. 

Besides already mentioned attribute expires-after Cache tag helper has also the following attributes:

Attribute Functionality
expires-on This is time based expiration. Takes DateTime as parameter and expires according to passed DateTime
expires-after This is time based expiration. Takes TimeSpan. This is most commonly used attribute which preserves some content for some amount of time. 
expires-sliding This is time based expiration. Also takes as parameter TimeSpan, but each calling to cache will prolong caching for TimeSpan amount of time. If your site is heaviliy loaded then your content can last forever
vary-by-header This is so called list type expiration. Following code
<Cache vary-by-header="User-Agent,Accept-Language">
    Time cached : @DateTime.Now
</Cache>
will tell to .Net Core to refresh content if User-Agent, Accept-Language attribute of header was changed.
vary-by-query This is so called list type expiration. This is useful if you want to cache according to query parameters. Example of usage:
<Cache vary-by-query="param1,param2">
    Time cached according to param1, param2 : @DateTime.Now
</Cache>
vary-by-route This is so called list type expiration. This attribute looks at mvc attribute Route for caching. It means different routes can be cached.
vary-by-cookie This is so called list type expiration. Very similar to previous, just instead of passing route we pass cookie names here.
vary-by-user Takes bool parameter. One interesting feature of this attribute: no user is also treated as some abstract user and will be treated correspondingly.
vary-by Probably most  cunny attribute. For example this code
<Cache vary-by='@Model.Sum'>Time  : @DateTime.Now</Cache>
 allows to cache displayed time by some results of Sum calculation. vary-by allows to cache anything that is in our model.
vary-by-priority  It can have one of four enum values:
@CacheItemPriority.Low
@CacheItemPriority.High
@CacheItemPriority.Normal
@CacheItemPriority.NeverRemove
 
enabled Simply means enable or disable the cache. 

List type expiration means that you can pass list of comma separated values as parameter. 

Script tag helper

Besides features of standard html features script tag helper has additional features:

  1. Cache breaking. With attribute asp-append-version allow you to add ?v=someparame to your src attribute and will make your js not cached at all. Keep in mind though that this mechanism works for local files, not for remote urls. 
  2. Mask input for js file reading. Two attributes are asp-src-include and asp-src-exclude. They can look like this
    <script asp-src-include="/js/**/*.js" asp-src-exclude="/js/folder1/sub"  ></script>. Single start references single folder. Double start will include all folder and subfolders. That code will include all js files from folder js except those that are in folder folder1/sub.
  3. Load js if some cdn js is not available: asp-fallback-src

Ling tag helper

It is the same as script tag helper, but instead of src uses href. For example instead of asp-src-include it uses asp-href-include. 

Distributed Cache Tag Helper

It has the same parameters as cache helper but as name implies intended for providing distribution. Also it has the same attributes as Cache tag helper. The main difference is that Distributed cache helper allows injection of cache managers of your choice instead of built in InMemory cache helper. Among options can be redis or MS SQL cache. Another difference is that distributed cache requires attribute name to be set. It should be unique name in your whole web application. Consider some steps that you'll need in order to use SQL server cache:

  1. Add following nuget package: Microsoft.Extensions.Caching.SqlServer
  2. Configure Startup.cs 
  3. Create table that will be used for caching

Below goes example of configuration of adding distributed service cache of MS SQL server in Startup.cs file:

services.AddDistributedSqlServerCache(sqlServerCacheOptions =>
            {
                sqlServerCacheOptions.ConnectionString =
                    Configuration.GetConnectionString("DefaultConnection");
                sqlServerCacheOptions.SchemaName = "dbo";
                sqlServerCacheOptions.TableName = "SQLCache";
            });

You can use then following SQL for caching

CREATE TABLE[dbo].[SQLCache](    
  [Id]
  [nvarchar](449) NOT NULL,
  [Value][varbinary](max) NOT NULL,
  [ExpiresAtTime][datetimeoffset](7) NOT NULL,
  [SlidingExpirationInSeconds][bigint]
  NULL,   
  [AbsoluteExpiration]
  [datetimeoffset](7) NULL,   
  CONSTRAINT[pk_Id] PRIMARY KEY 
    CLUSTERED([Id] ASC) WITH(PAD_INDEX = OFF, 
	STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
	ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
  ON[PRIMARY]) ON[PRIMARY] TEXTIMAGE_ON[PRIMARY]

After those steps your code will get option of distributed caching. Among benefits of distributed cache I want to name one: persistance of cache during application restarts.

Image Tag Helper

Starting from old time it was an issue of caching of images. As usually it happend that if you uploaded some image, your users were able to see only old images, not a new ones. With .Net core it's pretty easy to solve. Just add 

asp-append-version="true" to your img tag like this:

<img src='~/images/a.jpg' asp-append-version="true" />

At my computer following html was generated:

<img asp-append-version="true" src="/Images/aligator.png?v=dlnlj_gStnFeM9RM9ADAm1fZA-MN_U1ile9VNQXWTaA">

You can consider as asp-append-version cache breaker. One word of warning. src attribute should point to local file. If it points to some url image then be ready for caching in any case.

1 Comment

  • Vijay said

    I have to thank you for the efforts you have put in penning this site.

    I really hope to check out the same high-grade blog posts from you in the
    future as well. In fact, your creative writing abilities has
    encouraged me to get my very own blog now ;)

Add a Comment
 

 

How To Use Package Manager Console For Creating Migrations

 

Hello everybody,

today I want to describe some basic steps that you can use in order to create and apply migrations to your code.

So, let's start. 

Imagine that in your .Net Core project you made some changes and would like them to be created in a form of C# code migration. How to do this in package manager console? Below are steps that I've applied:

1. add-migration "identity"

2. update-database

Enjoy with results. The first command will create for your C# code that will describe which tables need to be created. Second command will execute that C# code and will create on your db them. 

1 Comment

  • Volodya said

    before 1 and 2 you also need following command to execute in package manager console:

    Enable-Migrations

Add a Comment
 

 

Different Types Of Views

 

Hello everybody,

today I want to write few words about different kinds of Views in .Net core.

So, if you decide somehow to create new view you can see something like this:

and now question. What is the difference between MVC View Page, MVC View Layout Page, MVC View Start Page and MVC View Imports page?

So, if to draw the lines then following can be said. 

MVC View Page is fitting for displaying different models.

MVC View Layout Page is inteded as View that has @RenderBody() statement. RenderBody will be placeholder where MVC View Page will be rendered. 

MVC View Start Page is used as mediator between MVC View Page and MVC View Layout page.

The last puzzling view is MVC View Imports file. 

@using DPlatform
@using DPlatform.Models
@using DPlatform.Models.AccountViewModels
@using DPlatform.Models.ManageViewModels
@using Microsoft.AspNetCore.Identity
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

As you can see it is just description of imports of models that will be used in your views. Or convenient way to avoid pointing at every view your usings.

No Comments

 

Add a Comment