Visual Studio and Package Management

nuget logo

All of you have used the latest and greatest open source software in your .net based applications. And you already know that it is hard to figure out the best choice, get it, set it up, run it and update it.

Recently I came across the Visual Studio 2010 extension called NuGet (formerly NuPack) which is a package management for the projects. NuGet is a free, open source developer focused package management system for the .NET platform intent on simplifying the process of incorporating third party libraries into a .NET application during development.

Let’s take ELMAH as an example. It’s a fine error logging utility which has no dependencies on other libraries, but is still a challenge to integrate into a project. These are the steps it takes:

  1. Find ELMAH
  2. Download the correct zip package.
  3. “Unblock” the package.
  4. Verify its hash against the one provided by the hosting environment.
  5. Unzip the package contents into a specific location in the solution.
  6. Add an assembly reference to the assembly.
  7. Update web.config with the correct settings which a developer needs to search for.

NuGet automates all these common and tedious tasks for a package as well as its dependencies. It removes nearly all of the challenges of incorporating a third party open source library into a project’s source tree. This will help developers to reduce such exercise for downloading, installing and configuring the third party software in to the application.

In upcoming posts, I’ll show how to utilize NuGet to manage open source packages in to project.

How to show thumbnails of XPS documents.

Recently I came across the requirement for displaying thumbnails of XPS document in SharePoint document library. As a hardcore developer, I’m not in favor of readymade third -party components unless and until you really need them. Hence, I’ve decided to create an image generator myself. I explored the native .net methods for reading the XPS documents. After exploring, I found that in .net framework 3.0, there is a managed dll called ReachFramework.dll is having all the necessary classes and methods for reading and writing of XPS document.

Classes

Class diagram - XPS document thumbnail generation
Class diagram

XpsThumbnail class

This is the one and only class which is actually generates the thumbnails from XPS documents using GenerateThumbnail method.

converter.GenerateThumbnail();

Properties

Property Description
OutputFormat Output format for the generated image.
OutputQuality Quality for the generated image.
OutputStream MemoryStream object to be returned
XpsFileName XPS document whose image needs to be gerated.

Complete Class Listing

    ///
    /// Provides methods for converting XPS document in to various image format
    ///
    public class XpsImage
    {
        private BitmapEncoder bitmapEncoder = null;
        ///
        /// Default constructor
        ///
        public XpsImage()
        {
        }

        ///
        /// Sets the XPS file to be read
        ///
        public String XpsFileName { private get; set; }

        ///
        /// Gets or Sets the image format for thumbnail
        ///
        public OutputFormat OutputFormat {get; set; }

        ///
        /// Gets or Sets the image quality for thumbnail
        ///
        public OutputQuality OutputQuality { private get; set; }

        ///
        /// Returns the Memory stream of generated thumbnail
        ///
        public MemoryStream OutputStream { get; private set; }

        ///
        /// Generate the thumbnail of given document and populates the ThumbnailStream property
        ///
        public void GenerateThumbnail()
        {
            XpsDocument xpsDocument = new XpsDocument(this.XpsFileName, FileAccess.Read);
            FixedDocumentSequence documentPageSequence = xpsDocument.GetFixedDocumentSequence();

            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(this.XpsFileName);
            string fileExtension = string.Empty;

            switch (this.OutputFormat)
            {
                case OutputFormat.Jpeg:
                    fileExtension = ".jpg";
                    bitmapEncoder = new JpegBitmapEncoder();
                    break;
                case OutputFormat.Png:
                    fileExtension = ".png";
                    bitmapEncoder = new PngBitmapEncoder();
                    break;
                case OutputFormat.Gif:
                    fileExtension = ".gif";
                    bitmapEncoder = new GifBitmapEncoder();
                    break;
                default:
                    fileExtension = ".jpg";
                    bitmapEncoder = new JpegBitmapEncoder();
                    break;
            }

            double imageQualityRatio = 1.0;
            switch (this.OutputQuality)
            {
                case OutputQuality.Low:
                    imageQualityRatio /= 2.0;
                    break;

                case OutputQuality.Good:
                    imageQualityRatio *= 2.0;
                    break;

                case OutputQuality.Super:
                    imageQualityRatio *= 3.0;
                    break;
                default:
                    imageQualityRatio *= 1.0;
                    break;
            }

            DocumentPage documentPage = documentPageSequence.DocumentPaginator.GetPage(0);
            RenderTargetBitmap targetBitmap = new RenderTargetBitmap((int)(documentPage.Size.Width * imageQualityRatio), (int)(documentPage.Size.Height * imageQualityRatio), 96.0 * imageQualityRatio, 96.0 * imageQualityRatio, PixelFormats.Pbgra32);
            targetBitmap.Render(documentPage.Visual);

            bitmapEncoder.Frames.Add(BitmapFrame.Create(targetBitmap));
            string str4 = string.Format("{0}{1}", fileNameWithoutExtension, fileExtension);
            MemoryStream memoryStream = new MemoryStream();
            bitmapEncoder.Save(memoryStream);
            this.OutputStream = memoryStream;
            xpsDocument.Close();
        }
    }

