Conditional Ref, Ref ReadOnly, Ref Reassignment in C# 7.X

C# has gone through the major changes starting from 6.0 specifically from 7.0. I wrote a list of posts on C# new features which covers key topics that can be used in our day to day programming. You can find the previous posts list below

C# 7.X posts

Today we are going to discuss few uses of ref which provided altogether different meaning to it.

Conditional Ref: This feature was introduced in C# 7.2. Before going to this specific topic, we know that ref keyword has been in C# prior to 7.X and we used this keyword to pass the values by reference as

        static void Main(string[] args)
        {
            TestRef testRef = new TestRef() { Description = "First Object" };
            double price = 20;

            DoSomething(ref price, ref testRef);
            Console.WriteLine(price);
            Console.Write(testRef.Description);

            Console.ReadKey();
        }

        public static void DoSomething(ref double finalPrice, ref TestRef test )
        {
            finalPrice = finalPrice * 1.2;
            test = new TestRef() { Description = "Second Object" };
        }

   public class TestRef
    {
        public string Description { get; set; }
    }

Here I am passing a value type variable price and an object of a class type TestRef (we know classes are reference type). So let’s see the result before discussing it

Here we can see that  finalPrice is passed as ref parameter and when we are updating the value in the method, the updated value is available in caller function as it was passed using ref. Similarly in case of TestRef’s instance as ref parameter, a new instance is assigned to the variable then the variable in caller method also got updated with the new instance. It is because the instance testRef was pass passed using ref.

We have discussed few other usages of ref keyword which got introduced in 7.X, conditional ref are one of the interesting ones. We used ternary operator in past as

    var smallArray = new int[] { 1, 2, 3, 4, 5 };
    var largeArray = new int[] { 10, 20, 30, 40, 50 };

    int index = 7;
    int val = ((index < 5) ? smallArray[index] : largeArray[index - 5]);
    val = 0;

Here val gets assigned with value 0. If we change this value, no update takes place in the original array. Now let’s see the power of ref keyword here. We can see that based on condition first or second value is returned but now we can use ref keyword as

    ref int val = ref ((index < 5) ? ref smallArray[index] : ref largeArray[index - 5]);
    val = 0;

Here I am using the same array but here we are using the ref keyword in Consequent (smallArray), Alternative (largeArray) and put the ref at the whole ternary expression. Also, at left side added ref as ref int val. Removing any ref keyword will produce an error. If we want to store it as normal value then we may remove ref from left and outer ref from right.

Now val is pointing to the largeArray[2] and as we assigned it to 0, array also got updated.

Also as these ternary operator refers to a memory location so we may use it as LValue as

    ref ((index < 5) ? ref smallArray[index] : ref largeArray[index - 5]) = 0;

ref readonly: I discussed about ref keyword in one of my previous posts (refer here). It allows us to pass the values by reference, return the value by reference. But what about if we want to return a value which we dont want to get modified by the caller. Either we pass it by value (which creates a copy ) or we can use ref readonly. It will make sure the reference is returned (not the copy) but caller cannot modify the returned value. Let’s see an example


static void Main(string[] args)
{
    var points = new Point[] { new Point(1,2), new Point(1, 2), new Point(1, 2) };

    var point = new Point();
    point.SetPoints(points);

    ref readonly var myPoint = ref point.GetPoint(2);

    // It is a compile time error
    myPoint.Y = 10;

    Console.ReadKey();
}
	
struct Point
    {
        public int X;
        public int Y;

        public Point(int x, int y)
        {
            X = x;
            Y = y;
            points = null;
        }

        private Point[] points;

        public void SetPoints(Point[] arrPoint)
        {
            points = arrPoint;
        }

        public ref readonly Point GetPoint(int index)
        {
            if (points.Length &amp;gt; index)
                return ref points[index];
            else
                throw new KeyNotFoundException();
        }
    }

Here you can see GetPoint method in struct which returns one of the points from the array using ref keyword. Now if we want that the caller should not be able to modify it, then we need to put ref readonly in return type (not while returning). Now if you see while calling, we have to use ref on the right side and ref readonly on the left side and changing that variable would be a compile time error. As the method return ref readonly we cannot remove readonly from left side, however we can completely remove ref from both side including readonly then it will create a copy of the point.

