Monthly Archives: February 2014

Example of binary DataContract serialization

By   February 28, 2014
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

namespace ConsoleApplication13
{
    public class MyClass
    {
        public int MyProperty { get; set; }

        public string MyProperty2 { get; set; }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            // create an object
            var data = new MyClass()
            {
                MyProperty = 5,
                MyProperty2 = "abc"
            };

            // create serailizer
            var serializer = new DataContractSerializer(typeof(MyClass));

            // serialization
            string path = @"C:\Temp\test.bin";
            using (var fs = File.OpenWrite(path))
            using (var writer = XmlDictionaryWriter.CreateBinaryWriter(fs))
            {
                serializer.WriteObject(writer, data);
            }

            // deserialization
            MyClass data2;
            using (var fs = File.OpenRead(path))
            using (var reader = XmlDictionaryReader.CreateBinaryReader(fs, XmlDictionaryReaderQuotas.Max))
            {
                data2 = (MyClass)serializer.ReadObject(reader);
            }
        }
    }
}

Ensure initialization of IIS hosted web application for both HTTP and non-HTTP request

By   February 21, 2014

Web application developper usually put initialization codes in Global.Application_Start method, which is called when the web application receives the first HTTP request.

But if the application contains a WCF service who expose an non-HTTP endpoint (ex: net.tcp), Application_Start may not be called before a non-HTTP request is processed.

How to ensure that an application is initialized correctly before processing any HTTP or non-HTTP request? Here is a solution:

  1. Create a static class who manage application initialization/finilization
    
    using System;
    
    namespace MyWebApplication
    {
        public static class AppManager
        {
            private static object _locker = new object();
            private static bool _isInitialized = false;
            private static bool _isFinalized = false;
    
            public static void Initialize()
            {
                // Ensure that initialization is executed only once
                lock (_locker)
                {
                    if (_isInitialized)
                        return;
                    _isInitialized = true;
                }
    
                // Put initialization code here...
            }
    
            public static void Finalize()
            {
                lock (_locker)
                {
                    if (!_isInitialized || _isFinalized)
                        return;
                    _isFinalized = true;
                }
    
                // Put finalization codes here...
            }
        }
    }
    
    
  2. Call Initialize() and Finalize() in Global.asax.cs
    
    using System;
    
    namespace MyWebApplication
    {
        public class Global : System.Web.HttpApplication
        {
            protected void Application_Start(object sender, EventArgs e)
            {
                AppManager.Initialize();
            }
    
            protected void Application_End(object sender, EventArgs e)
            {
                AppManager.Finalize();
            }
        }
    }
    
    
  3. Create a custom service host factory who creates WCF service host with “Opened” and “Closed” events.
    
    using System;
    using System.ServiceModel.Activation;
    
    namespace MyWebApplication
    {
        public class MyServiceHostFactory : ServiceHostFactory
        {
            protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
            {
                var host = base.CreateServiceHost(serviceType, baseAddresses);
                host.Opened += host_Opened;
                host.Closed += host_Closed;
                return host;
            }
    
            private void host_Opened(object sender, EventArgs e)
            {
                AppManager.Initialize();
            }
    
            private void host_Closed(object sender, EventArgs e)
            {
                AppManager.Finalize();
            }
        }
    }
    
    
  4. Modify the markup of *.svc file by specifying the custom factory
    
    <%@ ServiceHost Language="C#" Debug="true" Service="MyWebApplication.Service" CodeBehind="Service.svc.cs" 
        Factory="MyWebApplication.MyServiceHostFactory" %>