Salı, 07 Mart 2017 / Published in Uncategorized

IntroductionWeb applications work on HTTP protocol and HTTP is a stateless protocol. Every HTTP request is treated as an independent request. The Server does not have knowledge about the variable values, which are being used in the previous request.

 

Session is a feature in ASP.NET Core that enables us to save/store the user data. Session stores the data in the dictionary on the Server and SessionId is used as a key. The SessionId is stored on the client at cookie. The SessionId cookie is sent with every request. The SessionId cookie is per browser and it cannot be shared between the browsers. There is no timeout specified for SessionId cookie and they are deleted when the Browser session ends.At the Server end, session is retained for a limited time. The default session timeout at the Server is 20 minutes but it is configurable.Sessions are of two types, namely In-Proc or In-memory and Out-Proc or Distributed session. If our session is in-memory and our application is hosted on Web-Farm environment, we need to use sticky sessions to tie each session to a specific Server whereas an Out-Proc session does not require sticky sessions and they are the most preferred way to use sessions in our application.

 

Configuring sessionMicrosoft.AspNetCore.Session package provides middleware to manage the sessions in ASP.NET Core. To use session in our Application, we need to add this package as a dependency in project.json file.

 

Project.json

  1. {  
  2.   "version""1.0.0-*",  
  3.   "buildOptions": {  
  4.     "debugType""portable",  
  5.     "emitEntryPoint"true  
  6.   },  
  7.   "dependencies": {},  
  8.   "frameworks": {  
  9.     "netcoreapp1.0": {  
  10.       "dependencies": {  
  11.         "Microsoft.NETCore.App": {  
  12.           "type""platform",  
  13.           "version""1.0.1"  
  14.         },  
  15.         "Microsoft.AspNetCore.Mvc""1.0.1",  
  16.         "Microsoft.AspNetCore.Server.Kestrel""1.0.1",  
  17.         "Microsoft.AspNetCore.Routing""1.0.1",  
  18.         "Microsoft.AspNetCore.Session" : "1.0.1"  
  19.       },  
  20.       "imports""dnxcore50"  
  21.     }  
  22.   }  
  23. }  

The next step is to configure session in Startup class. We need to call "AddSession" method in ConfigureServices method of startup class. The "AddSession" method has one overload method, which accepts various session options such as Idle Timeout, Cookie Name and Cookie Domain etc. If we do not pass the session options, the system will take the default options. Now, we need to call "UseSession" method in Configure method of startup class. This method enables the session for the Application.

 

Startup.cs

  1. using System;  
  2. using Microsoft.AspNetCore.Builder;  
  3. using Microsoft.AspNetCore.Hosting;  
  4. using Microsoft.AspNetCore.Http;  
  5. using Microsoft.Extensions.DependencyInjection;  
  6.   
  7. namespace WebApplication {  
  8.     public class Startup {  
  9.         public void Configure(IApplicationBuilder app)  
  10.         {  
  11.             app.UseSession();  
  12.             app.UseMvc();  
  13.             app.Run(context => {  
  14.                 return context.Response.WriteAsync("Hello Readers!");  
  15.             });  
  16.         }  
  17.   
  18.         public void ConfigureServices(IServiceCollection services)  
  19.         {  
  20.             services.AddMvc();  
  21.             services.AddSession(options => {   
  22.                 options.IdleTimeout = TimeSpan.FromMinutes(30);   
  23.             });  
  24.         }       
  25.     }  
  26. }  

It is important to call "UseSession" method before the "UseMvc" method in Configure method of startup class. If we call “UseMvc” method before “UseSession” method, the system will throw an exception.

 

 

How to access the sessionWe can use session from HttpContext, once it is installed and configured. To use session in controller class, we need to reference "Microsoft.AspNet.Http" in controller. There are three methods that enables us to set the session value, which are Set, SetInt32 and SetString. The "Set" method accepts byte array as an argument. The SetInt32 and SetString method are the extension methods of Set and they internally cast byte array to int and string respectively. Same as there are three methods that  are used to retrieve the value from the session: Get, GetInt32 and GetString. The Get method returns byte of arrays.

 

