Tuesday, August 23, 2016

Associating any file with an installed application

Recently I got a requirement to associate a file having custom extension with the installed version of our own application. So, whenever user clicks on that given extension file, it should open up directly in my WPF application along with the data population. So, let’s check out how you can achieve this:

Step 1 - Creating an application: Create a WPF application or you can take any of your existing application. I’m working on WPF application (using MVVM) but the concept remains same for others, you can go with your Windows Forms or Console application also. That’s pretty acceptable. In my application, I'm taking few customer properties and a file path.

Step 2 - Get key for Signing: For signing my assembly I’m using inbuilt feature of Visual Studio. Go to your project properties, navigate to Signing option as shown below:

                                            








If you already have a key then you can browse and associate it else you can always go ahead and create a new key. Please note: You can use any other way to sign your assembly. In order to make this post simple, I’m using the easiest way J
Once the key is created, it will be automatically added to your project with name as <xxx>.pfx

Step 3 - Signing the manifest: Now as your key is ready, next step is to associate it with your deployment. This can be done by updating the ClickOnce manifests section under Signing tab as shown below:











On the above screen check the given checkbox and browse your pfx file. Note: Please verify expiry date of the certificate once it is browsed successfully.

Step 4 - Associating a File: Next step is to associate our custom file extension, for me it is .shw (this .shw file is in JSON format). Similarly you can take any extension that you would like to associate with your WPF application.  Let’s quickly go to Publish option and furnish all the required details as shown in below image:

















Add default icon for your application using Application Files dialog. Once the icon is associated with your application, you will be able to see that in Application Files dialog. By any chance, if you can’t find your icon in list, please follow my previous post for troubleshooting this J

Step 5 - Tweak your application: Now most important step is to update our WPF application, so that it can understand this new extension (.shw).

Update application startup with following code: 
protected override void OnStartup(StartupEventArgs e)
   {      
      if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null
               && AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Length > 0)
            {                

               string fileName = "";
               try
                {  
                   fileName = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
                   Uri uri = new Uri(fileName);
                   fileName = uri.LocalPath;

                   AppShared.SelectedFilepAth = fileName;

                }                

               catch (Exception ex)
                {                   

	  // do exception handling
                }
      }              
       base.OnStartup(e);
    }

Update your ViewModel so that your view can read data as:

public MyViewModelConstructor()
        {                     

             if (!string.IsNullOrEmpty(AppShared.SelectedFilepAth))
             {

                Customer = Newtonsoft.Json.JsonConvert.DeserializeObject<Customer>(System.IO.File.ReadAllText(AppShared.SelectedFilepAth));
                FilePath = AppShared.SelectedFilepAth;
             }            

            else
            {                

                Customer = new Customer() { Name = "Test User", Age = 100 };
            }
        }
 
Step 6 - Final Step: Build your code. Publish it. Install it and wow you are done. After performing all these steps, try double clicking your file, it will automatically pop-up your application with pre-loaded data.
 
It's straight forward. Isn't it?

Ok, let's do something more. Till now we were doing our file association via nice and user friendly GUI. But there is an alternate way available to achieve the same for our command-line lovers in which they have to play with application manifest file directly. Below are the steps to perform the same operation using command line:
  • Open you application manifest. In case, if it is not available please add a new app manifest file to your project and open it into the editor of your choice.
  • Add a new fileAssociation element as a child of Assembly element.
  • Add 4 attributes to this newly added fileAssocitation element – extension, description, progid and defaultIcon. Sample manifest file is given here, In case if you want to associate more file types, then you have to add another fileAssocitation element.
  • Sign application manifest using Mage.exe utility:
mage -Sign <YourApp>.exe.manifest -CertFile <yourCertificate>.pfx

Entire list of Mage command parameters is given over here.
Hope you enjoyed associating your file with multiple ways. Create a file with funny extension, open it and have fun. Happy learning!

Tuesday, August 16, 2016

Error: Icon file is not set to be published...

Today while working on one of the application that was for ClickOnce deployment I faced a small issue which took almost my half an hour. My task was to associate a default icon to my application. So, in order to do this, I went to my project properties and simply set the icon as shown below:
















As you can see in above screenshot, it is showing an error icon which states: 'Icon file is not set to be published with the application, or is not part of the required download group'

Then I build my application and land up with below error message which was more clear:






After hitting my head for many minutes, I thought, let's check out what is this 'download group'.

On surfing net, I got the clue that download group is nothing but a collection of files which are going to be part of our publish activity.
So, I quickly opened Application Files dialog using Project properties >> Publish. The Application Files dialog looks like:















I noticed that my icon file is not listed above. Then I got an idea on what went wrong :)
I immediately changed the to build action to 'Content' and force it to 'Copy Always'. And guess what?
My error is gone :)