If you remember In (about In)operator which allows the variable pass by reference but called method can’t modify that, it is opposite as Caller cannot modify the returned variable however the keywords are bit different.

As I used struct for the example which is value type and using operators like ref, In etc makes sure that we dont create a copy of that. However we know value type are easy to initialize and destroy in memory but Microsoft recommends that if the size of the struct is more than System.IntPtr.Size then we should avoid creating the copy of the struct.

Tip: Use the ref readonly for large structures and top preserve the immutability of the data structure.

Ref ReAssignment – This feature was added in C# 7.3 which allows us reassign a ref local variable to different location and obviously that should be of same type. Lets see an example

In this example I am going to use earlier Point class and just removed readonly from GetPoint method.

Here we can see a C# 7.2 feature where we get the reference of an array via ref and if we update the ref variable via another ref instance, it updates the original array as we can see in the tool tip.

Ref reassignment allows us to update ref local variables to different location which was not possible prior to C# 7.3 as

Here we can see refPoint was referencing to the last element of the array and once we assign to the first element, it started referring to the first object. This code will work only C# version is selected as 7.3.

As mentioned earlier, C# 7.X and 8.0 has lots of new features and few important ones we discussed earlier. In this post, we discussed three important features related to ref- Conditional ref, ref readonly, ref reassignment. Hope you have enjoyed the post.

Thanks
Brij

 

Advertisements

Hosting ASP.NET Core Applications on IIS – A Detailed Look

In last few years, I spent a significant amount of time researching, writing, speaking on ASP.NET application’s performance. Performance of a web app is not just its code but it depends a lot on the hosting platform, configurations and the usage of available resources etc. If you are hosting ASP.NET Webforms/MVC application on IIS, then you can follow below tips and get benefitted quickly.

12 tips to increase the performance of your ASP.NET application drastically – Part 1
12 tips to increase the performance of your ASP.NET application drastically – Part 2

Whenever I think about the performance of any web application, there are three major areas comes into my mind (I am not considering the external factors)

  1. Hosting Server
  2. Application itself
  3. Database/Third Party APIs etc

Any application can’t be highly performant until all three are properly optimized. It can perform better if all were taken in consideration in early stages development lifecycle.

ASP.NET Web Forms is/was very popular web framework but it has many known performance issues. To overcome many and to use latest standards and best practices, Microsoft introduced ASP.NET MVC framework. Over time, Microsoft sensed the need of new highly performant cross platform web framework to compete in market and introduced the all new ASP.NET Core framework (Initial Name: ASP.NET 5) which is written from scratch. Although at a high level, most of the constructs are similar with ASP.NET MVC but the underlying engine got completely rewritten.

While working on ASP.NET Core, MS worked on the complete stack, like for backend – they introduced Entity Framework core and for hosting the application, a new highly optimized web server, known as Kestrel. But as we know IIS provides an array of features, configuration and battle tested for all kind of scenarios, Kestrel was not ready as an edge server.

Although the new server was introduced with ASP.NET Core but it appears that initially, the main focus was on ASP.NET core and other backend frameworks. During ASP.NET 1.X, it was advised to used IIS as frontend server which in turn forwards the requests to Kestrel. A reverse proxy was suggested due to security and reliability reasons. It didn’t have defense against attacks and other configurations like various timeouts, size limits, concurrent connection limits etc. So, we only had the option to deploy the application using IIS (Nginx, Apache for other platforms) as reverse proxy. In the newer versions (ASP.NET Core 2.X), lot of enhancements has been made in Kestrel and with ASP.NET Core 2.1 and later, Kestrel started supporting https (which is nowadays basic requirement for hosting any web application on internet). Now it can be used as internet facing server . In this post and coming post, we will discuss the available deployment options with IIS and explore that what is happening behind the scene.

Using IIS as a Reverse Proxy:

In this scenario, ASP.NET Core application is hosted on kestrel which sits behind IIS. At a high level, it looks like

 

 

 