The main reason behind storing bytes array is to make sure that session values are serializable for the storage on remote Servers. Apart from int and string, we need to serialize to byte array to store it in session.

 

ExampleIn the example given below, I have set my name into session in first request and retrieved the session value in another request.

  1. using Microsoft.AspNetCore.Http;  
  2. using Microsoft.AspNetCore.Mvc;  
  3.   
  4. public class HomeController : Controller  
  5. {  
  6.   
  7.     [Route("home/index")]  
  8.     public IActionResult Index()  
  9.     {  
  10.         HttpContext.Session.se.SetString("name","Jignesh Trivedi");  
  11.         return View();  
  12.     }  
  13.     [Route("home/GetSessionData")]  
  14.     public IActionResult GetSessionData()  
  15.     {  
  16.         ViewBag.data = HttpContext.Session.GetString("name");;  
  17.         return View();  
  18.     }  
  19. }  

Output

 

Custom Session Extension methodsAs discussed earlier, there are two extension methods to get the data from session and set the data to session are available, namely GetInt32 and GetString, SetInt32 and SetString. Similarly, we can add our custom extension methods to get and set the value in session.In the example given below, I have created an extension method to set double value to session and get double value from session.

  1. using System;  
  2. using Microsoft.AspNetCore.Http;  
  3. public static class SessionExtensions  
  4. {  
  5.     public static double? GetDouble(this ISession session, string key)  
  6.     {  
  7.         var data = session.Get(key);  
  8.         if (data == null)  
  9.         {  
  10.             return null;  
  11.         }  
  12.         return BitConverter.ToDouble(data, 0);  
  13.     }   
  14.   
  15.     public static void SetDouble(this ISession session, string key, double value)  
  16.     {  
  17.         session.Set(key, BitConverter.GetBytes(value));  
  18.     }  
  19. }  

Usage of the extension method

  1. using Microsoft.AspNetCore.Http;  
  2. using Microsoft.AspNetCore.Mvc;  
  3. public class HomeController : Controller  
  4. {  
  5.   
  6.     [Route("home/index")]  
  7.     public IActionResult Index()  
  8.     {  
  9.         HttpContext.Session.SetString("name","Jignesh Trivedi");  
  10.         HttpContext.Session.SetDouble("Percentage",75.56);  
  11.         return View();  
  12.     }  
  13.     [Route("home/GetSessionData")]  
  14.     public IActionResult GetSessionData()  
  15.     {  
  16.         ViewBag.data = HttpContext.Session.GetString("name");  
  17.         ViewBag.Percent = HttpContext.Session.GetDouble("Percentage");  
  18.         return View();  
  19.     }  
  20. }  

Output

 

Store Complex Data in to SessionAs we are aware, session is able to store only byte of an array. Compared to the previous version, ASP.NET Core does not perform any operation such as serialization/ de-serialization on the values stored in session. Here, I am converting the complex object into JSON and store it as a string. Later, I am retrieving it as a string and de-serialize to original object.Thus, I have written the extension method for set and get complex object to session.

  1. using System;  
  2. using Microsoft.AspNetCore.Http;  
  3. using Newtonsoft.Json;  
  4.   
  5. public static class SessionExtensions  
  6. {  
  7.     public static T GetComplexData<T>(this ISession session, string key)  
  8.     {  
  9.         var data = session.GetString(key);  
  10.         if (data == null)  
  11.         {  
  12.             return default(T);  
  13.         }  
  14.         return JsonConvert.DeserializeObject<T>(data);  
  15.     }   
  16.   
  17.     public static void SetComplexData(this ISession session, string key, object value)  
  18.     {  
  19.         session.SetString(key, JsonConvert.SerializeObject(value));  
  20.     }  
  21. }  

