Branislav Abadjimarinov's technical blog

Branislav Abadjimarinov's technical blog - Browsing C#

  1. WeakReference and .net memory management

    WeakReference class is relatively unknown to the .net community. A weak reference in general is a reference to an object that doesn't stop the garbage collector from collecting an object. In its nature it is an agile reference to object - it can be useful to keep large objects in memory only if the application can afford it. If the application is pressed for memory it can collect the object which is weakly referenced.

    The WeakReference class is drop dead simple to use. When you want to crate a weak reference to an object you just create a WeakReference and pass the object as a constructor parameter like this:

    WeakReference weakRef = new WeakReference(referencedObjectInstance);

    You can use the IsAlive Boolean property to check if an object is collected. And you can get the object instance using the Target property. It is good practice to use those two in combination to check first if the object is still available and than access it.

    Another use of the WeakReference class is to check if objects are collected as expected. Let's say I have a simple Student class:

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

    And I want to create an array of students. The array will not be garbage collected if an object from it is still alive. In the case where only one object form an array is alive it will prevent all the others array objects from being garbage collected. Creating the WeakReference will allow us to track if the objects are really collected.

        class Program
        {
            static void Main()
            {
                Student[] firstGrade = new Student[2];
                
                firstGrade[0] = new Student { Name = "Usefull Bob"};
                firstGrade[1] = new Student { Name = "Average Joe"};

                WeakReference weakRef = new WeakReference(firstGrade[1]);

                GC.Collect();

                Console.WriteLine(weakRef.IsAlive ? "Alive!" : "Dead");

                // Uncomment to prevent all objects in the array from garbadge collection
                // Console.WriteLine(firstGrade[0].Name);
            }
        }

    There is also some differences if our application is running in Debug or Release mode. When the application is in Debug mode the garbage collector behavior is pretty much unpredictable as some objects are kept alive intentionally to support better debugging experience. If you want to get a real picture of the memory management in your app you have to do your profiling in Release mode. WeakReference class can also be used in Unit tests to verify if an object is garbage collected as expected.
     

    Posted by Branislav Abadjimarinov on May 20 at 1:50 AM

  2. AJAX the easy way in ASP.NET Web Forms using genric handlers

    In this article we'll see a quick and elegant ajax call solution based on generic handlers in asp.net and jQuery. The goal is to populate a street list in a dropdown with ajax call based on a selected postal code in a dropdown. The usual way to do this in ASP.NET Web Forms will be to use the AjaxToolkit, MS Ajax library and web service. The problem with this approach is that it is coplex and prone to errors.
    To accomplish the task we will create a generic handler(.ashx file) in our asp.net project. The generic handler is a lightweight approach to deliver content to the user. It doesn't have the heavy page lifecycle. By default the generic handler has only one method - ProcessRequest and one readonly property - IsReusable. The handler inherits directly from IHttpHandler. The IsReusable property defines if one handler object can be pooled and shared on different requests. If you set it to true be sure that the ProcessRequest method is thread safe. Than we will implement the ProcessRequest methods as follows:

    using System;
    using System.Web;
    using System.Collections.Generic;
    using System.Runtime.Serialization.Json;

    public class GetStreetsByPostCode : IHttpHandler
    {
      public void ProcessRequest(HttpContext context)
      {
        List<string> streets = new List<string>();
        int postCode;
        string postCodeParameter = context.Request.QueryString["code"];
       
        if (!String.IsNullOrEmpty(postCodeParameter) &&
            int.TryParse(postCodeParameter, out postCode))
        {
          AddressService service = new AddressService();
          streets = service.GetAvailableStreetsByPostCode(postCode);
        }
       
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<string>));
        serializer.WriteObject(context.Response.OutputStream, streets);

        context.Response.ContentType = "application/json";
      }

      public bool IsReusable
      {
        get
        {
          return false;
        }
      }
    }

    As you see we are using DataContractJsonSerializer object to serialize data in JSON format. The JSON format is native data representation format for the JavaScript language. Also we set the content type http header to "application/json" which is the JSON document mime type. The AddressService is just a class used to get data. This is all we need from server side. For client side we will use jQuery library. Based on a selected post code we will populate a dropdown with available streets for this post code. The script bellow will make an ajax request to our generic handler, parse the JSON data and fill in the dropdown values.

    $(function() {
      $("#DropDownPost").change(function() {
        LoadAddress();
      });
    });
    function LoadAddress() {
      var selectedPostCode = $("#DropDownPostCode option:selected").text();
      if (selectedPostCode && selectedPostCode != "0") {
        $.post("/GetStreetsByPostCode.ashx?code=" + selectedPostCode,
             function(result) {
                 var streets = eval("(" + result + ")");
                 ClearStreetsDropDown();
                 PopulateStreetsDropDown(streets);});
      } else {
        ClearStreetsDropDown();
      }
    }
    function ClearStreetsDropDown() {
      $('#DropDownStreet option').each(function(i, option) { $(option).remove(); });
    }
    function PopulateStreetsDropDown(streets) {
        $('#DropDownStreet').append(
            $('<option selected="selected"></option>').val("").html("")
          );
        $.each(streets, function(val, text) {
          $('#DropDownStreet').append(
            $('<option></option>').val(text).html(text)
          );
        });
    }

    Posted by Branislav Abadjimarinov on March 26 at 12:15 AM

  3. Renew User in the same Request in asp.net while using forms authentication with cookies

    In ASP.NET forms authentication the usual authentication flow goes like this:

    • a user submits his credentials;
    • they are  validated against database, web.config or other data source;
    • an authentication cookie is issued and added to the current response (which is not sent yet);
    • the cookie is sent along with the response;
    • on the next request from that user the cookie is decrypted and the current Security Principal is initialised with the data;

    While this is good for most cases it has one flow - immediately after the authentication cookie is issued the current Security Principal for the request is outdated. You can check this with the following code:

    if(Membership.ValidateUser(userName, password))
    {
        FormsAuthentication.SetAuthCookie(userName, false);
        bool isAuthenticated = Request.IsAuthenticated; // isAuthenticated is false
    }

    This outcome is logical because of the authentication flow but some times it is confusing and can cause problems. A possible solution is to renew the information for the Current Security Principal for the request. This can be done with the following code:
    public void RenewCurrentUser()
    {
      System.Web.HttpCookie authCookie =
        System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
      if (authCookie != null)
      {
        FormsAuthenticationTicket authTicket = null;
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        if (authTicket != null && !authTicket.Expired)
        {
          FormsAuthenticationTicket newAuthTicket = authTicket;

          if (FormsAuthentication.SlidingExpiration)
          {
            newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket);
          }
          string userData = newAuthTicket.UserData;
          string[] roles = userData.Split(',');

          System.Web.HttpContext.Current.User =
            new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles);
        }
      }
    }

    You can check if the solution works like this:

    if(Membership.ValidateUser(userName, password))
    {
        FormsAuthentication.SetAuthCookie(userName, false);
        bool isAuthenticated = Request.IsAuthenticated; // isAuthenticated is false
        RenewCurrentUser();
        isAuthenticated = Request.IsAuthenticated; // isAuthenticated is true
    }
     

    Posted by Branislav Abadjimarinov on January 24 at 3:52 AM

  4. Course Programming .NET and WPF

    This semester at FMI, Sofia University, is starting a new course dedicated to programming  .NET and using the latest Microsoft  technologies. The course is called "Programming .NET and WPF".  You can check out the program of the course on the official site of FMI. The course also has an online home - www.dotnet.graduate-bg.com , where you can check the schedule of the lectures, download the presentations or ask questions in the forum . The course will present the newest and most powerful presentation technology from Microsoft - WPF (Windows Presentation Foundation). I'll do some basic lectures on Attributes and Strings and also some more in depth presentation on LINQ and multi-threaded programming techniques. This course continues the fine tradition not only to show the latest technologies but also to give students a chance to play and develop their own projects as part of the curriculum.

    Posted by Branislav Abadjimarinov on October 28 at 2:53 PM

  5. How to render asp.net control to string

    Every control in ASP.NET inherits from System.Web.UI.Control and have the RenderControl method. When you want to get the html output of the control at any point of the page execution lifecycle you can use the following method.

    public string RenderControl(Control ctrl)
    {
        StringBuilder sb = new StringBuilder();
        StringWriter tw = new StringWriter(sb);
        HtmlTextWriter hw = new HtmlTextWriter(tw);

        ctrl.RenderControl(hw);
        return sb.ToString();
    }

    At this point ASP.NET MVC does not have full support for asp.net controls. Using this trick you can render control's html directly on the view using a html helper. While this is good for read-only controls it will not work with controls that require event handling because in ASP.NET MVC by default you are missing  the page lifecycle.

    Posted by Branislav Abadjimarinov on October 28 at 9:10 AM

© Copyright 2017 Powered by AtomSite 1.3.0.0