I created an asp.net core sample application which I deployed on IIS. Let’s take a quick look into the steps for deployment.

  1. First, we need to configure IIS on Windows (if it’s not there).
  2. Install the .NET Core Hosting Module (Can be downloaded from here based on the versions).  After installation, you can go to the IIS modules section and ANCM will appear as
  3. Create the website at IIS
    1. Create a folder which will contain app’s published folders, files and binaries
    2. Create a new logs folder inside the earlier created which will contain the logs created by ASP.NET Core module when stdout is enabled.
    3. In IIS, Add a new Website by right clicking on Sites folder under Connections -> ServerName as NetCoreProxy (say).
    4. It by default creates a new application pool named as preferably -. Go to application pools under Connections-> Server Name and Click on NetCoreProxy. Select “No Managed Code” under .NET CLR version 
      “No Managed Code” why? We will discuss it later.
    5. Check the identity which is by default as “AppPoolIdentity” and change it if needed.
  4. Last step, publish the website by Right Clicking on the project in Visual Studio in the newly created folder at 3 a.

Publishing the ASP.NET Core App

While publishing an ASP.NET Core app, we need to select the deployment mode option which has two options: Framework dependent and Self-Contained. Publishing with second option produces a significantly larger binaries because it contains the coreclr and other required system libraries. This should not be a preferred option until necessary because of the huge size and performance implications as it loads all the resources and JIT them on the fly.

Now we should be able to browse our ASP.NET core web site.

Let’s take a look in details

The first question that arises is why do we need to install something on IIS? One of the problems with earlier versions of ASP.NET, that ASP.NET and IIS both has its own pipeline which contains multiple modules (IIS pipeline contains native and managed modules) and each request has to go through both the pipelines invoking each module (However this problem was resolve till certain extent using Integrated Pipeline setting at IIS). Most of the times, many of them are not used by the appliccation. Using ASP.NET Core, we got a new pipeline which has list of middleware that are added at application startup based on the need. To avoid all the IIS overheads, when we install the bundle on IIS, it adds a native module AspNetCoreModule (ANCM) which is invoked at very early stage and forwards the requests to Kestrel as soon as it reaches to IIS. Earlier it was done by an existing module called HTTP Platform Handler which used to forward the request but MS decided to create a new native module ANCM which was fork of HTTP Platform Handler to have better control and able to provide tailored features.

Also, we have seen in deployment steps that we selected “No Managed Code” while configuring the application pool, it means we don’t want to run any managed modules for the requests of this application. As mentioned earlier, IIS pipeline contains the native and managed modules both, ASP.NET core requests do go through some of the native modules like authentication modules (Anonymous, basic, Windows etc), dynamic compression etc. Few native modules are not part of the process and as many of them has a corresponding asp.net core middleware (for details, look here). Let’s take a look that how does it work

We can see here that ASP.NET core app runs into a different process dotnet.exe, not in the worker process which was the case with earlier versions of ASP.NET. I also used the process explorer to see it

Here we can see that dotnet.exe is a different process which runs the application. What is this Console Host process? If we take a look in ASP.NET core’s startup class, we will see a main method, similar to console application which is the first method which gets called when the application starts.

Let’s go through step by step process, how a request is served in this scenario

  1. The request is received by the HTTP.sys from the network.
  2. If response is cached at HTTP.sys then it is sent back from there else gets a place the corresponding Application Pool’s queue.
  3. When a thread is available in the thread pool, it picks up the request and start processing it.
  4. The request goes through IIS processing pipeline. As mentioned earlier the request goes through few native IIS modules and once it reaches to ANCM, it forwards the request to Kestrel (under dotnet.exe).
  5. ANCM has a responsibility to manage the process as well. If (re)starts the process (if not running or crashed) and IIS integration middleware configure the server to listen the request on port defined in environment variable. It only accepts the requests which originates from ANCM.
    Note -Please do note that in ASP.NET Webforms/MVC the application is hosted under the worker process w3wp.exe which is managed by Windows Activation Service (WAS) which was part of IIS.
  6. Once the request is received by Kestrel, it creates the HTTPContext object and request is handed over to ASP.NET Core middleware pipeline.
  7. The request is passed to routing middleware which invokes the right controller and action method (model binding, various filters almost similar way as earlier versions).
  8. Finally, the response is returned from the action and passed to kestrel via Middlewares and later sent back to client via IIS.