Usage of the extension methodIn the following example, I have created one public class and within controller action method, created the instance of the class, stored some data and sent it for storing in session. Similarly, I created one action method to retrieve the complex data from session.

  1. public class User   
  2. {  
  3.     public string Name { getset; }  
  4.     public double Percentage { getset; }  
  5. }  

Action method

  1. [Route("home/SetComplexData")]  
  2. public IActionResult SetComplexData()  
  3. {  
  4.     User user = new User();  
  5.     user.Name = "Jignesh Trivedi";  
  6.     user.Percentage = 75.45;             
  7.       
  8.     HttpContext.Session.SetComplexData("UserData", user);  
  9.     return View("index");  
  10. }  
  11. [Route("home/GetComplexData")]  
  12. public IActionResult GetComplexData()  
  13. {  
  14.     ViewBag.data = HttpContext.Session.GetComplexData<User>("UserData");  
  15.     return View();  
  16. }  

SummaryThe main advantages of ASP.NET Core is that it supports modularity. It means that we need to add the module, as we wish to use it in our application. The usage of session is slightly different than the classic ASP.NET Application. This article helps us to understand how to install, configure and use session with ASP.NET Core.

Salı, 07 Mart 2017 / Published in Uncategorized

I have developed an easy way to copy/paste the data between WPF Applications and Excel. This code is compatible for the controls inherited from System.Windows.Controls.ItemsControls. These are the controls with the ItemsSource property. Controls of this type are DataGrid, ListBox, ListView etc.

It’s OpenSource and its code in GitHub.

It’s very easy to use  and we will install the utility by NuGet and we will set up any properties of our control in the XAML code.

This is how it works

https://www.youtube.com/watch?v=Vym1OiF9z3E&feature=youtu.be

Prerequisites

The utility has been tested in WPF Applications and we don’t know, if it runs in (Silverlight, WP or WUP) apps.

It is necessary to have 4.5.2 NET Framework version or later.

Installation

We will install it from NuGet.

SetUp

After installation has been completed, we will setup the WPF Window and we add the next import in XAML,

  1. xmlns:ml="clr-namespace:MoralesLarios.Utilities.Excel;assembly=MoralesLarios.Utilities"   

We will add the properties given below in the ItemsControl in XAML. 

  1. <DataGrid x:Name="dataGrid" ml:ExcelActions.EnabledCopyExcel="True" <!—- enabled copy/copiall excel –> ml:ExcelActions.EnabledPasteExcel="True"  
  2.     <!—- enabled paste excel –>/>   

This simple code enables the copy/paste data between DataGrid control and Excel.

https://www.youtube.com/watch?v=79Q7g81klz8&feature=youtu.be

In terms of its simple form, we will make the actions with the keyboard.

  • Ctrol + A – CopyAll – Copy all DataGrid rows
  • Ctrol + C – Copy Selected – Copy DataGrid selected rows.
  • Ctrol + P – Paste – Paste data in DataGrid.

Other AttachProperties

We can add functionality with the next AttachProperties. 

  1. ml: ExcelActions.EnabledCopyExcel = "True"  
  2. ml: ExcelActions.EnabledPasteExcel = "True"  
  3. ml: ExcelActions.ContainsHeader = "False"  
  4. ml: ExcelActions.CreateContextMenu = "True"  
  5. ml: ExcelActions.CancelWithErrors = "False"  
  6. ml: ExcelActions.PaintFlash = "True"  
  7. ml: ExcelActions.ColorFlash = "Yellow"  
  8. ml: ExcelActions.ShowErrorMessages = "True"   

CreateContextMenu

Enabled or disabled shows the context menu in the ItemsControl.

  1. ml:ExcelActions.CreateContextMenu="True"   

Its default value is True.

ContainsHeader

Enabled or disabled copy controls headers.

  1. ml:ExcelActions.ContainsHeader="False"   

Its default value is True.

PaintFlash

Show or hide the color flash mark in the control that occurs when we copy or paste in the control.

  1. ml:ExcelActions.PaintFlash="True"   

Its default value is True.