After fixing this issue, I realized that it was very silly. As it wasted my many minutes, I thought to add it to my repository, so that it can be useful for all others who got stuck like me :(

Happy troubleshooting !!! 

Sunday, August 14, 2016

Back to blogging

Hey friends, I’m back to my blogging world after a gap of few months. Yes, you are right. I’m alive. Actually I was busy with motherhood J

Last night, I was scared to look at my blog, fearing all the followers have given up on me. Trust me, this is very-very scary feeling. Although it’s been not so long since I become a blogger but a fear of losing followers, who actually take time to read my posts is something which I can’t express. Hope you are reading this.

After a long break, it is bit difficult to get the same momentum. But I’ll try to make it up. So, stay tuned and keep reading.

Happy learning!!!

Tuesday, February 16, 2016

Reading version information from project.json

As of now, many of you are aware about the information stored in project.json file in ASP.NET Core 1.0. My this blog post will tell, how to retrieve the version number from project.json file.


Below is the screenshot of my json file:




















And below is the code to get the version number:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
            // Reading project.json file
            var projConfig = new ConfigurationBuilder().AddJsonFile("project.json").Build();

            //app version number
            var appVersion = projConfig["version"];

            // SQL Server version number
            var sqlServerVersion = projConfig["dependencies:EntityFramework.MicrosoftSqlServer"]; 
}
Hope this post was helpful.
Mothertouch Round Walker (Blue)

Thursday, February 11, 2016

Application State in ASP.NET Core 1.0

Mee Mee Steam Engine
Introduction to Application State
Application state provides a way to store in-memory data, which are smaller in size. It includes both global and user-specific data. Such data can be used across application and can be used by all users. Prior to ASP.NET Core 1.0 also there were Application and Session state options available to store such sort of data.

Ways of managing Application State?
Now question is, which state storage provider is to be used and when? It is influenced by variety of factors:
  • Size of data
  • Format of data
  • Duration to persist data
  • Sensitivity of data, etc.
Based on your answers, Application State can be managed in variety of ways like:
  • HTTPContext
  • Cookies
  • Session
  • Querystring and Post
  • Cache
  • Other options (EF, Azure Table Storage, etc.)
As part of ASP.NET Core 1.0 release, there is change in HTTPContext object. Hence I’ll emphasis on that.

HTTPContext:
Items collection of HTTPContext is used to store data which is required only for that particular request. It means contents are discarded and renewed after every HTTP request. HTTPContext.Items is a simple dictionary collection of type IDictionary<object, object>. HTTPContext.Items is very useful in sharing data between various middleware components. In another words, one middleware component can add data to HTTPContext.Items collection and other middleware component in the same HTTP request pipeline can read it. Ways to get an instance of HTTPContext can be found here.
Why HTTPContext re-introduced?
Main reasons for re-introducing HTTPContext are:
  • ASP.NET Core 1.0 no more uses System.Web assembly. It was done in order to reduce the application footprint by introducing new libraries based on functionality.
  • Huge size of object graph for HttpContext. Earlier this size was approximate 30K, which has now come down to approximate 2K.
Application State Considerations
  • Data is stored in-memory. Hence it is fast as compared to database stored on the server.
  • Application State stores data as Object type, so value has to be converted to appropriate type while reading.
  • Application State data can be access simultaneously by many threads. So, data updates should be done in thread-safe manner.
  • Application State cannot be preserved in Web Farm and Garden scenarios.

Wednesday, February 10, 2016

Consuming Services in ASP.NET Core MVC View

Exclusive Amazon Deals
In continuation to my previous post on injecting services in controller, this time I'm writing on how to inject services directly in MVC View. In order to achieve this, a new keyword @inject is used.
Here I'm not writing entire code again as it can be referred from my previous article.

Let's register the service in ConfigureServices method as:

public void ConfigureServices(IServiceCollection services)
        {
           ...
           ...
           services.AddTransient<IGUIDService,GUIDService>();
        }

Next is to inject service inside a View as:
@inject IGUIDService guidService

Now service is injected and available for use. Let's quickly use it:

@using CustomTagHelper.Services;
@inject IGUIDService guidService

<p>@guidService.GenerateGUID()</p>

Run your application and you will be able to see the required output as:









Hope you enjoyed learning :)

Monday, February 8, 2016

Consuming Services in ASP.NET Core MVC Controller


Exclusive Amazon Deals
Another interesting feature of ASP.NET Core is service consumption using Dependency Injection. I already provided the overview of Dependency Injection in my earlier articles. Moving further, in this article we will see how one can inject and consume services to controller using dependency injection.

In ASP.NET, you can access services at any stage of your HTTP pipeline through dependency injection. By default, it provides Constructor injection, but it can easily be replaced by any other container of your choice. Before moving ahead, one point is very important to understand and that is lifetime of services.

ASP.NET Core allows you to configure four different lifetimes for your services.
  • Transient - Created on every request
  • Scoped - Created once per request
  • Singleton - Created first time when they are requested
  • Instance - Created in ConfigureServices method and behaves like a Singleton