So we can see the request processing is quite different than earlier versions ASP.NET apps hosted on IIS.

Using Kestrel as an Edge Server

With ASP.NET Core 2.1, Kestrel got lots of new capability which makes it capable of using it an edge server, however for the enterprise level application, it is still recommended to use it behind a proxy. Obviously, one of the first choices is using IIS in windows environment. With ASP.NET Core 2.2, It got some more refinement which makes IIS a better option. We will discuss that in next blog post. Kestrel as an edge server looks like

As this post is specific to IIS hosting, I will not go into the detail but earlier lots of important web server features like Keep alive timeouts, connection timeout, body reading timeouts, request timeouts, size limits, concurrent connection limits, memory limits etc were not available but now most of the configuration can be done and it supports https as well. Even with that Microsoft suggests using IIS as a reverse proxy due to additional feature, security, configurations and many more.

Hope you have enjoyed the post. Do share the feedback. In next post, We will discuss the In-process enhancement  in ASP.NET Core 2.2 in detail.

Cheers
Brij

TracePoint : An awsome feature of Visual Studio

Have you ever wanted to see the intermediate values of a variable which is inside a loop without pausing the execution via breakpoint?

I am sure you will say YES. A visual studio feature called Tracepoint can be very helpful in these scenarios.

Breakpoint allows to stop at a point where you can see the variable value but you may loose the track of it loops for more than 4-5 times.

Tracepoint is an awesome feature of Visual Studio and it is available since Visual Studio 2005. It allows you to write the values in output window without even stopping at any point or you can stop it after the loop and see how the loop progressed based on your needs. I recently started using it and found is very useful. I am sure it is relatively less used.

Let’s see an example. Here I have created a simple program which finds out the nth number in a fibonacci series. Lets see the code

Now I am going to set a tracepoint at line #41. To set up a tracepoint, one need to set up a breakpoint and right click on it which provides few options, then select Actions which opens window as

(In earlier versions of Visual Studio, the options was named as Choice which is Actions as mentioned above)

Here I have written i={i} => result={result} . The values insde {} are the variable names in the program and the value of these variables will be printed.

The messages will be logged in output window. See here the check box Continue Execution which is self explanatory. If you uncheck this then the breatpoint would be hit as normal and pause the execution. So lets run the program and see the output window

I have provaide value 7. Here you can see that the value got printed here for each loop iteration. This is quite useful if number are pretty high.

Debugging is also get tricky in case mutli-threading and asynchronous programming scenarios which is pretty common nowadays.

There are few others pseudo variables available which can be used display various other useful information as

Hope you have enjoyed the post.

Cheers,
Brij

How to know the version of MVC of an Existing Project

Hello All,

This is one of the common questions which we see often in various forums. Even I have struggled to find the exact version of the MVC earlier. It becomes more tricky as Micrososft releases new MVC versions at regular interval. Earlier each new release was a major release with release number like MVC 1, MVC 2, MVC 3, MVC 4,MVC 5 but recently we see new releases with minor version like MVC 5.1, MVC 5.2 and even now with build number like the upcoming one ASP.NET MVC 5.2.4 (while previous one 5.2.3). It also become more problematic sometimes when we upgrade the mvc version.

Note – The version of a software is normally denoted by four number separated by dots as x.x.x.x which is as Major.Minor.Build.Revision.

There are many ways to find the specific version. We will discuss few common ones here

1- The simplest way to open Web.Config file and look for System.Web.Mvc, you could see similar as

Here 5.2.3 is the current version.

2- We can check the references in the solution explorer, find out the System.Web.Mvc, right click on it and select properties as

3- If your project contain packages.config (normally every project has it), then we can find the version from here easily.     Search for Microsoft.AspNet.Mvc and you should find something as