Using Code

The class itself is the simple class and made for simplicity. Below is small snippet how to utilize the class.

converter.XpsFileName = “XPSdocument.xps”;
converter.OutputFormat = OutputFormat.Png;
converter.OutputQuality = OutputQuality.Super;
converter.GenerateThumbnail();

Conclusion

The sample application provided with this article just demonstrated the utilization of the code. In the demo application, you need to save the image by invoking context menu from the thumbnail to see the output as I’m using the in memory image stream to display image in to picture box.

And please don’t hesitate to provide feedback, good or bad! I hope you enjoyed this article.

ASP.net application performance tuning with ViewState

In past, I’ve started developing asp.net applications with the default settings of asp.net. Sometimes I found that the application is not responding quickly as it should be. I’ve digged in to this matter and figured out that the entire page is heavily loaded with the hidden page viewstate. Due to this length, the application is taking much long time to load in browser. To overcome this issue, the viewstate needs to be compressed using some kind of the compression.

ASP.net application viewstate size after compression

Below is the methods which I’ve used in my application for compressing the viewstate data.

public static class Zip
{
    private const int BUFFER_SIZE = 65536;
    static int viewStateCompression = Deflater.NO_COMPRESSION;

    public static  int ViewStateCompression
    {
        get { return viewStateCompression; }
        set { viewStateCompression = value; }
    }

    public static byte[] Compress(byte[] bytes)
    {
        using (MemoryStream memoryStream = new MemoryStream(BUFFER_SIZE))
        {
            Deflater deflater = new Deflater(ViewStateCompression);
            using (Stream stream = new DeflaterOutputStream(memoryStream, deflater, BUFFER_SIZE))
            {
                stream.Write(bytes, 0, bytes.Length);
            }
            return memoryStream.ToArray();
        }
    }

    public static byte[] Decompress(byte[] bytes)
    {
        using (MemoryStream byteStream = new MemoryStream(bytes))
        {
            using (Stream stream = new InflaterInputStream(byteStream))
            {
                using (MemoryStream memory = new MemoryStream(BUFFER_SIZE))
                {
                    byte[] buffer = new byte[BUFFER_SIZE];
                    while (true)
                    {
                        int size = stream.Read(buffer, 0, BUFFER_SIZE);
                        if (size <= 0)
                            break;

                        memory.Write(buffer, 0, size);
                    }
                    return memory.ToArray();
                }
            }
        }
    }
}

System.Web.UI.Page is having two methods SavePageStateToPersistenceMedium(Object state) & LoadPageStateFromPersistenceMedium() which are responsible for state management via viewstate. We need to override these methods in to our custom base class for compressing the viewstate.

protected override void SavePageStateToPersistenceMedium(Object state)
{
    if (ViewStateCompression == Deflater.NO_COMPRESSION)
    {
        base.SavePageStateToPersistenceMedium(state);
        return;
    }

    Object viewState = state;
    if (state is Pair)
    {
        Pair statePair = (Pair)state;
        PageStatePersister.ControlState = statePair.First;
        viewState = statePair.Second;
    }

    using (StringWriter writer = new StringWriter())
    {
        new LosFormatter().Serialize(writer, viewState);
        string base64 = writer.ToString();
        byte[] compressed = Zip.Compress(Convert.FromBase64String((base64)));
        PageStatePersister.ViewState = Convert.ToBase64String(compressed);
    }
    PageStatePersister.Save();
}

protected override Object LoadPageStateFromPersistenceMedium()
{
    if (viewStateCompression == Deflater.NO_COMPRESSION)
        return base.LoadPageStateFromPersistenceMedium();

    PageStatePersister.Load();
    String base64 = PageStatePersister.ViewState.ToString();
    byte[] state = Zip.Decompress(Convert.FromBase64String(base64));
    string serializedState = Convert.ToBase64String(state);

    object viewState = new LosFormatter().Deserialize(serializedState);
    return new Pair(PageStatePersister.ControlState, viewState);
}

To enable compression we need to override OnInit method from System.Web.UI.Page class.

protected override void OnInit(EventArgs e)
{
    Zip.ViewStateCompression = Deflater.BEST_COMPRESSION;
    base.OnInit(e);
}

I’ve used Sharp ZipLib for the compression and found the interesting results. On an average I found that the entire viewstate is compressed nearly up to 30% of the original viewstate size.

ASP.net application viewstate size after compression

Below is a small piece of code which is showing the viewstate data size.

public class ViewstateSizeControl : Label
{
    private const string SCRIPT = "document.getElementById('{0}').innerText = 'Size of Viewstate: ' + document.getElementById('__VIEWSTATE').value.length;";

    protected override void OnLoad(EventArgs e)
    {
        if (Visible)
        {
            Page.ClientScript.RegisterStartupScript(
                typeof(Page),
                UniqueID,
                string.Format(SCRIPT, ClientID),
                true);
        }
        base.OnLoad(e);
    }
}

To use the control, simply put the control on the aspx page and compare the size of viewstate before and after compression.

Hope this will help you all in your upcoming/current assignment.

Happy Programming..