To understand the service consumption in easier way, we will create a sample application going step-by-step. My example service will provide GUID to respective controller. So, let's start quickly. 
Create a new project - Create a new project using ASP.NET Web Application template as shown below:
















Add Service Interface - Create an interface named IGUIDService under Services folder as shown below:

public interface IGUIDService
    {
        string GenerateGUID();
    }

Add Service Implementation - Create a class named GUIDServiceunder Services folder and provide the implementation of IGUIDService interface as shown below:

public class GUIDService : IGUIDService
    {
        public string GenerateGUID()
        {
            return ("Generated GUID is: " + Guid.NewGuid()).ToString();
        }
    }


Add a Controller - Next task is to add a Controller namedGUIDController by right clicking on Controllers folder as shown below:














Add a View - Before adding a View, create a folder named under Views folder. Now add a View by right clicking on GUID folder as shown:

















Update the code inside View as shown below: 

@ViewData["GeneratedGUID"]

Use Service in Controller - Now instantiate the service and set the data for View as shown below:

public class GUIDController : Controller
    {
        private IGUIDService _guidService;

        public GUIDController(IGUIDService guidService)
        {
            _guidService = guidService;
        }
        public IActionResult Index()
        {
            ViewData["GeneratedGUID"] = _guidService.GenerateGUID();
            return View();
        }
    }

Register Service - Last step is to register the service in the ConfigureServices method of Startup class as shown below:


public void ConfigureServices(IServiceCollection services)
        {
           ...
           services.AddMvc();
           services.AddInstance<IGUIDService>(new GUIDService());
        }


Everything is set. Now run your application and you would be able to see GUID on browser as:

Friday, February 5, 2016

Tag Helpers in ASP.NET Core 1.0

Exclusive Amazon Deals
This article is for those who would like to use Tag Helpers over old Razor/HTML helpers. Tag Helpers, another new feature of ASP.NET Core. Let’s quickly have a look at it.

What are Tag Helpers?
As per ASP.NET documentation:
                    "Tag Helpers enable server-side code to participate in creating and rendering HTML elements in Razor files".

Tag Helpers are somewhat similar to HTML Helpers/Razor Helpers introduced in previous version of ASP.NET MVC but those helpers were not that easy to understand for web designers because of inline C# method calls. As web designers are more inclined towards HTML, a simpler and comfortable approach was required. Fortunately, ASP.NET Core 1.0 provided that. Now one need not to use HTML Helpers to build cshtml forms. Means when you had to write this:




Now you can write this:




As you can see above format is very easy to understand as it is purely a HTML syntax.

How Tag Helpers work?

When you create a new ASP.NET web application in Visual Studio, it adds Microsoft.AspNet.Tooling.Razor to the project.json file. This is the package that adds Tag Helper tooling and enables intelliSense in Visual Studio. In order to make our Razor views aware of Tag Helpers, a special file named _ViewImports.cshtml is used. This file is stored in Views folder. By default this file will be there. By any chance if file is not there, then create it and add following line in it:




Pre-defined Tag Helpers

ASP.NET Core 1.0 includes a list of pre-defined Tag Helpers:

Anchor - generates hyperlink
Input - generates input elements
Select – generates dropdownlist
Cache – manages partial page caching
Form – generates form element
Script – processes script tag
Link – processes link element
Label – outputs label element
Option – targets individual options in a list                   
TextArea – processes textarea tag
Environment – controls rendering of content
ValidationMessage – generates validation error
ValidationSummary – provides validation summary message
I’ll try to brief about all above Tag Helpers in coming posts. Now what if existing tags doesn't fulfill our need? In that case, we have to go ahead and invent something else. Should we proceed to create Tag Helper based on our requirement? 
Creating Custom Tag Helpers
As part of this article, we will create a new Tag Helper for appreciating someone. Our tag will be <appreciate>. For example:
<appreciate person-name-for-appreciation="shweta"></appreciate>
 
The server will use appreciate Tag Helper to convert that markup into following:
<label>Great Work, Shweta</label>
In order to create this new Tag Helper, we have to create a new class named AppreciateTagHelper and inherit TagHelper in that. Make sure to add the reference of Microsoft.AspNet.Razor.TagHelpers in this new class. Sample code is as:










Note - it is not mandatory to suffix TagHelper in class name. It is just a good practice.
To make this Tag Helper available to all Razor views, we have to add addTagHelper directive to _ViewImports.cshtml file as:
@addTagHelper "*,CustomTagHelper"
 
Above statement signifies that all the custom Tag Helpers (denoted by wild card character) will be available from assembly named CustomTagHelper. If interested, instead of * you can go with fully qualified names also.
Next step is to update our views. Let’s go ahead and append below line in view:
<appreciate person-name-for-appreciation="shweta"></appreciate>
Good thing is, you will get intelliSense for your custom Tag Helper also J
Run your application and you will find that appreciate Tag Helper is replaced with your label markup with output as:
 






Hope you enjoyed learning this new feature.