4- We can get the MVC version programatically based on the need as

5- There is a nuget package available which provides lots of useful information named MVCDiagnostics which adds a     page  named mvcdiagnostics.aspx which displays other useful information along with MVC version. This package could be   very useful if you are upgrading to new version and facing issues. The page looks as

I have not included the complete page for brevity but lot more details are availble on this page.

Package can be installed from here

This is quick post on of the common questions. Hope you find it useful.

Cheers,
Brij

Presented in Cleveland .NET User Group on ASP.NET Performance tips

Hello All,

Recently I presented in Cleveland C#/VB.NET User group on my favorite topic ASP.NET. I was amazed with the response as it was a full house event even in the holiday season. The event took place on 28th Dec 2017 at Indepedence (Cleveland) ohio. I discussed “10 Tips to Make ASP.NET Apps Faster” which was loaded with cool Demos. Here is a glimpse of the room

 

I had lot of fun speaking there. Please find the slides here

Thanks a lot to the all the attendees and Cleveland .NET user group for hosting me as a Guest Speaker.

Cheers,
Brij

Learning ASP.NET Web API [Packt] – ASP.NET Core RC1 to ASP.NET Core 1.0

Hello All,

Recently, I published a video course on ASP.NET Web API using ASP.NET Core framework. Initially, when I started working on it, it was named as ASP.NET 5 and as it progressed till last section, Microsoft announced to rename it as ASP.NET Core and RC2 got released few days prior to the course release date. Microsoft took more than six months to release the next RC version. Although the concept was same but there were major changes in tooling and libraries. As it was not the final version so we decided to provide the details of differences once RTM releases.

In this post, I will be putting the details of the changes by section and also update the sample which will be available with the course. As ASP.NET 5 got renamed to ASP.NET Core, accordingly the names of libraries got changed to ASP.NET Core as well so we need to change all the references. The following table contains the details of packages that we need to update in our sample with the video number.

ASP.NET 5 Reference (Earlier) ASP.NET Core 1.0 Reference (Current) Video#
Microsoft.AspNet.Mvc Microsoft.ASPNETCore.MVC 2.2
EntityFramework.Core
EntityFramework.MicrosoftSqlServer
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
2.3
Microsoft.AspNet.Mvc.Formatters.Xml Microsoft.AspNetCore.Mvc.Formatters.Xml 2.4
Microsoft.AspNet.Mvc.TagHelpers
Microsoft.AspNet.Identity.EntityFramework
Microsoft.AspNetCore.Mvc.TagHelpers
Microsoft.AspNetCore.Identity.EntityFrameworkCore
5.4

Updated sample is available with the course and refer the project.json to find the updated references. Also, Microsoft again reintroduced web.config file but it will be there along with Project.json.

Note – The details will be included for only for those those sections where changes are required.

Section 2   
As this was the first section where we started our discussion on ASP.NET Core Web API and started working on our sample so this section got many changes. Let’s discuss each

Video 2.1 : There are changes in the project creation flow. Earlier when we used to create ASP.NET Core project, it used to have two sets of references – one for core and other for full framework. We either used to build the application using both the framework and remove one based on our needs. As there were many libraries which could not work in both the platforms so Microsoft has provided the option to select the framework upfront while creating the project which makes the complete process simpler. Also, in real world scenarios, there are rare chances when we need to build the binaries for both the framework.  Now when we open New Project window and select web from left side then we get three options as
2.1Here we have three options.

  1. First one is a traditional ASP.NET application using .NET 4.6.
  2. Selected one is ASP.NET Core application using .NET Core framework and the same is used in our course.
  3. Third one is again ASP.NET Core application but uses the standard .NET framework.

When we select the second option, it shows the following dialog

2.1_2

It also got revamped completely. We had earlier lots of options which included standard ASP.NET templates. Now it contains only ASP.NET Core templates and has three options same as earlier ASP.NET 5 templates and we used the empty template for our course. Just to mention again, now we have just one bag named as .NETCoreApp,Version=v1.0  which contains set of libraries for .NET Core only in the references.