https://www.youtube.com/watch?v=nN77KFOriso&feature=youtu.be

ColorFlash

Setup the color of flash for the  copy paste action (it is only visible if the property PaintFlash is true).

  1. ml:ExcelActions.ColorFlash="Yellow"   

Bruhes.Gray is its default value.

ShowErrorMessages

This property shows an error message, if an errors occurs, for example, if the data copied is not compatibile with the datasource of control.

  1. ml:ExcelActions.ShowErrorMessages="True"   

Its default value is True.

https://www.youtube.com/watch?v=Oyk7uTvmMeM&feature=youtu.be

CancelWithErrors

When we copy many rows from Excel, if any row is not correct and if an error occurs, this property specifies, when we paste the correct rows or don’t paste any row.

True – Paste the correct rows

False – Don’t paste anything.

Its default value is True.

Recommendations

It is necessary that the ItemsSource property of ItemsControl is an ObservableCollection type, because this type refreshes the items correctly and informs the removal and addition of changes.

Limitations

In this version, in the paste action, it only inserts the data and doesn’t update the rows or paste incomplete types.

Salı, 07 Mart 2017 / Published in Uncategorized

The default MVC 5 setup gives you a horrendous menu to work with and I probably could have made it look half way decent but I remembered the old SiteMapProvider I had used many moons ago and wondered if there was anything like it available today. Turns out there is and it’s available at https://github.com/maartenba/MvcSiteMapProvider. You can also do a package install…

Install-Package MvcSiteMapProvider.MVCx

…where x is the MVC version you are running.

Ok, so you got it configured and it looks pretty good but highlighting is a real PITA, I Googled for quite a while and the cleanest solution required is that you adorn one of the menu items with an ‘selected‘ class attribute. Well, since you can’t get to the element to add the said attribute, what can we do?

In the Mvc.sitemap file, the only thing that you are really allowed to set is the description field and when set, it overwrites the title field with what you entered in the description. So I got to thinking if I could get the current page and check it against the list of menu items and when I got a match, just set the menu items class to highlight the item.

So, given a very basic sitemap with just a few items:

<mvcSiteMapNode title="Home" controller="Home"
action="Index" description="selected">
  <mvcSiteMapNode title="Pricing"
  controller="Pricing" action="Index" />
  <mvcSiteMapNode title="Contact"
  controller="Home" action="Contact"/>
  <mvcSiteMapNode title="Testimonials"
  controller="Testimonials" action="Index"/>
  <mvcSiteMapNode title="About"
  controller="Home" action="About"/>
  <mvcSiteMapNode title="Admin"
  controller="Admin" action="Index" roles="Admin" />
</mvcSiteMapNode>

As you can see, I set the Home menu item to selected and as long as it is unique, this scheme will work.