There are some more changes as below

a) Earlier we used to have following line in startup.cs which was entry point for the web application

// Entry point for the application.
public static void Main(string[] args) => WebApplication.Run<Startup>(args);

but now we have a new file program.cs which contains the main method which is now entry point for the web application.

b) Configuration file web.config is also back in project file and available along with project.json although all the settings should be put in project.json and we will be using the same.

c) There are also changes in the number of the parameters in ConfigureServices method in startup.cs which includes Hosting Environment and logger factory but we will not be using it in our sample.

Video 2.2: Only change in the references. Refer the initial table.

Video 2.3: In this video, we discussed that there are four options to register a service but we found AddSingleton and AddInstance very similar, both allows single instance across multiple requests with a difference in the instance creation. Now we have only AddSingleton where either we can pass the instance or provide the type info as.

To register via interface and class name

services.AddSingleton<IBookStoreRepository, BookStoreRepository>();

and to register an instance

IBookStoreRepository bookStoreRepository = new BookStoreRepository(new BookStoreContext());
services.AddSingleton(bookStoreRepository);

Video 2.4: Only change in the references. Refer the table.

Section 3
In this section we added CRUD operations to our sample using  HTTP verbs. Only few changes are required in the section as mentioned below.

Video 3.2: Microsoft did an awesome change with it by making the JSON response in camel case by default. In our sample we added serialize settings in statrtup.cs as

options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

It is no more required.

Video 3.3 :  We returned various status codes from the action methods based on the request.The classes that we used also got renamed as

ASP.NET 5 ASP.NET Core 1.0
HttpUnauthorized Unauthorized
HttpNotFound (and its overloads) NotFound
HttpBadRequest (and its overloads) BadRequest

The above changes has taken place in all the action methods wherever used.

Section 4 
In this section, we added few more features to our sample like sorting, paging etc. Here there is a change in the way we access URL Helper as discussed below.

Video 4.3: We used URL helper for generating the URLs and it was injected via constructor without any other changes as it was by default available which is not the case now.

Now we need to access it via UrlHelperFactory and action context. ActionContext is accessed via ActionContextAccessor, for that we need to register it in startup.cs as

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

and we need to inject the UrlHelperFactory and ActionContextAccessor in constructor to get the URL helper as

  public BooksController(IBookStoreRepository _repository, IUrlHelperFactory urlHelperFactory, IActionContextAccessor actionContextAccessor)
        {
            this.repository = _repository;
            this.urlHelper = urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);
        }

Rest of the code would be same as we got the similar URL helper.

Section 5
In this section we talked about security implementation. In it we have only few changes as below.

Video 5.2 : We created a custom authorization attribute RequireHttpsAttribute which inherited from AuthorizationFilterAttribute where we checked the scheme from the URL. Now RequireHttpsAttribute is itself available under the namespace Microsoft.AspNetCore.Mvc so we can use the same to enforce the SSL in complete application or any specific controller/action.

Video 5.4 : Only few references changes. Refer the table

Section 6 
In this section, we discussed some advanced topics like DI, CORS etc and there are few changes in DI. Let’s see that

Video 6.1:
a) As discussed earlier that now we don’t have AddInstance option for registering the service, same can be achieved via AddSingleton.

b) We discussed that we can also inject services via property using FromServices attribute but it is not available any more as it was creating confusion and issues. Constructor injection is always preferable. From services is available and can be used for Action Injection as

public IEnumerable<Book> Get([FromServices] IBookStoreRepository repository)
{
...
}

These are the key changes that took place specific to Web API and our course. I created again the sample from scratch using the ASP.NET Core 1.0 which can be downloaded from the course.

Thanks a lot for your support and feedback.

Cheers
Brij

How to test email functionality without configuring Smtp Client

Writing code for sending mail is one of the common tasks that we need to work every now and again. Sometimes it is one of the requirements in our application and some time we develop to send alerts to all when application looses its control on production :).

.NET made it very simple to send the mail which normally looks a complicated task. We can easily write 4-5 lines of the code to send the mail. Lets just have a look on a sample code

Continue reading