Now in your _Layout.cshtml file, add the JavaScript to do the actual work:

    window.onload = function () {
        setPage();
    }
 
    function setPage() {
        hrefString = document.location.href ? document.location.href : document.location;
 
        if (document.getElementById("menu") != null)
            setActiveMenu(document.getElementById("menu").getElementsByTagName("a"), 
                             extractPageName(hrefString));
    }
 
    function extractPageName(hrefString)
    {
        var arr = hrefString.split('/');
        return  arr[arr.length-1].toLowerCase();
    }
 
    function setActiveMenu(arr, crtPage)
    {
        for (var i=0; i 

Then in your styles page, set the current class to whatever highlighting you desire, mine looks like this:

.current{
    color: #eab34f !important;
}

I got the code above from a site, don’t remember where but I had to modify it to key on the title field and the parsing needed some work, but a lot of it came from him. Sorry dude, don’t remember!

Salı, 07 Mart 2017 / Published in Uncategorized

The default MVC 5 setup gives you a horrendous menu to work with and I probably could have made it look half way decent but I remembered the old SiteMapProvider I had used many moons ago and wondered if there was anything like it available today. Turns out there is and it’s available at https://github.com/maartenba/MvcSiteMapProvider. You can also do a package install…

Install-Package MvcSiteMapProvider.MVCx

…where x is the MVC version you are running.

Ok, so you got it configured and it looks pretty good but highlighting is a real PITA, I Googled for quite a while and the cleanest solution required is that you adorn one of the menu items with an ‘selected‘ class attribute. Well, since you can’t get to the element to add the said attribute, what can we do?

In the Mvc.sitemap file, the only thing that you are really allowed to set is the description field and when set, it overwrites the title field with what you entered in the description. So I got to thinking if I could get the current page and check it against the list of menu items and when I got a match, just set the menu items class to highlight the item.

So, given a very basic sitemap with just a few items:

<mvcSiteMapNode title="Home" controller="Home"
action="Index" description="selected">
  <mvcSiteMapNode title="Pricing"
  controller="Pricing" action="Index" />
  <mvcSiteMapNode title="Contact"
  controller="Home" action="Contact"/>
  <mvcSiteMapNode title="Testimonials"
  controller="Testimonials" action="Index"/>
  <mvcSiteMapNode title="About"
  controller="Home" action="About"/>
  <mvcSiteMapNode title="Admin"
  controller="Admin" action="Index" roles="Admin" />
</mvcSiteMapNode>

As you can see, I set the Home menu item to selected and as long as it is unique, this scheme will work.

Now in your _Layout.cshtml file, add the JavaScript to do the actual work:

    window.onload = function () {
        setPage();
    }
 
    function setPage() {
        hrefString = document.location.href ? document.location.href : document.location;
 
        if (document.getElementById("menu") != null)
            setActiveMenu(document.getElementById("menu").getElementsByTagName("a"), 
                             extractPageName(hrefString));
    }
 
    function extractPageName(hrefString)
    {
        var arr = hrefString.split('/');
        return  arr[arr.length-1].toLowerCase();
    }
 
    function setActiveMenu(arr, crtPage)
    {
        for (var i=0; i 

Then in your styles page, set the current class to whatever highlighting you desire, mine looks like this:

.current{
    color: #eab34f !important;
}

I got the code above from a site, don’t remember where but I had to modify it to key on the title field and the parsing needed some work, but a lot of it came from him. Sorry dude, don’t remember!

Salı, 07 Mart 2017 / Published in Uncategorized

In my last blog post, entitled Caching for Non-Web Applications – Part 1, I introduced you to the MemoryCache class. This class allows you to create a cache for any type of application just like in ASP.NET applications. The great thing about the MemoryCache class is that there is no reliance on the System.Web namespace. This means you are free to use the MemoryCache class in any type of application such as Windows Forms, WPF and Windows Services. The last blog post showed you how to add and retrieve data from the cache. This blog post expands on the last one and shows you additional methods you can take advantage of to work with cache data.

Add or Get Existing

The AddOrGetExisting method has the same signature as the Add method. However, instead of returning a true or false value, it will either return a null if the key/value pair was added to the cache, or return the object if the key value is found already in the cache.

object ret;
ret = MemoryCache.Default.AddOrGetExisting("Key2", 
         "Value 2", DateTimeOffset.Now.AddSeconds(5));
if (ret == null) {
	MessageBox.Show("Key did NOT exist");
}
else {
	MessageBox.Show("The Key did already exist");
}

AddOrGetExisting Using CachePolicy

Just like you are able to add a new item to the cache using the CachePolicy using the Add method, you can do the same with the AddOrGetExisting method. The code below will add a new cache item with a sliding expiration of 5 seconds.

object ret;
CacheItemPolicy pol = new CacheItemPolicy();
pol.SlidingExpiration = new TimeSpan(0, 0, 5);
ret = MemoryCache.Default.AddOrGetExisting("Key2", 
                   "Value 2", pol);
if (ret == null) {
	MessageBox.Show("Key did NOT exist");
}
else {
	MessageBox.Show("The Key did already exist");
}

Set Method

The Set method adds an entry into the cache if the specified key value does not exist. However, if the key value does exist, it will update the value for that key in the cache. I prefer to use this method over the Add or AddOrGetExisting as I typically just want to either add, or update, and not worry about whether I have created the value previously or not. This method does not return any value.

MemoryCache.Default.Set("Key3", "Value 3", 
     DateTimeOffset.Now.AddSeconds(5));

You can use a CacheItemPolicy to set a sliding expiration on the item to cache.

CacheItemPolicy pol = new CacheItemPolicy();
pol.SlidingExpiration = new TimeSpan(0, 0, 5);
MemoryCache.Default.Set("Key3", "Value 3", pol);

Notify Before Removal from Cache

Just before an item is to be removed from the cache because it is expiring, you may create a method to respond to this event. Write the following method to accept a CacheEntryUpdateArguments object. Within this method body, you can write whatever code you want. In the sample below, I am just writing out the Key and the reason for the removal.

private void UpdateHandler(CacheEntryUpdateArguments e) {
	Console.WriteLine(e.Key);
	Console.WriteLine(e.RemovedReason.ToString());
}

Once you have this method written, you assign that method to the UpdateCallback property of a CacheItemPolicy object. The code snippet below shows you how you assign this method to the UpdateCallback property.

CacheItemPolicy pol = new CacheItemPolicy();
pol.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(3);
pol.UpdateCallback = UpdateHandler;
MemoryCache.Default.Set(THE_KEY, "Update 3", pol);

If you run the above code and wait a few seconds, you will see a couple of messages printed in the Output window.

Within the UpdateHandler method, you also have the option to change the value in the cache and place it back into the cache. You do this by assigning a new CacheItem object with the same key and a value to the e.UpdatedCacheItem property. You must also set the e.UpdatedCacheItemPolicy property to a new CacheItemPolicy object. When this method ends, the item is not removed and is updated within the cache. The code to do this is shown below:

private void UpdateHandler(CacheEntryUpdateArguments e) {
	Console.WriteLine(e.Key);
	Console.WriteLine(e.RemovedReason.ToString());
	e.UpdatedCacheItem = new CacheItem(e.Key, "My New Value");
	CacheItemPolicy pol = new CacheItemPolicy();
	pol.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10);
	pol.UpdateCallback = UpdateHandler;
	e.UpdatedCacheItemPolicy = pol;
}

Notify After Removal from Cache

If you do not care to update an item in the cache, you may just respond to the RemovedCallback event. The design pattern is similar to what you just wrote in the previous example. First, create a method that accepts a CacheEntryRemovedArguments object. The only two properties in that object you care about are the e.RemovedReason and the e.CacheItem. The e.CacheItem object contains the item that was just removed from the cache.

private void RemovedHandler(CacheEntryRemovedArguments e) {
  Console.WriteLine(e.RemovedReason.ToString());
  Console.WriteLine("Removed Handler: " + e.CacheItem.Key);
}

With the RemovedHandler method created, you may now set the RemovedCallback property of a CacheItemPolicy object. You then use that CacheItemPolicy object to add a new item into the MemoryCache object.

CacheItemPolicy pol = new CacheItemPolicy();
pol.SlidingExpiration = new TimeSpan(0, 0, 3);
pol.RemovedCallback = RemovedHandler;
MemoryCache.Default.Set("Key3", "Remove 3", pol);

If you run the above code, then either let the value expire, or explicitly remove the item from cache, the RemovedHandler method is called.

Summary

In this blog post, you learned to call the AddOrGetExisting method. This method is different from the Add method as it either adds an item to the cache, or retrieves one if the key already exists. You also learned to use the Set method to either add a new item to the cache, or update an item in the cache if it already exists. Providing a couple of callback functions to the CacheItemPolicy lets you respond when an item is about to be deleted from the cache, or after it has already been deleted.

Sample Code

You can download the code for this sample at www.pdsa.com/downloads. Choose the category “PDSA Blogs”, then locate the sample Caching for Non-Web Applications.

TOP