<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4734008815438417747</id><updated>2024-10-05T07:34:56.358+05:30</updated><category term="Silverlight"/><category term="Silverlight 4"/><category term="ASP.Net MVC 3"/><category term="ASP.Net"/><category term="ASP.Net MVC"/><category term="Design Patterns"/><category term="jQuery"/><category term="Patterns"/><category term="Print API"/><category term="jQuery templates"/><category term="ASP.Net WebApi"/><category term="Azure"/><category term="Azure BLOB Storage"/><category term="C#"/><category term="Chunk read"/><category term="Dependency Injection"/><category term="OData"/><category term="Print fit to page"/><category term="WCF"/><category term="WCF Data Services"/><category term="Abstract Factory Pattern"/><category term="Amazon S3"/><category term="AsyncController"/><category term="AsyncPostBack"/><category term="Bind to Ancestor or parent property"/><category term="Builder Pattern"/><category term="CheckAll using jQuery"/><category term="ComboBox"/><category term="Command"/><category term="Containers"/><category term="DI"/><category term="Dependency property"/><category term="EntityFramework4.1"/><category term="Factory Method"/><category term="FlowControlManager"/><category term="GetAnimationBaseValue"/><category term="IOC"/><category term="Inversion Of Control"/><category term="JSONP"/><category term="Json Converter"/><category term="Large file downloads"/><category term="Mediator Pattern"/><category term="Nuget"/><category term="OWIN"/><category term="ObservableCollection"/><category term="ObservableCollection Filtering"/><category term="Observer Pattern"/><category term="Print centered"/><category term="REST"/><category term="Razor"/><category term="Regulator"/><category term="Security Exception"/><category term="SignalR"/><category term="Silverlight 5"/><category term="Silverlight Binding"/><category term="Silverlight Child window pattern"/><category term="Silverlight WCF Fault"/><category term="UpdatePanel"/><category term="VS2010"/><category term="VSTS"/><category term="WCF Duplex MEP"/><category term="WCF REST JSON"/><category term="WebJobDeploy"/><category term="Windows Phone"/><category term="Windows Phone 7.1"/><category term="XAP"/><category term="autofac"/><category term="autofac action filter"/><category term="checksum"/><category term="executiontime"/><category term="nLayerArchitecture"/><title type='text'>Tito.Net</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://info.titodotnet.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default?start-index=26&amp;max-results=25'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>66</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-3940821333298572486</id><published>2018-03-31T00:50:00.000+05:30</published><updated>2018-03-31T12:00:50.042+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Amazon S3"/><category scheme="http://www.blogger.com/atom/ns#" term="Azure"/><category scheme="http://www.blogger.com/atom/ns#" term="Azure BLOB Storage"/><title type='text'>Copy large data objects from Azure BLOB to Amazon S3</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Scenario&lt;/h2&gt;
&lt;div&gt;
This article is going to focus on providing guidance and library for copying Azure BLOB to Amazon S3. Using .NET (C#), have created few classes which will help us to achieve copying large BLOB into Amazon S3.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Points to be considered&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;As we&#39;re targeting large data objects to be copied, we need perform Multipart upload.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;From Azure BLOB, in order to download data in parts, we can utilize &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblob.downloadrangetostream?view=azure-dotnet&quot; target=&quot;_blank&quot;&gt;DownloadRangeToStream&lt;/a&gt; method.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Amazon S3 also provides us the facility to perform Multipart upload using the APIs exposed through AWS .NET SDK.&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;But first we need to understand the nature and different options the SDK provides and select which best suit of needs.&lt;/li&gt;
&lt;li&gt;AWS .NET SDK for Multipart upload provides High-Level API and Low-Level API.&lt;/li&gt;
&lt;li&gt;High-Level API provides us with some sophisticated way of performing few common operations on S3 by encapsulating core level implementations.&lt;/li&gt;
&lt;li&gt;Low-Level API as you might have guessed, exposes the core Multipart operations on S3.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;For our scenario, Low-Level API will be the best fit as we need few detailed control over the operations.&lt;/li&gt;
&lt;li&gt;Maximum of 10000 parts are allowed per upload.&lt;/li&gt;
&lt;li&gt;Part size can be of range 5MB to 5GB with an exception to the last part which can be less than 5MB.&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;To handle our scenario, we&#39;re going to stick to 100MB as part size in our library.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Library Source code&lt;/h2&gt;
&lt;div&gt;
Following classes has been created to facilitate developers utilize as library encapsulating the implementation logic of the copy operation and provide Request and Response object for ease of use and code management.&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/titodotnet/aws-samples/blob/master/AWSSamples/AWSSampleConsoleApp1/BlobToS3/BlobToS3Manager.cs&quot; target=&quot;_blank&quot;&gt;BlobToS3Manager&lt;/a&gt;: Holds the implementation logic of copying BLOB data int S3.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/titodotnet/aws-samples/blob/master/AWSSamples/AWSSampleConsoleApp1/BlobToS3/IBlobToS3Manager.cs&quot; target=&quot;_blank&quot;&gt;IBlobToS3Manager&lt;/a&gt;: Prototype of BlobToS3Manager.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/titodotnet/aws-samples/blob/master/AWSSamples/AWSSampleConsoleApp1/BlobToS3/BlobToS3Request.cs&quot; target=&quot;_blank&quot;&gt;BlobToS3Request&lt;/a&gt;: To hold the BLOB source and S3 target data needed for copy operation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/titodotnet/aws-samples/blob/master/AWSSamples/AWSSampleConsoleApp1/BlobToS3/BlobToS3Response.cs&quot; target=&quot;_blank&quot;&gt;BlobToS3Response&lt;/a&gt;: To hold the response of the copy operation.&amp;nbsp; &amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
You can find the above 4 library files in my github directory &lt;a href=&quot;https://github.com/titodotnet/aws-samples/tree/master/AWSSamples/AWSSampleConsoleApp1/BlobToS3&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Snippet 1 (&lt;a href=&quot;https://github.com/titodotnet/aws-samples/blob/master/AWSSamples/AWSSampleConsoleApp1/BlobToS3/BlobToS3Manager.cs&quot; target=&quot;_blank&quot;&gt;BlobToS3Manager&lt;/a&gt;)&lt;/h3&gt;
&lt;/div&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false;&quot; style=&quot;text-align: left;&quot;&gt;namespace AWSSampleConsoleApp1.BlobToS3
{
    using Amazon.S3.Model;
    using Microsoft.WindowsAzure.Storage.Blob;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Security.Cryptography;
    using System.Threading.Tasks;

    /// &amp;lt;summary&amp;gt;
    /// Handles the BLOB to S3 
    /// &amp;lt;/summary&amp;gt;
    public class BlobToS3Manager : IBlobToS3Manager
    {
        /// &amp;lt;summary&amp;gt;
        /// The container not exists.
        /// &amp;lt;/summary&amp;gt;
        private const string ContainerNotExists = &quot;BLOB Container doesn&#39;t exists.&quot;;

        /// &amp;lt;summary&amp;gt;
        /// The BLOB not exists.
        /// &amp;lt;/summary&amp;gt;
        private const string BlobNotExists = &quot;BLOB doesn&#39;t exists.&quot;;

        /// &amp;lt;summary&amp;gt;
        /// Part size to read from BLOB and upload to S3.
        /// &amp;lt;/summary&amp;gt;
        private const long PartSize = 104857600; // 100 MB.

        /// &amp;lt;summary&amp;gt;
        /// The BLOB S3 request.
        /// &amp;lt;/summary&amp;gt;
        private readonly BlobToS3Request blobToS3Request;
        /// &amp;lt;summary&amp;gt;
        /// Initializes new instance of BLOB to S3 Manager.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;blobToS3Request&quot;&amp;gt;The BLOB to S3 request.&amp;lt;/param&amp;gt;
        public BlobToS3Manager(BlobToS3Request blobToS3Request)
        {
            this.blobToS3Request = blobToS3Request;
        }

        /// &amp;lt;summary&amp;gt;
        /// Copies BLOB to S3.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;The BLOB to S3 response.&amp;lt;/returns&amp;gt;
        public async Task&amp;lt;BlobToS3Response&amp;gt; CopyFromBlobToS3Async()
        {
            BlobToS3Response blobToS3Response = new BlobToS3Response();
            var validation = await this.Validate();

            if (!validation.Item1)
            {
                return validation.Item2;
            }

            var sourceBlob = validation.Item3;
            await sourceBlob.FetchAttributesAsync();
            var remainingBytes = sourceBlob.Properties.Length;
            long readPosition = 0; // To be used offset / position from where to start reading from BLOB.

            InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest
            {
                BucketName = this.blobToS3Request.TargetS3Bucket,
                Key = this.blobToS3Request.TargetS3File
            };

            // Will use UploadId from this response.
            InitiateMultipartUploadResponse initiateMultipartUploadResponse = this.blobToS3Request.S3Client.InitiateMultipartUpload(initiateMultipartUploadRequest);
            List&amp;lt;UploadPartResponse&amp;gt; uploadPartResponses = new List&amp;lt;UploadPartResponse&amp;gt;();

            try
            {
                int partCounter = 0; // To increment on each read of parts and use it as part number.
                var sha256 = new SHA256Managed();

                while (remainingBytes &amp;gt; 0)
                {
                    // Determine the size when final block reached as it might be less than Part size. 
                    // Will be PartSize except final block.
                    long bytesToCopy = Math.Min(PartSize, remainingBytes);

                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        // To download part from BLOB.
                        await sourceBlob.DownloadRangeToStreamAsync(memoryStream, readPosition, bytesToCopy).ConfigureAwait(false);
                        memoryStream.Position = 0;
                        partCounter++;

                        UploadPartRequest uploadRequest = new UploadPartRequest
                        {
                            BucketName = this.blobToS3Request.TargetS3Bucket,
                            Key = this.blobToS3Request.TargetS3File,
                            UploadId = initiateMultipartUploadResponse.UploadId,
                            PartNumber = partCounter,
                            PartSize = bytesToCopy,
                            InputStream = memoryStream
                        };

                        UploadPartResponse uploadPartResponse = this.blobToS3Request.S3Client.UploadPart(uploadRequest);
                        uploadPartResponses.Add(uploadPartResponse);

                        remainingBytes -= bytesToCopy;
                        readPosition += bytesToCopy;

                        // $&quot;Uploaded part with part number {partCounter}, size {bytesToCopy}bytes and remaining {remainingBytes}bytes to read.&quot;)

                        // Calculate the checksum value.
                        if (remainingBytes &amp;lt;= 0)
                        {
                            sha256.TransformFinalBlock(memoryStream.ToArray(), 0, (int)bytesToCopy);
                        }
                        else
                        {
                            byte[] bytesToSend = memoryStream.ToArray();
                            sha256.TransformBlock(bytesToSend, 0, (int)bytesToCopy, bytesToSend, 0);
                        }
                    }
                }

                blobToS3Response.Sha256CheckSum = BitConverter.ToString(sha256.Hash).Replace(&quot;-&quot;, string.Empty);

                CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest
                {
                    BucketName = this.blobToS3Request.TargetS3Bucket,
                    Key = this.blobToS3Request.TargetS3File,
                    UploadId = initiateMultipartUploadResponse.UploadId
                };

                completeMultipartUploadRequest.AddPartETags(uploadPartResponses);

                CompleteMultipartUploadResponse completeMultipartUploadResponse = await this.blobToS3Request.S3Client.CompleteMultipartUploadAsync(completeMultipartUploadRequest).ConfigureAwait(false);

                blobToS3Response.IsSuccess = true;
                blobToS3Response.S3Path = completeMultipartUploadResponse.Location;
            }
            catch (Exception exception)
            {
                blobToS3Response.IsSuccess = false;
                blobToS3Response.Message = exception.Message;

                AbortMultipartUploadRequest abortMultipartUploadRequest = new AbortMultipartUploadRequest
                {
                    BucketName = this.blobToS3Request.TargetS3Bucket,
                    Key = this.blobToS3Request.TargetS3File,
                    UploadId = initiateMultipartUploadResponse.UploadId
                };

                await this.blobToS3Request.S3Client.AbortMultipartUploadAsync(abortMultipartUploadRequest).ConfigureAwait(false);
            }

            return blobToS3Response;
        }

        /// &amp;lt;summary&amp;gt;
        /// Validates the source BLOB is valid.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;The resultant tuple.&amp;lt;/returns&amp;gt;
        private async Task&amp;lt;Tuple&amp;lt;bool, BlobToS3Response, CloudBlockBlob&amp;gt;&amp;gt; Validate()
        {
            BlobToS3Response blobToS3Response = null;
            CloudBlobContainer cloudBlobContainer = this.blobToS3Request.BlobClient.GetContainerReference(this.blobToS3Request.SourceBlobContainer);

            if (!await cloudBlobContainer.ExistsAsync())
            {
                blobToS3Response = new BlobToS3Response
                {
                    IsSuccess = false,
                    Message = ContainerNotExists
                };

                return new Tuple&amp;lt;bool, BlobToS3Response, CloudBlockBlob&amp;gt;(false, blobToS3Response, null);
            }

            CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(this.blobToS3Request.SourceBlob);

            if (await cloudBlockBlob.ExistsAsync())
            {
                return new Tuple&amp;lt;bool, BlobToS3Response, CloudBlockBlob&amp;gt;(true, null, cloudBlockBlob);
            }

            blobToS3Response = new BlobToS3Response
            {
                IsSuccess = false,
                Message = BlobNotExists
            };

            return new Tuple&amp;lt;bool, BlobToS3Response, CloudBlockBlob&amp;gt;(false, blobToS3Response, null);
        }

    }
}

&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;h3&gt;
Snippet 2 (&lt;a href=&quot;https://github.com/titodotnet/aws-samples/blob/master/AWSSamples/AWSSampleConsoleApp1/CopyFromBlobToS3.cs&quot; target=&quot;_blank&quot;&gt;CopyFromBlobToS3&lt;/a&gt;: Sample on how to create instances and call the library)&lt;/h3&gt;
&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/titodotnet/76049cb220ae155e26913826696de995.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;div&gt;
Full source code can be found in my github repo &lt;a href=&quot;https://github.com/titodotnet/aws-samples/tree/master/AWSSamples&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
References&lt;/h2&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblob.downloadrangetostream?view=azure-dotnet&quot;&gt;https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblob.downloadrangetostream?view=azure-dotnet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblob.downloadrangetostreamasync?view=azure-dotnet&quot;&gt;https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblob.downloadrangetostreamasync?view=azure-dotnet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/dev/LLuploadFileDotNet.html&quot;&gt;https://docs.aws.amazon.com/AmazonS3/latest/dev/LLuploadFileDotNet.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html&quot;&gt;https://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/3940821333298572486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2018/03/copy-large-data-objects-from-azure-blob.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/3940821333298572486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/3940821333298572486'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2018/03/copy-large-data-objects-from-azure-blob.html' title='Copy large data objects from Azure BLOB to Amazon S3'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-8066938912617272435</id><published>2018-02-18T21:38:00.000+05:30</published><updated>2018-02-18T23:46:35.937+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="checksum"/><category scheme="http://www.blogger.com/atom/ns#" term="Chunk read"/><title type='text'>Calculating Hash values / checksum for files while we read them as Streams in chunks</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Introduction&lt;/h2&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;You might need to encounter situations where you need to calculate the checksum of file / stream while transmitting across the wire. Nowadays, it is common to transmit the file stream frequently and during that scenario, you need to ensure data has not been corrupted during this transmission process. For which in the receiving end you need to use the same algorithm and recalculate the checksum to ensure the transmitted data is not corrupted.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Scenario&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Let me take the same scenario I explained in my previous post&amp;nbsp;&lt;a href=&quot;http://info.titodotnet.com/2018/02/download-large-files-as-chunks-and.html&quot; target=&quot;_blank&quot;&gt;Download large files as chunks and upload them into BLOB&lt;/a&gt;. In which we downloaded and transmitted large file as stream in chunks. There are lot of articles over web explaining calculating checksum for full file stream. Here we&#39;ll see the snippet below for the case of calculating checksum for chunks and get them accumulated at the end.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Tips&lt;/h2&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;HashAlgorithm.TransformBlock and HashAlgorithm.TransformFinalBlock will help you achieve this.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Snippet&lt;/h2&gt;
&lt;/div&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false;&quot;&gt;public class LargeFileProcessor
    {       
        /// &amp;lt;summary&amp;gt;
        /// Logger instance.
        /// &amp;lt;/summary&amp;gt;
        private ILogger logger = new Logger();

        /// &amp;lt;summary&amp;gt;
        /// Download Large File as chunk and upload as chunk into BLOB.
        /// &amp;lt;/summary&amp;gt;
        public async Task ProcessLargeFile()
        {
            // Trimmed for brevity.

            string urlToDownload = CloudConfigurationManager.GetSetting(&quot;DownloadURL&quot;); // Provide valid URL from where the large file can be downloaded.

            Stopwatch stopwatch = Stopwatch.StartNew();

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(urlToDownload))
                    {
                        // To avoid error related to &#39;An existing connection was forcibly closed by the remote host&#39;. Use Http1.0 instead of Http1.1.
                        Version = HttpVersion.Version10
                    };

                    using (HttpResponseMessage response = await httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
                    {
                        using (Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                        {
                            const int pageSizeInBytes = 104857600; // 100MB. As Blob chunk max size is 100MB as of now.

                            var sha256 = new SHA256Managed();

                            var bytesRemaing = response.Content.Headers.ContentLength.Value; // Read Total file size from the header.

                            while (bytesRemaing &amp;gt; 0)
                            {
                                var bytesToCopy = (int)Math.Min(bytesRemaing, pageSizeInBytes);
                                var bytesToSend = new byte[bytesToCopy];

                                var bytesCountRead = await ReadStreamAndAccumulate(stream, bytesToSend, bytesToCopy);

                                // Instead of calculating bytes remaining to exit the While loop,  we can use bytesCountRead as bytesCountRead will be 0 when there are no more bytes to read form the stream.   
                                bytesRemaing -= bytesCountRead;

                                // Calculate the checksum value.
                                if (bytesRemaing &amp;lt;= 0)
                                {
                                    sha256.TransformFinalBlock(bytesToSend, 0, bytesCountRead);
                                }
                                else
                                {
                                    sha256.TransformBlock(bytesToSend, 0, bytesCountRead, bytesToSend, 0);
                                }
                            }

                            var checksum = BitConverter.ToString(sha256.Hash).Replace(&quot;-&quot;, string.Empty);
                            this.logger.WriteLine($&quot;Hash value is : {checksum}&quot;);

                            await Task.FromResult(0);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.logger.WriteLine(ex.Message);
                throw;
            }
            finally
            {
                stopwatch.Stop();
                this.logger.WriteLine($&quot;Execution time in mins: {stopwatch.Elapsed.TotalMinutes}&quot;);
            }
        }

        /// &amp;lt;summary&amp;gt;
        /// Read the stream and accumulate till it reaches the number of bytes specified to copy.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;stream&quot;&amp;gt;Stream to be read from.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;bytesToSend&quot;&amp;gt;Target byte array that holds the bytes read.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;bytesCountToCopy&quot;&amp;gt;The number of bytes to be copied.&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;The number of bytes read.&amp;lt;/returns&amp;gt;
        private async Task&amp;lt;int&amp;gt; ReadStreamAndAccumulate(Stream stream, byte[] bytesToSend, int bytesCountToCopy)
        {
                        // Trimmed for brevity.
        }

        /// &amp;lt;summary&amp;gt;
        /// Reads the stream with retry when failed. 
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;stream&quot;&amp;gt;Stream to be read from.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;bytesToSend&quot;&amp;gt;Target byte array that holds the bytes read.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;bytesCountToCopy&quot;&amp;gt;The number of bytes to be copied.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;offset&quot;&amp;gt;The byte offset in buffer at which to begin writing data from the stream.&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;The number of bytes read.&amp;lt;/returns&amp;gt;
        private async Task&amp;lt;int&amp;gt; ReadStreamWithRetry(Stream stream, byte[] bytesToSend, int bytesCountToCopy, int offset)
        {
                        // Trimmed for brevity.
        }
    }

&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;In the above Snippet I&#39;ve trimmed set of code to just focus on minimalist snippet to portray calculating checksum for chunk read. You can find full source code in my github repo&amp;nbsp;&lt;a href=&quot;https://github.com/titodotnet/azure-samples/blob/master/AzureSamples/AzureSampleConsoleApp1/ChunkDownloadLargeFileAndUploadToBlob.cs&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
References&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;http://peterkellner.net/2010/11/24/efficiently-generating-sha256-checksum-for-files-using-csharp/&quot;&gt;http://peterkellner.net/2010/11/24/efficiently-generating-sha256-checksum-for-files-using-csharp/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hashalgorithm.transformblock?view=netframework-4.7.1#System_Security_Cryptography_HashAlgorithm_TransformBlock_System_Byte___System_Int32_System_Int32_System_Byte___System_Int32_&quot;&gt;https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hashalgorithm.transformblock?view=netframework-4.7.1#System_Security_Cryptography_HashAlgorithm_TransformBlock_System_Byte___System_Int32_System_Int32_System_Byte___System_Int32_&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hashalgorithm.transformfinalblock?view=netframework-4.7.1#System_Security_Cryptography_HashAlgorithm_TransformFinalBlock_System_Byte___System_Int32_System_Int32_&quot;&gt;https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hashalgorithm.transformfinalblock?view=netframework-4.7.1#System_Security_Cryptography_HashAlgorithm_TransformFinalBlock_System_Byte___System_Int32_System_Int32_&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/8066938912617272435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2018/02/calculating-hash-values-checksum-for.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/8066938912617272435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/8066938912617272435'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2018/02/calculating-hash-values-checksum-for.html' title='Calculating Hash values / checksum for files while we read them as Streams in chunks'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-2397300164763787497</id><published>2018-02-11T19:13:00.000+05:30</published><updated>2018-03-30T23:30:26.842+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Azure"/><category scheme="http://www.blogger.com/atom/ns#" term="Azure BLOB Storage"/><category scheme="http://www.blogger.com/atom/ns#" term="Chunk read"/><category scheme="http://www.blogger.com/atom/ns#" term="Large file downloads"/><title type='text'>Download large files as chunks and upload them into BLOB</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Introduction&lt;/h2&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;In real case scenarios there are time where we need to download large files from from a Web resource and save it to Azure BLOB storage. Even though there are few articles over Web which helped, I&#39;m not able to get a end to end working solution for files with size ranging from 20GB to 30GB. Have detailed below challenges and related solutions for your convenience.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Problem statement&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Download large files from the Web resource and upload them into Azure BLOB storage.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Challenges and Solutions&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;First we&#39;ll hit memory issue when we try to read the full stream and load all bytes into memory. An article &lt;a href=&quot;http://www.tugberkugurlu.com/archive/efficiently-streaming-large-http-responses-with-httpclient&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; explains well how to avoid this Memory issue.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Another article &lt;a href=&quot;https://www.red-gate.com/simple-talk/cloud/platform-as-a-service/azure-blob-storage-part-4-uploading-large-blobs/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; detailed how to read&amp;nbsp;&lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; color: #24292e; margin: 0px; padding: 2.72px 0px;&quot;&gt;FileStream&lt;/code&gt;&lt;span style=&quot;color: #24292e; font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp;as chunks and upload them into BLOB. Using the details from this and #1 we can try to achieve the solution.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Use&amp;nbsp;&lt;span style=&quot;background-color: rgba(27 , 31 , 35 , 0.05); color: #24292e;&quot;&gt;Stream.Read&lt;/span&gt;&amp;nbsp;by passing respective parameters. In that one of the parameter is maximum number of bytes to read from the current stream. And&amp;nbsp; the&amp;nbsp;&lt;span style=&quot;background-color: rgba(27 , 31 , 35 , 0.05); color: #24292e;&quot;&gt;Stream.Read&lt;/span&gt;&amp;nbsp;method returns the bytes read. But that also got into issue as the Stream.Read method returns total number of bytes read which can be less than the maximum count parameter. Detailed documentation of Stream.Read can be found &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.io.stream.read?view=netframework-4.7.1&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&amp;nbsp;Along with that, we can use&amp;nbsp;&lt;span style=&quot;background-color: rgba(27 , 31 , 35 , 0.05); color: #24292e;&quot;&gt;CloudBlockBlob.&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblockblob.putblockasync?view=azure-dotnet&quot; target=&quot;_blank&quot;&gt;PutBlock&lt;/a&gt;&lt;/span&gt;&amp;nbsp;method to upload read chunks into BLOB. Points to note here are, each block (chunk) in BLOB can be maximum of 100MB in size and at the max you can have 50000 blocks (100MB x 50000 blocks = 4.75TB). Detailed documentation can be found &lt;a href=&quot;https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-list#remarks&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Even though #2.1 and #2.2 looks straight forward, there might be issues because Read can read less number of bytes which in turn increases the number of blocks (more than 50000 limit) in the Azure BLOB storage.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;In order to avoid issue mentioned above in #2.3, we need to accumulate the resultant of&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background-color: rgba(27 , 31 , 35 , 0.05); color: #24292e;&quot;&gt;Stream.Read&lt;/span&gt;&amp;nbsp;till it reaches the expected size (100MB in our case).&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Even though you fix the issues specified in #1 and #2 above, you might face exception stating&amp;nbsp;&lt;span style=&quot;background-color: rgba(27 , 31 , 35 , 0.05); color: #24292e;&quot;&gt;An existing connection was forcibly closed by the remote host.&lt;/span&gt;&amp;nbsp;. Though I&#39;m not able to identify the solution for this, have found workaround using the articles &lt;a href=&quot;https://tutel.me/c/programming/questions/33233780/systemnethttphttprequestexception+error+while+copying+content+to+a+stream&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://social.msdn.microsoft.com/Forums/en-US/c620ce2c-c512-4c9f-a481-521ecd260039/systemioioexception-unable-to-read-data-from-the-transport-connection-the-connection-was-closed?forum=vstswebtest&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. Use Http1.0 instead of Http1.1.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Code samples can be found in my github repo &lt;a href=&quot;https://github.com/titodotnet/azure-samples/blob/master/AzureSamples/AzureSampleConsoleApp1/ChunkDownloadLargeFileAndUploadToBlob.cs&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Snippet&amp;nbsp;&lt;/h3&gt;
&lt;/div&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false;&quot;&gt;public class LargeFileProcessor
    {
        /// &amp;lt;summary&amp;gt;
        /// Logger instance.
        /// &amp;lt;/summary&amp;gt;
        private ILogger logger = new Logger();

        /// &amp;lt;summary&amp;gt;
        /// Retry count.
        /// &amp;lt;/summary&amp;gt;
        private int retryCount = 5;

        /// &amp;lt;summary&amp;gt;
        /// Time delay for retry.
        /// &amp;lt;/summary&amp;gt;
        private TimeSpan delay = TimeSpan.FromSeconds(10);

        /// &amp;lt;summary&amp;gt;
        /// Download Large File as chunk and upload as chunk into BLOB.
        /// &amp;lt;/summary&amp;gt;
        public async Task ProcessLargeFile()
        {
            // Create Storage account reference.
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(&quot;StorageAccount&quot;));

            // Create the blob client.
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Retrieve reference to a container.
            CloudBlobContainer container = blobClient.GetContainerReference(CloudConfigurationManager.GetSetting(&quot;ContainerName&quot;));
            container.CreateIfNotExists();

            // Create Blob reference.
            CloudBlockBlob blob = container.GetBlockBlobReference(CloudConfigurationManager.GetSetting(&quot;BlobFileName&quot;));

            string urlToDownload = CloudConfigurationManager.GetSetting(&quot;DownloadURL&quot;); // Provide valid URL from where the large file can be downloaded.

            Stopwatch stopwatch = Stopwatch.StartNew();

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(urlToDownload))
                    {
                        // To avoid error related to &#39;An existing connection was forcibly closed by the remote host&#39;. Use Http1.0 instead of Http1.1.
                        Version = HttpVersion.Version10
                    };

                    using (HttpResponseMessage response = await httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
                    {
                        using (Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                        {
                            const int pageSizeInBytes = 104857600; // 100MB. As Blob chunk max size is 100MB as of now.

                            var blockIds = new List&amp;lt;string&amp;gt;();
                            var sha256 = new SHA256Managed();

                            var bytesRemaing = response.Content.Headers.ContentLength.Value; // Read Total file size from the header.
                            int blockIdentifier = 0;

                            while (bytesRemaing &amp;gt; 0)
                            {
                                blockIdentifier++;
                                var bytesToCopy = (int)Math.Min(bytesRemaing, pageSizeInBytes);
                                var bytesToSend = new byte[bytesToCopy];

                                var bytesCountRead = await ReadStreamAndAccumulate(stream, bytesToSend, bytesToCopy);

                                // Instead of calculating bytes remaining to exit the While loop,  we can use bytesCountRead as bytesCountRead will be 0 when there are no more bytes to read form the stream.   
                                bytesRemaing -= bytesCountRead;

                                this.logger.WriteLine($&quot;bytes read: {bytesCountRead}&quot;);
                                this.logger.WriteLine($&quot;bytes remaining: {bytesRemaing}&quot;);

                                string base64BlockId = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format(&quot;largefile1BlockId{0}&quot;, blockIdentifier.ToString(&quot;0000000&quot;))));
                                blockIds.Add(base64BlockId);

                                // Calculate the checksum value.
                                if (bytesRemaing &amp;lt;= 0)
                                {
                                    sha256.TransformFinalBlock(bytesToSend, 0, bytesCountRead);
                                }
                                else
                                {
                                    sha256.TransformBlock(bytesToSend, 0, bytesCountRead, bytesToSend, 0);
                                }

                                await blob.PutBlockAsync(base64BlockId, new MemoryStream(bytesToSend), null);
                            }

                            var checksum = BitConverter.ToString(sha256.Hash).Replace(&quot;-&quot;, string.Empty);
                            this.logger.WriteLine($&quot;Hash value is : {checksum}&quot;);
                            await blob.PutBlockListAsync(blockIds);

                            await Task.FromResult(0);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.logger.WriteLine(ex.Message);
                throw;
            }
            finally
            {
                stopwatch.Stop();
                this.logger.WriteLine($&quot;Execution time in mins: {stopwatch.Elapsed.TotalMinutes}&quot;);
            }
        }

        /// &amp;lt;summary&amp;gt;
        /// Read the stream and accumulate till it reaches the number of bytes specified to copy.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;stream&quot;&amp;gt;Stream to be read from.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;bytesToSend&quot;&amp;gt;Target byte array that holds the bytes read.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;bytesCountToCopy&quot;&amp;gt;The number of bytes to be copied.&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;The number of bytes read.&amp;lt;/returns&amp;gt;
        private async Task&amp;lt;int&amp;gt; ReadStreamAndAccumulate(Stream stream, byte[] bytesToSend, int bytesCountToCopy)
        {
            int bytesReadSoFar = 0;

            while (bytesReadSoFar &amp;lt; bytesCountToCopy)
            {
                var currentBytesCountRead = await ReadStreamWithRetry(stream, bytesToSend, bytesCountToCopy - bytesReadSoFar, bytesReadSoFar).ConfigureAwait(false);
                bytesReadSoFar += currentBytesCountRead;
            }

            return bytesReadSoFar;
        }

        /// &amp;lt;summary&amp;gt;
        /// Reads the stream with retry when failed. 
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;stream&quot;&amp;gt;Stream to be read from.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;bytesToSend&quot;&amp;gt;Target byte array that holds the bytes read.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;bytesCountToCopy&quot;&amp;gt;The number of bytes to be copied.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&quot;offset&quot;&amp;gt;The byte offset in buffer at which to begin writing data from the stream.&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;The number of bytes read.&amp;lt;/returns&amp;gt;
        private async Task&amp;lt;int&amp;gt; ReadStreamWithRetry(Stream stream, byte[] bytesToSend, int bytesCountToCopy, int offset)
        {
            int currentRetry = 0;
            for (; ; )
            {
                try
                {
                    var bytesRead = await stream.ReadAsync(bytesToSend, offset, bytesCountToCopy);
                    return bytesRead;
                }
                catch (Exception ex)
                {
                    this.logger.WriteLine($&quot;Operation Exception : {ex.Message}&quot;);

                    currentRetry++;

                    // Check if it is within the retry count specified.
                    if (currentRetry &amp;gt; this.retryCount)
                    {
                        // Rethrow the exception if it more than the retry attempt.
                        throw;
                    }
                }

                // Wait to retry the operation.
                await Task.Delay(delay);
            }

        }
    }

&lt;/pre&gt;
&lt;div&gt;
&lt;span style=&quot;color: #24292e; font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Full source code has been provided&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/titodotnet/azure-samples/blob/master/AzureSamples/AzureSampleConsoleApp1/ChunkDownloadLargeFileAndUploadToBlob.cs&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;span style=&quot;color: #24292e; font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
References&lt;/h2&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tugberkugurlu.com/archive/efficiently-streaming-large-http-responses-with-httpclient&quot;&gt;http://www.tugberkugurlu.com/archive/efficiently-streaming-large-http-responses-with-httpclient&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/simple-talk/cloud/platform-as-a-service/azure-blob-storage-part-4-uploading-large-blobs/&quot;&gt;https://www.red-gate.com/simple-talk/cloud/platform-as-a-service/azure-blob-storage-part-4-uploading-large-blobs/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weblog.west-wind.com/posts/2014/jan/29/using-net-httpclient-to-capture-partial-responses&quot;&gt;https://weblog.west-wind.com/posts/2014/jan/29/using-net-httpclient-to-capture-partial-responses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://inside.covve.com/uploading-block-blobs-larger-than-256-mb-in-azure/&quot;&gt;https://inside.covve.com/uploading-block-blobs-larger-than-256-mb-in-azure/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.alexandre-gomes.com/?p=144&quot;&gt;http://www.alexandre-gomes.com/?p=144&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-list#remarks&quot;&gt;https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-list#remarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.io.stream.read?view=netframework-4.7.1&quot;&gt;https://docs.microsoft.com/en-us/dotnet/api/system.io.stream.read?view=netframework-4.7.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tutel.me/c/programming/questions/33233780/systemnethttphttprequestexception+error+while+copying+content+to+a+stream&quot;&gt;https://tutel.me/c/programming/questions/33233780/systemnethttphttprequestexception+error+while+copying+content+to+a+stream&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://social.msdn.microsoft.com/Forums/en-US/c620ce2c-c512-4c9f-a481-521ecd260039/systemioioexception-unable-to-read-data-from-the-transport-connection-the-connection-was-closed?forum=vstswebtest&quot;&gt;https://social.msdn.microsoft.com/Forums/en-US/c620ce2c-c512-4c9f-a481-521ecd260039/systemioioexception-unable-to-read-data-from-the-transport-connection-the-connection-was-closed?forum=vstswebtest&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
&amp;nbsp;&lt;/h2&gt;
&lt;span style=&quot;color: #24292e; font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/2397300164763787497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2018/02/download-large-files-as-chunks-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2397300164763787497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2397300164763787497'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2018/02/download-large-files-as-chunks-and.html' title='Download large files as chunks and upload them into BLOB'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-4702142565259266389</id><published>2017-10-30T01:14:00.003+05:30</published><updated>2017-10-30T01:23:03.474+05:30</updated><title type='text'>Time triggered / Scheduler service with Azure Service Fabric</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Introduction&lt;/h2&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Azure Service Fabric Services can be configured to exhibit trigger based behavior similar to &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/app-service/web-sites-create-web-jobs&quot; target=&quot;_blank&quot;&gt;WebJobs&lt;/a&gt; and &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview&quot; target=&quot;_blank&quot;&gt;Azure Functions&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Time triggered / Scheduler Service in Azure Service Fabric&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;To create a time triggered (scheduler) Service in Azure Service Fabric, I can think of following two quick options among the possible ways.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;Create &lt;/span&gt;a time triggered WebJob and add/deploy it as a &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-deploy-existing-app&quot; target=&quot;_blank&quot;&gt;guest executable&lt;/a&gt; in Azure Service Fabric.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Create Azure Service Fabric Stateless Service and implement the listener to handle jobs.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Here I&#39;m taking the second approach which involves the respective listener to be created. Rather than writing new Scheduling framework, I&#39;m using the &lt;a href=&quot;https://www.quartz-scheduler.net/&quot; target=&quot;_blank&quot;&gt;Quartz.Net&lt;/a&gt; framework. I&#39;m using the CRON expression behavior to have the behavior inline with the time trigger behavior of WebJobs and Azure Functions.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;I&#39;ll be explaining two approaches below.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Simple Time trigger Service&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Time trigger Service using Dependency Injection&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Simple Time trigger Service&lt;/h3&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul style=&quot;box-sizing: border-box; color: #24292e; margin-bottom: 16px; margin-top: 0px; padding-left: 32px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Uses &lt;a href=&quot;https://www.quartz-scheduler.net/&quot; style=&quot;box-sizing: border-box; color: #0366d6;&quot; target=&quot;_blank&quot;&gt;Quartz.Net&lt;/a&gt; framework.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; margin-top: 4px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Without Dependency Injection.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; margin-top: 4px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Listerner gets all the &lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; margin: 0px; padding: 2.72px 0px;&quot;&gt;IJob&lt;/code&gt; types from the current assembly with &lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; margin: 0px; padding: 2.72px 0px;&quot;&gt;JobInfoAttribute&lt;/code&gt; decorated.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; margin-top: 4px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; margin: 0px; padding: 2.72px 0px;&quot;&gt;JobInfoAttribute&lt;/code&gt; holds the name and CRON expression of the job.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; margin-top: 4px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Code samples can be found in my github repo &lt;a href=&quot;https://github.com/titodotnet/azure-servicefabric-sample/tree/master/ServiceFabricTriggerSolution/SimpleTimeTriggerService&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;color: #24292e;&quot;&gt;Snippet 1 (SimpleTimeTriggerListener)&lt;/span&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false;&quot;&gt;using Microsoft.ServiceFabric.Services.Communication.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Reflection;
using Quartz;
using TimeTriggerService;
using Quartz.Impl;

namespace SimpleTimeTriggerService
{
    public class SimpleTimeTriggerListener : ICommunicationListener
    {
        private IScheduler scheduler;

        public void Abort()
        {
            scheduler.Shutdown(false);
        }

        public Task CloseAsync(CancellationToken cancellationToken)
        {
            scheduler.Shutdown(true);
            return Task.FromResult(true);
        }

        public Task&amp;lt;string&amp;gt; OpenAsync(CancellationToken cancellationToken)
        {
            var tasks =
                Assembly.GetExecutingAssembly()
                    .GetTypes()
                    .Where(
                        t =&amp;gt;
                            typeof(IJob).IsAssignableFrom(t) &amp;amp;&amp;amp;
                            Attribute.IsDefined(t, typeof(JobInfoAttribute)));

            foreach (var task in tasks)
            {
                var schedulerFactory = new StdSchedulerFactory();
                scheduler = schedulerFactory.GetScheduler();
                var jobInfo = Attribute.GetCustomAttribute(task, typeof(JobInfoAttribute)) as JobInfoAttribute;
                var jobName = jobInfo == null ? task.Name : jobInfo.Name;
                var job = new JobDetailImpl(jobName, null, task);

                var trigger =
                    TriggerBuilder.Create()
                        .WithIdentity($&quot;{jobName}Trigger&quot;, null)
                        .WithCronSchedule(jobInfo.CronExpression)
                        .ForJob(job)
                        .Build();
                scheduler.ScheduleJob(job, trigger);                
            }

            scheduler.Start();

            return Task.FromResult(&quot;Sample Simple Job scheduler&quot;);
        }
    }
}

&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Time trigger Service using Dependency Injection&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul style=&quot;box-sizing: border-box; color: #24292e; margin-bottom: 0px; margin-top: 0px; padding-left: 32px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Uses &lt;a href=&quot;https://www.quartz-scheduler.net/&quot; style=&quot;box-sizing: border-box; color: #0366d6;&quot; target=&quot;_blank&quot;&gt;Quartz.Net&lt;/a&gt; framework.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;box-sizing: border-box; color: #24292e; margin-bottom: 0px; margin-top: 0px; padding-left: 32px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box; margin-top: 4px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;With Dependency Injection using &lt;a href=&quot;https://github.com/alphacloud/Autofac.Extras.Quartz&quot; style=&quot;box-sizing: border-box; color: #0366d6; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Autofac (Autofac integration package for Quartz.Net)&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;box-sizing: border-box; color: #24292e; margin-bottom: 0px; margin-top: 0px; padding-left: 32px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box; margin-top: 4px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Listerner gets all the &lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; margin: 0px; padding: 2.72px 0px;&quot;&gt;IJob&lt;/code&gt; types from the current assembly with &lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; margin: 0px; padding: 2.72px 0px;&quot;&gt;JobInfoAttribute&lt;/code&gt; decorated.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;box-sizing: border-box; color: #24292e; margin-bottom: 0px; margin-top: 0px; padding-left: 32px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box; margin-top: 4px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; margin: 0px; padding: 2.72px 0px;&quot;&gt;JobInfoAttribute&lt;/code&gt; holds the name and CRON expression of the job.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;box-sizing: border-box; color: #24292e; margin-bottom: 0px; margin-top: 0px; padding-left: 32px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box; margin-top: 4px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Code samples can be found in my github repo &lt;a href=&quot;https://github.com/titodotnet/azure-servicefabric-sample/tree/master/ServiceFabricTriggerSolution/TimeTriggerService&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;color: #24292e;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;color: #24292e;&quot;&gt;Snippet 2 (TimeTriggerListener with Autofac)&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false;&quot;&gt;using Microsoft.ServiceFabric.Services.Communication.Runtime;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
using Autofac;
using Quartz;
using Autofac.Extras.Quartz;
using System.Reflection;

namespace TimeTriggerService
{
    internal class TimeTriggerListener : ICommunicationListener
    {
        private IScheduler scheduler;

        public void Abort()
        {
            scheduler.Shutdown(false);
        }

        public Task CloseAsync(CancellationToken cancellationToken)
        {
            scheduler.Shutdown(true);
            return Task.FromResult(true);
        }

        public Task&amp;lt;string&amp;gt; OpenAsync(CancellationToken cancellationToken)
        {
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterModule(new QuartzAutofacFactoryModule());
            builder.RegisterModule(new QuartzAutofacJobsModule(Assembly.GetExecutingAssembly()));
            builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(x =&amp;gt; typeof(IJob).IsAssignableFrom(x)).As&amp;lt;IJob&amp;gt;();
            builder.RegisterType&amp;lt;Logger&amp;gt;().As&amp;lt;ILogger&amp;gt;();
            builder.RegisterType&amp;lt;JobScheduler&amp;gt;().AsSelf();
            IContainer container = builder.Build();
            ConfigureScheduler(container);

            return Task.FromResult(&quot;Sample Job scheduler&quot;);
        }
        
        private void ConfigureScheduler(IContainer container)
        {
            IEnumerable&amp;lt;IJob&amp;gt; jobList = container.Resolve&amp;lt;IEnumerable&amp;lt;IJob&amp;gt;&amp;gt;();
            var jobScheduler = container.Resolve&amp;lt;JobScheduler&amp;gt;();
            this.scheduler = jobScheduler.Start();
        }
    }
}

&lt;/pre&gt;
&lt;/div&gt;
&lt;span style=&quot;color: #24292e;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;color: #24292e;&quot;&gt;Snippet 3 (JobScheduler)&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false;&quot;&gt;using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;

namespace TimeTriggerService
{
    public class JobScheduler
    {
        private IScheduler scheduler;
        private IEnumerable&amp;lt;IJob&amp;gt; jobs;
        public JobScheduler(IScheduler schedulerParam, IEnumerable&amp;lt;IJob&amp;gt; jobsParam)
        {
            this.scheduler = schedulerParam;
            this.jobs = jobsParam;
        }

        public IScheduler Start()
        {
            foreach (var job in jobs)
            {
                var task = job.GetType();
                var jobInfo = Attribute.GetCustomAttribute(task, typeof(JobInfoAttribute)) as JobInfoAttribute;
                var jobName = jobInfo == null ? task.Name : jobInfo.Name;
                var jobDetail = new JobDetailImpl(jobName, null, task);
                var trigger =
                    TriggerBuilder.Create()
                        .WithIdentity($&quot;{jobName}Trigger&quot;, null)
                        .WithCronSchedule(jobInfo.CronExpression)
                        .ForJob(jobDetail)
                        .Build();
                scheduler.ScheduleJob(jobDetail, trigger);
            }
            scheduler.Start();

            return scheduler;
        }
    }
}
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span style=&quot;color: #24292e; font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #24292e; font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Full source code has been provided &lt;a href=&quot;https://github.com/titodotnet/azure-servicefabric-sample&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/4702142565259266389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2017/10/time-triggered-scheduler-service-with.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/4702142565259266389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/4702142565259266389'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2017/10/time-triggered-scheduler-service-with.html' title='Time triggered / Scheduler service with Azure Service Fabric'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-348313647026392368</id><published>2017-10-30T00:38:00.000+05:30</published><updated>2017-10-30T00:38:00.533+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net WebApi"/><category scheme="http://www.blogger.com/atom/ns#" term="Json Converter"/><title type='text'>Applying strict boolean behavior in ASP.NET WEB API JSON request model</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Introduction&lt;/h2&gt;
&lt;div&gt;
In ASP.NET WEB API / MVC in the request input model if you have some property that accepts bool type with content type application/json, it might even accept numbers which will be converted to bool type. If you send numbers as input for bool, it&#39;ll be converted to false for 0 and true for everything else (with an exception observed - 08 and 09 as null).&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Problem statement&lt;/h2&gt;
&lt;div&gt;
To restrict from numbers being accepted as input for bool type property in JSON content type.&lt;/div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Solution&lt;/h2&gt;
&lt;div&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Create a converter that inherits from&amp;nbsp;&lt;span style=&quot;background-color: white; color: #3d85c6; font-family: &amp;quot;consolas&amp;quot;; font-size: 13px;&quot;&gt;Newtonsoft.Json.JsonConverter&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Override &lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span style=&quot;background-color: white; font-family: &amp;quot;consolas&amp;quot;; font-size: 13px;&quot;&gt;ReadJson&lt;/span&gt; &lt;/span&gt;method, check the&amp;nbsp;&lt;span style=&quot;background-color: white; color: #3d85c6; font-family: &amp;quot;consolas&amp;quot;; font-size: 13px;&quot;&gt;ValueType&lt;/span&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;nbsp;&lt;/span&gt;for bool type and throw JSON serializer exception if not.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Snippet (Converter)&lt;/h3&gt;
&lt;/div&gt;
&lt;pre class=&quot;brush: csharp; toolbar: false;&quot;&gt;public class BooleanConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.ValueType != typeof(bool))
        {
            throw new JsonSerializationException(&quot;Invalid data type&quot;);
        }
        return reader.Value;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(bool);
    }
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/348313647026392368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2017/10/applying-strict-boolean-behavior-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/348313647026392368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/348313647026392368'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2017/10/applying-strict-boolean-behavior-in.html' title='Applying strict boolean behavior in ASP.NET WEB API JSON request model'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-2296183187904855623</id><published>2017-10-28T19:19:00.000+05:30</published><updated>2017-10-28T19:19:32.357+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net WebApi"/><category scheme="http://www.blogger.com/atom/ns#" term="autofac"/><category scheme="http://www.blogger.com/atom/ns#" term="autofac action filter"/><category scheme="http://www.blogger.com/atom/ns#" term="executiontime"/><title type='text'>Calculate execution time for your ASP.NET WEB API controller actions using Autofac action filter</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Requirement&lt;/h2&gt;
&lt;div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Calculate execution time of ASP.NET WEB API actions&lt;/li&gt;
&lt;li&gt;Create a common code that can calculate and log the details&lt;/li&gt;
&lt;li&gt;Project uses Autofac for Dependency Injection.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
If you&#39;ve integrated Azure Application Insights to your WEB API, automatically it&#39;ll log/capture the execution time of each request. If you need it as additional logging or in place where Application Insights not associated, this will be helpful. Let us get into the code directly.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Approach&amp;nbsp;&lt;/h2&gt;
&lt;div&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;We will be using ActionFilter to write the logic for calculating the execution time.&lt;/li&gt;
&lt;li&gt;In case of WEB API that uses Autofac as dependency resolver, we can utilize the &lt;span style=&quot;color: #3d85c6;&quot;&gt;IAutofacActionFilter &lt;/span&gt;to achieve the same.&lt;/li&gt;
&lt;li&gt;Register the respective action filter globally to execute for all controllers and actions, so that you don&#39;t need to worry when you add new controllers/actions.&lt;/li&gt;
&lt;li&gt;In the below example I provided the sample snippet related to Autofac based solution. Ignore the Custom logger in the below example as it is just for portraying the sample.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Snippet1: (Action Filter that calculates the execution time and logs)&lt;/h3&gt;
&lt;span style=&quot;background-color: white; color: blue; font-family: consolas, &amp;quot;courier new&amp;quot;, courier, monospace; font-size: 10pt;&quot;&gt;using&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: consolas, &amp;quot;courier new&amp;quot;, courier, monospace; font-size: 10pt;&quot;&gt; System;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style=&quot;background-color: white; margin: 0em; overflow: auto;&quot;&gt;&lt;code style=&quot;color: black; font-family: &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 10pt;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span style=&quot;color: blue;&quot;&gt;using&lt;/span&gt; System.Diagnostics;
&lt;span style=&quot;color: blue;&quot;&gt;using&lt;/span&gt; System.Linq;
&lt;span style=&quot;color: blue;&quot;&gt;using&lt;/span&gt; System.Web;
&lt;span style=&quot;color: blue;&quot;&gt;using&lt;/span&gt; System.Web.Http.Controllers;
&lt;span style=&quot;color: blue;&quot;&gt;using&lt;/span&gt; System.Web.Http.Filters;
&lt;span style=&quot;color: blue;&quot;&gt;using&lt;/span&gt; Autofac.Integration.WebApi;

&lt;span style=&quot;color: blue;&quot;&gt;namespace&lt;/span&gt; TestWebAPI1.Utils
{
    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt; ExecutionTimeActionFilterAttribute : IAutofacActionFilter
    {
        &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; StopwatchInstanceKey = &lt;span style=&quot;color: #a31515;&quot;&gt;&quot;StopwatchInstance&quot;&lt;/span&gt;;

        &lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;readonly&lt;/span&gt; ICustomLogger1 logger;

        &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; ExecutionTimeActionFilterAttribute(ICustomLogger1 loggerParam)
        {
            &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.logger = loggerParam;
        }


        &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; OnActionExecuting(HttpActionContext actionContext)
        {
            Stopwatch stopwatchInstance = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; Stopwatch();
            actionContext.Request.Properties[StopwatchInstanceKey] = stopwatchInstance;
            stopwatchInstance.Start();
        }

        &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            &lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt; (!actionExecutedContext.Request.Properties.ContainsKey(StopwatchInstanceKey))
            {
                &lt;span style=&quot;color: blue;&quot;&gt;return&lt;/span&gt;;
            }

            Stopwatch stopwatchInstance = actionExecutedContext.Request.Properties[StopwatchInstanceKey] &lt;span style=&quot;color: blue;&quot;&gt;as&lt;/span&gt; Stopwatch;
            &lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt; (stopwatchInstance == &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;)
            {
                &lt;span style=&quot;color: blue;&quot;&gt;return&lt;/span&gt;;
            }

            stopwatchInstance.Stop();
            &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt; actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;

            &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.logger.WriteLine($&lt;span style=&quot;color: #a31515;&quot;&gt;&quot;Execution time of action : {actionName} in controller : {actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerName} is {stopwatchInstance.ElapsedMilliseconds} milliseconds&quot;&lt;/span&gt;);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Snippet 2: (Autofac registration in WebApiConfig)&lt;/h3&gt;
&lt;/div&gt;
&lt;pre style=&quot;background-color: white; margin: 0em; overflow: auto;&quot;&gt;&lt;code style=&quot;color: black; font-family: &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 10pt;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;namespace&lt;/span&gt; TestWebAPI1
{
    &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt; WebApiConfig
    {
        &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; Register(HttpConfiguration config)
        {
            &lt;span style=&quot;color: green;&quot;&gt;// Web API configuration and services&lt;/span&gt;
            &lt;span style=&quot;color: green;&quot;&gt;// Configure Web API to use only bearer token authentication.&lt;/span&gt;
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(&lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            &lt;span style=&quot;color: green;&quot;&gt;// Web API routes&lt;/span&gt;
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: &lt;span style=&quot;color: #a31515;&quot;&gt;&quot;DefaultApi&quot;&lt;/span&gt;,
                routeTemplate: &lt;span style=&quot;color: #a31515;&quot;&gt;&quot;api/{controller}/{id}&quot;&lt;/span&gt;,
                defaults: &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; { id = RouteParameter.Optional }
            );

            &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; builder = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; ContainerBuilder();
            
            builder.RegisterType&amp;lt;CustomLogger1&amp;gt;().As&amp;lt;ICustomLogger1&amp;gt;().InstancePerDependency();
            
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
            
            builder.RegisterWebApiFilterProvider(config);
            builder.Register(c =&amp;gt; &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; ExecutionTimeActionFilterAttribute(c.Resolve&amp;lt;ICustomLogger1&amp;gt;()))
                .AsWebApiActionFilterFor&amp;lt;ApiController&amp;gt;()
                .InstancePerRequest();

            &lt;span style=&quot;color: blue;&quot;&gt;var&lt;/span&gt; container = builder.Build();
            config.DependencyResolver = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; AutofacWebApiDependencyResolver(container);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
References&lt;/h2&gt;
&lt;div&gt;
The concept has been taken based on the suggestions by some blogs and stackoverflow forums (unable to recall exact article).&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/2296183187904855623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2017/10/calculate-execution-time-for-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2296183187904855623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2296183187904855623'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2017/10/calculate-execution-time-for-your.html' title='Calculate execution time for your ASP.NET WEB API controller actions using Autofac action filter'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-5908186561315098225</id><published>2017-10-28T18:33:00.000+05:30</published><updated>2017-10-28T18:33:45.990+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="VSTS"/><category scheme="http://www.blogger.com/atom/ns#" term="WebJobDeploy"/><title type='text'>Web Deployment package Zip not getting created even after specifying required MSBuild args in Visual Studio Build task</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
Introduction&lt;/h2&gt;
Visual Studio Team Services (VSTS) provide the facilitation to incorporate Continuous Integration and Continuous deployment. For Azure WebApp/WebJobs Documentation and Blogs are available (like &lt;a href=&quot;https://blogs.msdn.microsoft.com/tfssetup/2016/05/18/deploying-and-schedule-azure-webjobs-from-vsts-to-azure-web-app-with-bonus-cron-scheduling/&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt;, &lt;a href=&quot;http://jakeydocs.readthedocs.io/en/latest/publishing/vsts-continuous-deployment.html&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt; ) to guide you how to achieve those. In this post we&#39;re going to have a look at scenario where the Web deployment package itself might not get created and solution for that.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Scenario&lt;/h3&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/vsts/build-release/tasks/build/visual-studio-build&quot; target=&quot;_blank&quot;&gt;Visual Studio build task&lt;/a&gt; has been added and configured appropriately.&lt;/li&gt;
&lt;li&gt;Respective MSBuild arguments &quot;/p:DeployOnBuild=true
/p:WebPublishMethod=Package /p:PackageAsSingleFile=true
/p:SkipInvalidConfigurations=true /p:PackageLocation=$(Build.BinariesDirectory)&quot; has been provided.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
But even after that Web deployment package zip file not getting created.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Possible Cause and Solution&lt;/h3&gt;
&lt;div&gt;
Ensure you have the Microsoft.Web.WebJobs.Publish NuGet package added to the respective project. If the package is not associated, in your CI execution Buildstep won&#39;t throw any exception, rather it simply won&#39;t create the web deployment zip package.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/5908186561315098225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2017/10/web-deployment-package-zip-not-getting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/5908186561315098225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/5908186561315098225'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2017/10/web-deployment-package-zip-not-getting.html' title='Web Deployment package Zip not getting created even after specifying required MSBuild args in Visual Studio Build task'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-7120385049930822672</id><published>2017-08-25T23:08:00.003+05:30</published><updated>2017-08-25T23:16:14.799+05:30</updated><title type='text'>Visual Studio 2017 - Azure Functions template unavailable</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;After installing &lt;span style=&quot;color: blue;&quot;&gt;Visual Studio 2017 version 15.3&lt;/span&gt; by including Azure development workload, sometimes Azure Functions template might not be available for you in the &lt;span style=&quot;color: blue;&quot;&gt;Add New Project &lt;/span&gt;dialog.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #0b5394; font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Solution&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;In such case, go to &lt;span style=&quot;color: blue;&quot;&gt;Tools &amp;gt;&amp;gt; Extensions and Updates...&lt;/span&gt; , verify update for &lt;span style=&quot;color: blue;&quot;&gt;Azure Functions and Web Jobs Tools&lt;/span&gt; and install the update.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYd4ImHxwdCXBzeXvacQPgw23bD2dUKhdv9E3_9Q1VQXy-VEsz9DEZMsNwZgZDi5AwBWe4SJEqXcNFtBx690ZLAoaqitH5heuD6XWCixzSegZROBfSodAk47tEpfIGCHmbUDHbXsQett9H/s1600/VS2017AzureFunctions.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;193&quot; data-original-width=&quot;927&quot; height=&quot;66&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYd4ImHxwdCXBzeXvacQPgw23bD2dUKhdv9E3_9Q1VQXy-VEsz9DEZMsNwZgZDi5AwBWe4SJEqXcNFtBx690ZLAoaqitH5heuD6XWCixzSegZROBfSodAk47tEpfIGCHmbUDHbXsQett9H/s320/VS2017AzureFunctions.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/7120385049930822672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2017/08/visual-studio-2017-azure-functions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/7120385049930822672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/7120385049930822672'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2017/08/visual-studio-2017-azure-functions.html' title='Visual Studio 2017 - Azure Functions template unavailable'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYd4ImHxwdCXBzeXvacQPgw23bD2dUKhdv9E3_9Q1VQXy-VEsz9DEZMsNwZgZDi5AwBWe4SJEqXcNFtBx690ZLAoaqitH5heuD6XWCixzSegZROBfSodAk47tEpfIGCHmbUDHbXsQett9H/s72-c/VS2017AzureFunctions.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-3408574920155559896</id><published>2014-02-09T20:38:00.002+05:30</published><updated>2014-02-09T20:46:35.249+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="OWIN"/><category scheme="http://www.blogger.com/atom/ns#" term="SignalR"/><title type='text'>Exception when SignalR hosted using OWIN by Azure worker</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;I came across the following error when I tried to host SignalR using OWIN by Azure worker role.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;b&gt;Could not load file or assembly &#39;Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&#39; or one of its dependencies. The located assembly&#39;s manifest definition does not match the assembly reference.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Upon searching over the web, I came across few links (specified some in References).&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Reason is specified over &lt;a href=&quot;https://nuget.codeplex.com/workitem/3827&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: #0b5394;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Fix&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;We need to add few configuration (specified in &lt;b&gt;Snippet 1&lt;/b&gt;) in app.config file of the project where we have specified the SignalR. mapping code.&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;While incorporating the fix, we need to observe it and tweak the new version accordingly, if required. Just verify the packages.config to understand which version of Microsoft.Owin and Microsoft.Owin.Security dll got installed. Most of the time, Microsoft.Owin dll version might have got changed. Ensure the new version specified in the app.config file to be matched with the one you&#39;ve installed / specified in packages.config.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Snippet 1: (app.config)&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false; highlight: [5];&quot;&gt;&amp;lt;runtime&amp;gt;
  &amp;lt;assemblyBinding xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot;&amp;gt;
    &amp;lt;dependentAssembly&amp;gt;
      &amp;lt;assemblyIdentity name=&quot;Microsoft.Owin&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; culture=&quot;neutral&quot; /&amp;gt;
      &amp;lt;bindingRedirect oldVersion=&quot;0.0.0.0-2.1.0.0&quot; newVersion=&quot;2.1.0.0&quot; /&amp;gt;
    &amp;lt;/dependentAssembly&amp;gt;
    &amp;lt;dependentAssembly&amp;gt;
      &amp;lt;assemblyIdentity name=&quot;Microsoft.Owin.Security&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; culture=&quot;neutral&quot; /&amp;gt;
      &amp;lt;bindingRedirect oldVersion=&quot;0.0.0.0-2.0.2.0&quot; newVersion=&quot;2.0.2.0&quot; /&amp;gt;
    &amp;lt;/dependentAssembly&amp;gt;
  &amp;lt;/assemblyBinding&amp;gt;
&amp;lt;/runtime&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Snippet 2: (packages.config)&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false; highlight: [1];&quot;&gt;&amp;lt;package id=&quot;Microsoft.Owin&quot; version=&quot;2.1.0&quot; targetFramework=&quot;net45&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Owin.Cors&quot; version=&quot;2.1.0&quot; targetFramework=&quot;net45&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Owin.Diagnostics&quot; version=&quot;2.0.2&quot; targetFramework=&quot;net45&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Owin.Host.HttpListener&quot; version=&quot;2.0.2&quot; targetFramework=&quot;net45&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Owin.Hosting&quot; version=&quot;2.0.2&quot; targetFramework=&quot;net45&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Owin.Security&quot; version=&quot;2.0.2&quot; targetFramework=&quot;net45&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Owin.SelfHost&quot; version=&quot;2.0.2&quot; targetFramework=&quot;net45&quot; /&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;References:&lt;/span&gt;&lt;/h4&gt;
&lt;a href=&quot;http://stackoverflow.com/questions/20083185/fileloadexception-when-hosting-signalr-at-azure-worker-role-with-f&quot;&gt;&lt;span style=&quot;color: #0b5394; font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://stackoverflow.com/questions/20083185/fileloadexception-when-hosting-signalr-at-azure-worker-role-with-f&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://nuget.codeplex.com/workitem/3827&quot;&gt;&lt;span style=&quot;color: #0b5394; font-family: Arial, Helvetica, sans-serif;&quot;&gt;https://nuget.codeplex.com/workitem/3827&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/3408574920155559896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2014/02/exception-when-signalr-hosted-using.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/3408574920155559896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/3408574920155559896'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2014/02/exception-when-signalr-hosted-using.html' title='Exception when SignalR hosted using OWIN by Azure worker'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-2473544956409316790</id><published>2013-03-21T19:31:00.000+05:30</published><updated>2013-03-21T19:31:01.863+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="WCF Data Services"/><title type='text'>Updating &#39;Microsoft.Data.OData 5.2.0&#39; to &#39;Microsoft.Data.OData 5.3.0&#39; failed</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;div style=&quot;margin: 0in;&quot;&gt;
&lt;span style=&quot;color: #666666; font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Updating
&#39;Microsoft.Data.OData 5.2.0&#39; to &#39;Microsoft.Data.OData 5.3.0&#39; failed. Unable to
find a version of &#39;Microsoft.AspNet.WebApi.OData&#39; that is compatible with
&#39;Microsoft.Data.OData 5.3.0&#39;.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin: 0in;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin: 0in;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;a href=&quot;http://blogs.msdn.com/b/astoriateam/archive/2013/02/18/wcf-data-services-5-3-0-rtw.aspx&quot; target=&quot;_blank&quot;&gt;WCF Data Services 5.3.0 RTW&lt;/a&gt; has been released few days back. Once you install it using the tools installer, it will update the &quot;Add Service Reference&quot; tooling integration in Visual Studio, after which it&#39;ll create the code based on the WCF Data Services 5.3.0. &amp;nbsp;In such case, for now if you try to add service reference to a WCF Data Service in an ASP.NET MVC 4 project you might end up getting the error specified at the top of this page.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin: 0in;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin: 0in;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;As mentioned in the error, it seems that the respective &quot;Microsoft.AspNet.WebApi.OData&quot; dll is not available in the last ASP.NET MVC 4 update. Hope this will be made available in the next related update.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin: 0in;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin: 0in;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Solution: Uninstall the respective program installed using the&amp;nbsp;&lt;a href=&quot;http://blogs.msdn.com/b/astoriateam/archive/2013/02/18/wcf-data-services-5-3-0-rtw.aspx&quot; target=&quot;_blank&quot;&gt;WCF Data Services 5.3.0 RTW&lt;/a&gt;&amp;nbsp;tools installer. If you try the service reference now it&#39;ll get you with&amp;nbsp;Microsoft.Data.OData 5.2.0 in the client. This way we can go with WCF Data Service created with 5.3.0 version and the respective client libraries (proxy....) with 5.2.0 (in ASP.NET MVC 4 client projects). Just tried locally, but didn&#39;t verified entire features.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin: 0in;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;As an alternate try with Nuget packages.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/2473544956409316790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2013/03/updating-microsoftdataodata-520-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2473544956409316790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2473544956409316790'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2013/03/updating-microsoftdataodata-520-to.html' title='Updating &#39;Microsoft.Data.OData 5.2.0&#39; to &#39;Microsoft.Data.OData 5.3.0&#39; failed'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-7477423335366633192</id><published>2012-08-10T17:01:00.000+05:30</published><updated>2012-08-11T18:38:36.769+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="OData"/><category scheme="http://www.blogger.com/atom/ns#" term="WCF Data Services"/><title type='text'>WCF Data Services - OData - Initial errors developers encounters</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;When authoring WCF Data Services - OData, lot of developers tries to view it in the browser during several stages of developement. Mostly they will come across the following error at initial stages.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;&lt;b&gt;The server encountered an error processing the request. See &amp;nbsp;server logs for more details.&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;When we think of creating WCF Data services, its better to have the following minimal understanding.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;b&gt;WCF Data services / OData service&lt;/b&gt; : A .Net framework component which is used to create services that uses Open Data Protocol (OData). This service exposes data through the endpoint which allows to access the data.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;b&gt;OData client libraries&lt;/b&gt; : Though not strictly required, several client libraries available for easy and effective access of OData format. Based on the client applications we create, we can make use of the respective client libraries. For example we have separate libraries for .Net, java, javascript, Silverlight, etc.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;b&gt;OData data model&lt;/b&gt; : Makes use of the exiting .Net member called Entity Data Model(EDM). &amp;nbsp;The data to be represented need to be modeled using EDM.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;b&gt;OData Protocol&lt;/b&gt; : This protocol is REST based. Defines &amp;nbsp;how the data model will be represented over the wire - either in XML based format defined by ATOM or in JSON format.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Now, let us look at the cause for the issue.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In the &lt;span style=&quot;color: #0b5394;&quot;&gt;InitializeService&lt;/span&gt; method of the svc.cs file, do ensure whether the &lt;span style=&quot;color: #0b5394;&quot;&gt;SetEntitySetAccessRule&lt;/span&gt; is specified for the respective entity and most important, the name of the entity set should be pluralized (if opted while creating the entity data model).&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Snippet 1&lt;/span&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
    // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
    // Examples:
    config.SetEntitySetAccessRule(&quot;Employees&quot;, EntitySetRights.AllRead);
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;References&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/data/hh237663.aspx&quot;&gt;http://msdn.microsoft.com/en-us/data/hh237663.aspx&lt;/a&gt; (By David Chappell)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff478141.aspx&quot;&gt;http://msdn.microsoft.com/en-us/library/ff478141.aspx&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/7477423335366633192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2012/08/wcf-data-services-odata-initial-errors.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/7477423335366633192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/7477423335366633192'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2012/08/wcf-data-services-odata-initial-errors.html' title='WCF Data Services - OData - Initial errors developers encounters'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-6074097005347696200</id><published>2012-06-16T18:01:00.000+05:30</published><updated>2012-06-16T18:01:39.352+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="JSONP"/><category scheme="http://www.blogger.com/atom/ns#" term="OData"/><title type='text'>OData : Cross domain OData request using jQuery, JSONP</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;I&#39;ve been doing a POC where I had a situation to make a request to a OData Service (service which exposed the data as OData &amp;nbsp;- Open Data Protocol) using jQuery. During my initial attempt, I got an error from the web browser which is due to the same origin policy of the web browser. &amp;nbsp;Usually Client side (request from browser using javascript) cannot be allowed to make a request to a resource that exists in another domain of which HTML &amp;lt;script&amp;gt; element is an exception. In such cases JSONP (JSON with padding) and CORS (Cross Origin Resource Sharing) is made use. Among the two, JSONP requests are commonly used right now and CORS is expected to catch the mass. In this post we&#39;ll focus on the JSONP model request for OData Service.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;To get a quick idea on the need for JSONP and how that stuff works, please have a quick glimpse &lt;a href=&quot;http://en.wikipedia.org/wiki/JSONP&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. &amp;nbsp;The code snippets I represent in this post will use the &lt;a href=&quot;http://www.nerddinner.com/&quot; target=&quot;_blank&quot;&gt;Nerd Dinner&lt;/a&gt; &lt;a href=&quot;http://www.nerddinner.com/Services/OData.svc/&quot; target=&quot;_blank&quot;&gt;OData Feed&lt;/a&gt;&amp;nbsp;for easier understanding.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;After deciding to make the JSONP request, I used jQuery.ajax() method with url : http://www.nerddinner.com/Services/OData.svc/Dinners?$format=json &amp;amp; jsonpCallback option which resulted in error. Upon analyzing it, found out the error is &quot;Uncaught SyntaxError: Unexpected token : &quot; and the error is because the returned data is a simple JSON format and not wrapped with the callback method which is expected. Then I searched and found out the right format to make the OData JSONP request. The option is available as a OData query $callback.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Following are the three different alterations we can do to make a cross domain OData request using jQuery and JSONP.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 1:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: js; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;$(document).ready(function () {

    $.ajax({
        url: &#39;http://www.nerddinner.com/Services/OData.svc/Dinners?$format=json&amp;amp;$callback=nerdCallback&#39;,
        dataType: &quot;jsonp&quot;
    });
});

function nerdCallback(result) {
    //Manipulate the resultant here....
    alert(&quot;Result count : &quot; + $(result[&quot;d&quot;][&quot;results&quot;]).length);
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 2:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: js; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;$(document).ready(function () {

    $.ajax({
        url: &#39;http://www.nerddinner.com/Services/OData.svc/Dinners?$format=json&amp;amp;$callback=?&#39;,
        dataType: &quot;jsonp&quot;,
        jsonpCallback: &quot;nerdCallback&quot;
    });
});

function nerdCallback(result) {
    //Manipulate the resultant here....
    alert(&quot;Result count : &quot; + $(result[&quot;d&quot;][&quot;results&quot;]).length);
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 3:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: js; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;$(document).ready(function () {

    $.ajax({
        url: &#39;http://www.nerddinner.com/Services/OData.svc/Dinners?$format=json&amp;amp;$callback=?&#39;,
        dataType: &quot;jsonp&quot;,
        success: function (result) {
            //Manipulate the resultant here....
            alert(&quot;Result count : &quot; + $(result[&quot;d&quot;][&quot;results&quot;]).length);
        }
    });
});
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;References:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://en.wikipedia.org/wiki/JSONP&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://en.wikipedia.org/wiki/JSONP&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ee834511.aspx&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://msdn.microsoft.com/en-us/library/ee834511.aspx&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.odata.org/&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://www.odata.org/&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/6074097005347696200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2012/06/odata-cross-domain-odata-request-using.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/6074097005347696200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/6074097005347696200'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2012/06/odata-cross-domain-odata-request-using.html' title='OData : Cross domain OData request using jQuery, JSONP'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-6215096813180339618</id><published>2012-05-30T10:32:00.003+05:30</published><updated>2012-05-30T10:32:59.541+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC 3"/><title type='text'>ASP.NET MVC 3 - Effectively using Model metadata</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In ASP.NET MVC 3, most developers might have observed the&amp;nbsp;existence&amp;nbsp;of the HTML helpers - DisplayForModel and EditorForModel. This post is just to give a hint on how effectively we can use the specified HTML helpers and hence we won&#39;t have any code Snippets here.&lt;br /&gt;
&lt;br /&gt;
I frequently come across situations of creating proof of concept and several sample applications to evaluate certain implementations / metrics. In such cases, lot of time I really worried on creating a sample data entry / display page which consumes my time, because my core objective is to evaluate my target as early as possible. The&amp;nbsp;EditorForModel HTML helper in ASP.NET MVC actually saves me lot of time and help me to just focus on my target while doing such POCs.&lt;br /&gt;
&lt;br /&gt;
While doing so I thought some simple&amp;nbsp;tweaks, like a way to represent display name, order ... for the property might help me to tune my sample page further. To achieve that, I got the help of DataAnnotations / Metadata.&lt;br /&gt;
&lt;br /&gt;
Some sample requirements are&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Need to hide a column - &lt;span style=&quot;color: #0b5394;&quot;&gt;ScaffoldColumn(false)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Hidden value - &lt;span style=&quot;color: #0b5394;&quot;&gt;HiddenInput&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Display a different name - &lt;span style=&quot;color: #0b5394;&quot;&gt;Display(Name = &quot;Employee Name&quot;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Display in a custom order - &lt;span style=&quot;color: #0b5394;&quot;&gt;Display(Order=1)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Display format with different type than default - &lt;span style=&quot;color: #0b5394;&quot;&gt;DataType(DataType.MultilineText)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Using these Metadata, we can, hide a property from creating HTML elements for that, create a hidden value element for a property, display a different name than that of the property, display in a custom order we need, specify what type of HTML element and what format can be used, etc.&lt;br /&gt;
&lt;br /&gt;
Once you start explore other parameters of attributes and options, you can achieve lot of cases with minimal effort. Really its a time saving mechanism. If none of the options fits our scenario, then we can do the regular way. &amp;nbsp;&amp;nbsp;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/6215096813180339618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2012/05/aspnet-mvc-3-effectively-using-model.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/6215096813180339618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/6215096813180339618'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2012/05/aspnet-mvc-3-effectively-using-model.html' title='ASP.NET MVC 3 - Effectively using Model metadata'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-3505052849282137634</id><published>2012-04-30T18:41:00.000+05:30</published><updated>2012-04-30T18:41:15.621+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC 3"/><category scheme="http://www.blogger.com/atom/ns#" term="Dependency Injection"/><title type='text'>ASP.NET MVC 3 - Using Ninject for Dependency Injection</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;This post is to show how to implement Dependency Injection in ASP.NET MVC 3 application with simple steps. For Details on Dependency Injection (DI) please refer to my article &lt;a href=&quot;http://info.titodotnet.com/2010/08/dependency-injection.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;For the sake of simplicity and to understand the idea, I have simply specified all the classes in same project(web application here). In real time scenario this might extend to multiple class libraries based on the nature of the project.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In our example, we&#39;re targeting a Mark sheet creation with minimal and predefined data. MarkSheetController expects a MarksheetModel and the MarkSheetModel expects a MarkEvaluator which we&#39;re going to achieve with Constructor injection as follows.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Implementaiton Details&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;First we need to install the Ninject.MVC3 Nuget package using Nuget manager. For details on Nuget manager please verify my post &lt;a href=&quot;http://info.titodotnet.com/2011/08/aspnet-mvc-3-updating-and-handling.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. Upon installing the package, a file called NinjectWebCommon.cs will get created under the folder called App_Start. &amp;nbsp;In the &amp;nbsp;static method called RegisterServices, add the statement to register the dependencies with Ninject container. Following Snippets are self explanatory to understand the concept.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 1: (App_Start/NinjectWebCommon.cs =&amp;gt; NinjectWebCommon.RegisterServices())&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;private static void RegisterServices(IKernel kernel)
{
    kernel.Bind&amp;lt;IMarkSheetModel&amp;gt;().To&amp;lt;MarkSheetModel&amp;gt;();
    kernel.Bind&amp;lt;IMarkEvaluator&amp;gt;().To&amp;lt;MarkEvaluator&amp;gt;();
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In the above snippet I&#39;ve registered with Ninject that&amp;nbsp;MarkSheetModel concrete class is bound to IMarkSheetModel and MarkEvaluator concrete class is bound to&amp;nbsp;IMarkEvaluator interface. Based on this Ninject resolves the dependency by creating instance for the respective concrete class and pass it in the place of the related interface specification. Following snippet shows how we&#39;re making use of constructor injection to achieve that.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 2: (MarkSheetController - note the IMarkSheetModel parameter in the constructor)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public class MarkSheetController : Controller
{
    private IMarkSheetModel model;


    public MarkSheetController(IMarkSheetModel modelParam)
    {
        model = modelParam;
    }

    //
    // GET: /MarkSheet/

    public ActionResult Index()
    {
        model.LoadDetails();
        return View(model);
    }

}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 3: (MarkSheetController - note the IMarkEvaluator parameter in the constructor)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public class MarkSheetModel : IMarkSheetModel
{
    private IMarkEvaluator evaluator;

    public string StudentId { get; set; }
    public string StudentName { get; set; }
    public IEnumerable&amp;lt;Subject&amp;gt; SubjectList { get; set; }
    public int Total { get; private set; }
    public decimal Average { get; private set; }
    public string Grade { get; private set; }
    
    public MarkSheetModel(IMarkEvaluator evaluatorParam)
    {
        evaluator = evaluatorParam;
    }

    public void LoadDetails()
    {
        this.StudentId = &quot;S1001&quot;;
        this.StudentName = &quot;Sample&quot;;

        this.SubjectList = new List&amp;lt;Subject&amp;gt; { new Subject{ SubjectId=&quot;Sub0001&quot;, SubjectName =&quot;Sub 1&quot;, Score = 78},
        new Subject{ SubjectId=&quot;Sub0002&quot;, SubjectName =&quot;Sub 2&quot;, Score = 84},
        new Subject{ SubjectId=&quot;Sub0003&quot;, SubjectName =&quot;Sub 3&quot;, Score = 72},
        new Subject{ SubjectId=&quot;Sub0004&quot;, SubjectName =&quot;Sub 4&quot;, Score = 69}};

        this.Total = this.evaluator.CalculateTotal(this.SubjectList);
        this.Average = this.evaluator.CalculateAverage(this.SubjectList);
        this.Grade = this.evaluator.CalculateGrade(this.SubjectList);
    }

}

public interface IMarkSheetModel
{
    void LoadDetails();
    IEnumerable&amp;lt;Subject&amp;gt; SubjectList { get; set; }
    string StudentId { get; set; }
    string StudentName { get; set; }
}

public class Subject
{
    public string SubjectId { get; set; }
    public string SubjectName { get; set; }
    public int Score { get; set; }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 4:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public class MarkEvaluator : IMarkEvaluator
{
    public int CalculateTotal(IEnumerable&amp;lt;Subject&amp;gt; subjectList)
    {
        return subjectList.Sum(su =&amp;gt; su.Score);
    }

    public decimal CalculateAverage(IEnumerable&amp;lt;Subject&amp;gt; subjectList)
    {
        return Convert.ToDecimal(CalculateTotal(subjectList)) / subjectList.Count();
    }

    public String CalculateGrade(IEnumerable&amp;lt;Subject&amp;gt; subjectList)
    {
        decimal averageScore = CalculateAverage(subjectList);

        if (averageScore &amp;gt; 80)
        {
            return &quot;Grade A&quot;;
        }
        else if (averageScore &amp;gt; 70)
        {
            return &quot;Grade B&quot;;
        }
        else if (averageScore &amp;gt; 60)
        {
            return &quot;Grade C&quot;;
        }
        else
        {
            return &quot;Grade D&quot;;
        }
    }
}

public interface IMarkEvaluator
{
    decimal CalculateAverage(IEnumerable&amp;lt;Subject&amp;gt; subjectList);
    string CalculateGrade(IEnumerable&amp;lt;Subject&amp;gt; subjectList);
    int CalculateTotal(IEnumerable&amp;lt;Subject&amp;gt; subjectList);
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;While executing the above snippets, the constructor of the MarkSheetController and MarkSheetModel is supplied with the respective instance.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;References:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/ninject/ninject.web.mvc/wiki/MVC3&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;https://github.com/ninject/ninject.web.mvc/wiki/MVC3&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/3505052849282137634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2012/04/aspnet-mvc-3-using-ninject-for.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/3505052849282137634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/3505052849282137634'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2012/04/aspnet-mvc-3-using-ninject-for.html' title='ASP.NET MVC 3 - Using Ninject for Dependency Injection'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-290553248118485569</id><published>2012-03-30T12:00:00.000+05:30</published><updated>2012-03-30T12:00:09.308+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC 3"/><title type='text'>ASP.NET MVC 3 - Converting / Serializing .Net objects into JSON format in View</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In ASP.NET MVC often we might need to use / manipulate Model objects or its property inside the javascript. In order to achieve that, we usually try to serialize the .Net object and store it in a javascript variable which will then be accessed further in javascript.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Using Razor view engine, we can achieve this easily. In the following, I&#39;ll explain two approaches with a simple View(.cshtml) snippet to understand the concept.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Approach 1: (Using Json.Encode(...))&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 1: (Index.cshtml)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;@model Web.POC.Models.FeedModel
@{
    ViewBag.Title = &quot;Feed viewer&quot;;
}

&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    var entries = @Html.Raw(Json.Encode(Model.FeedEntries));    
&amp;lt;/script&amp;gt;

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Approach 2: (Using JavaScriptSerializer)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 2: (Index.cshtml)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;@model Web.POC.Models.FeedModel
@{
    ViewBag.Title = &quot;Feed viewer&quot;;
}

@{
   System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
}
&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    var entries = @Html.Raw(serializer.Serialize(Model.FeedEntries));    
&amp;lt;/script&amp;gt;

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Assumptions:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;As specified, the above snippets are just to understand the concept. In that, consider that we&#39;re having a model &quot;FeedModel&quot; which holds a property called &quot;FeedEntries&quot; of some custom type which we&#39;re trying to convert into JSON object.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Also note that we need to use the HTML.Raw() to indicate that the output should not be HTML encoded.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/290553248118485569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2012/03/aspnet-mvc-3-converting-serializing-net.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/290553248118485569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/290553248118485569'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2012/03/aspnet-mvc-3-converting-serializing-net.html' title='ASP.NET MVC 3 - Converting / Serializing .Net objects into JSON format in View'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-6464747624564924108</id><published>2012-03-12T13:22:00.000+05:30</published><updated>2012-03-12T14:22:04.962+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><title type='text'>ASP.NET - Avoid multiple postbacks for control set using validators by disabling the button</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In ASP.NET disabling the button when a postback got initiated through button click and avoiding multiple postbacks or submits until the specific response is processed is one of the common thing that we need to implement. This is especially &amp;nbsp;needed for some long running operations. During my initial days, I achieve this as specified &lt;a href=&quot;http://info.titodotnet.com/2007/10/avoid-multiple-submits-during-ongoing.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. Later, I followed as specified &lt;a href=&quot;http://dailydotnettips.com/2011/02/07/disabling-button-when-performing-some-operation-in-asp-net/#more-482&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; in an article by Abhijit Jana. Few days back one of my friend asked me about how to disbale the button to avoid multiple submits / postbacks for control set that are using ASP.NET validation. To achieve that, I tried a sample and came up with two approaches.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Let us consider a scenario that we have a text box, a required field validator and button tied together using validation group.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Approach 1: (Using jQuery and a button proxy)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Apply CSS style=&quot;display:none;&quot; &amp;nbsp;to the button you want to disable.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Include a new button for display purpose and add a jQuery that validates the validation group using the function Page_ClientValidate() passing the validationgroup as parameter.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Based on the return value of Page_ClientValidate(), raise the click event of the hidden button using jQuery and disable the display button.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The following script snippet helps us to achieve that.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 1:(script)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    $(document).ready(function () {
        initAction();
    });

    function initAction() {
        $(&#39;#Button2&#39;).click(function (event) {
            event.preventDefault();

            if (Page_ClientValidate(&#39;ValGroup1&#39;)) {
                this.disabled = true;
                $(&#39;#Button1&#39;).click();
            }

        });
    }
&amp;lt;/script&amp;gt;

&lt;/pre&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Here is the full implementation of the same.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 2:(DisableButtonOnClickApp1.aspx)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;&amp;lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeFile=&quot;DisableButtonOnClickApp1.aspx.cs&quot;
    Inherits=&quot;DisableButtonOnClickApp1&quot; %&amp;gt;

&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&amp;gt;
&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&amp;gt;
&amp;lt;head runat=&quot;server&quot;&amp;gt;
    &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;
        &amp;lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-1.7.1.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
        $(document).ready(function () {
            initAction();
        });

        function initAction() {
            $(&#39;#Button2&#39;).click(function (event) {
                event.preventDefault();

                if (Page_ClientValidate(&#39;ValGroup1&#39;)) {
                    this.disabled = true;
                    $(&#39;#Button1&#39;).click();
                }

            });
        }
    &amp;lt;/script&amp;gt;

&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;form id=&quot;form1&quot; runat=&quot;server&quot;&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;td&amp;gt;
                    &amp;lt;asp:Label ID=&quot;Label1&quot; runat=&quot;server&quot; Text=&quot;Label 1 : &quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;
                &amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;
                    &amp;lt;asp:TextBox ID=&quot;TextBox1&quot; runat=&quot;server&quot; ValidationGroup=&quot;ValGroup1&quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;
                    &amp;lt;asp:RequiredFieldValidator ID=&quot;RequiredFieldValidator1&quot; runat=&quot;server&quot; ErrorMessage=&quot;RequiredFieldValidator&quot;
                        ControlToValidate=&quot;TextBox1&quot; ValidationGroup=&quot;ValGroup1&quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;
                &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot;&amp;gt;
                    &amp;lt;asp:Button ID=&quot;Button1&quot; runat=&quot;server&quot; Text=&quot;Hide Button&quot; Style=&quot;display: none;&quot;
                        ValidationGroup=&quot;ValGroup1&quot; onclick=&quot;Button1_Click&quot; /&amp;gt;
                    &amp;lt;asp:Button ID=&quot;Button2&quot; runat=&quot;server&quot; Text=&quot;Display Button&quot; /&amp;gt;
                &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;tr&amp;gt;
            &amp;lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot;&amp;gt;
                &amp;lt;asp:Label ID=&quot;StatusMessageLabel&quot; runat=&quot;server&quot; Text=&quot;&quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;
            &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
        &amp;lt;/table&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 3:(DisableButtonOnClickApp1.aspx.cs)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public partial class DisableButtonOnClickApp1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        StatusMessageLabel.Text = &quot;Button 1 click .......&quot;;
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;If you are not much interested in using one additional control to achieve this, the following approach might help you.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Approach 2: (Using&amp;nbsp;GetPostBackEventReference with PostBackOptions and UseSubmitBehavior&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The idea for this approach evolved from the &lt;a href=&quot;http://dailydotnettips.com/2011/02/07/disabling-button-when-performing-some-operation-in-asp-net/#more-482&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt; I specified above. Following snippets helps you to understand the implementation easily. Here we&#39;re going to use&amp;nbsp;ClientScript.&lt;/span&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;GetPostBackEventReference with PostBackOptions and Button.UseSubmitBehavior to achieve the resultant.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 4: (&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;DisableButtonOnClickApp2.aspx.cs&lt;/b&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public partial class DisableButtonOnClickApp2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        DisableButtonOnClick(Button1, &quot;ValGroup1&quot;);
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        StatusMessageLabel.Text = &quot;button 1 click......&quot;;
    }

    private void DisableButtonOnClick(Button buttonControl, string validationGroup)
    {
        StringBuilder disableButtonScriptBuilder = new StringBuilder();
        PostBackOptions postBackOptions = new PostBackOptions(buttonControl);

        postBackOptions.ValidationGroup = validationGroup;
        postBackOptions.Argument = &quot;&quot;;
        postBackOptions.PerformValidation = true;
        postBackOptions.ActionUrl = &quot;&quot;;
        postBackOptions.TrackFocus = false;
        postBackOptions.ClientSubmit = false;
        postBackOptions.RequiresJavaScriptProtocol = true;

        disableButtonScriptBuilder.Append(ClientScript.GetPostBackEventReference(postBackOptions, false));
        disableButtonScriptBuilder.Append(&quot;; if(Page_ClientValidate(&#39;&quot;);
        disableButtonScriptBuilder.Append(validationGroup);
        disableButtonScriptBuilder.Append(&quot;&#39;)){this.value=&#39;Processing...&#39;;this.disabled = true;}&quot;);

        //buttonControl.OnClientClick = ClientScript.GetPostBackEventReference(postBackOptions, false) + &quot;; if(Page_ClientValidate(&#39;&quot; + validationGroup + &quot;&#39;)){this.value=&#39;Processing...&#39;;this.disabled = true;}&quot;;
        buttonControl.OnClientClick = disableButtonScriptBuilder.ToString();
        buttonControl.UseSubmitBehavior = false;
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 5: (&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;DisableButtonOnClickApp2.aspx&lt;/b&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;&amp;lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeFile=&quot;DisableButtonOnClickApp2.aspx.cs&quot; Inherits=&quot;DisableButtonOnClickApp2&quot; %&amp;gt;

&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&amp;gt;

&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&amp;gt;
&amp;lt;head runat=&quot;server&quot;&amp;gt;
    &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;form id=&quot;form1&quot; runat=&quot;server&quot;&amp;gt;
    &amp;lt;div&amp;gt;
    &amp;lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;td&amp;gt;
                    &amp;lt;asp:Label ID=&quot;Label1&quot; runat=&quot;server&quot; Text=&quot;Label 1 : &quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;
                &amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;
                    &amp;lt;asp:TextBox ID=&quot;TextBox1&quot; runat=&quot;server&quot; ValidationGroup=&quot;ValGroup1&quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;
                    &amp;lt;asp:RequiredFieldValidator ID=&quot;RequiredFieldValidator1&quot; runat=&quot;server&quot; ErrorMessage=&quot;RequiredFieldValidator&quot;
                        ControlToValidate=&quot;TextBox1&quot; ValidationGroup=&quot;ValGroup1&quot;&amp;gt;&amp;lt;/asp:RequiredFieldValidator&amp;gt;
                &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot;&amp;gt;
                    &amp;lt;asp:Button ID=&quot;Button1&quot; runat=&quot;server&quot; Text=&quot;Button&quot; onclick=&quot;Button1_Click&quot; /&amp;gt;
                &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;tr&amp;gt;
            &amp;lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot;&amp;gt;
                &amp;lt;asp:Label ID=&quot;StatusMessageLabel&quot; runat=&quot;server&quot; Text=&quot;&quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;
            &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
        &amp;lt;/table&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Based on your comfort, use any of the above two approaches.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;REFERENCES&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://dailydotnettips.com/2011/02/07/disabling-button-when-performing-some-operation-in-asp-net/#more-482&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://dailydotnettips.com/2011/02/07/disabling-button-when-performing-some-operation-in-asp-net/#more-482&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/6464747624564924108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2012/03/aspnet-avoid-multiple-postbacks-for.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/6464747624564924108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/6464747624564924108'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2012/03/aspnet-avoid-multiple-postbacks-for.html' title='ASP.NET - Avoid multiple postbacks for control set using validators by disabling the button'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-1204776503008607230</id><published>2012-02-23T09:52:00.000+05:30</published><updated>2012-02-23T09:54:31.145+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight"/><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight 4"/><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight 5"/><title type='text'>Unauthorized access exception when value set for property using Secondary Thread - Silverlight</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Thinking about threading in Silverlight 4, we choose between the two options&lt;/span&gt;&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Background worker&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Managing thread manually&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Most of the time-consuming operations will be handled using the Background worker without blocking the UI. It ultimately executes in a separate thread. The main functions and events to know in Background worker are &lt;span style=&quot;color: #0b5394;&quot;&gt;DoWork&lt;/span&gt;, &lt;span style=&quot;color: #0b5394;&quot;&gt;RunWorkerCompleted &lt;/span&gt;and &lt;span style=&quot;color: #0b5394;&quot;&gt;RunWorkerAsync&lt;/span&gt;. As the name specifies we need to add the event handler for &lt;span style=&quot;color: #0b5394;&quot;&gt;DoWork &lt;/span&gt;event for doing the background operation. Add the handler for &lt;span style=&quot;color: #0b5394;&quot;&gt;RunWorkerCompleted &lt;/span&gt;to receive the operation completed notification. &amp;nbsp;&lt;span style=&quot;color: #0b5394;&quot;&gt;RunWorkerAsync &lt;/span&gt;method is to start the operation. The main thing to note is that we should not access directly access the UI objects from the &lt;span style=&quot;color: #0b5394;&quot;&gt;DoWork &lt;/span&gt;event.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Also there are times where we need to manage the threads manually. Since Silverlight runs in a Single threaded apartment (STA) application model and the default is the UI thread, accessing the UI objects from other thread leads to cross thread exception. Knowing this fact I worked with a secondary thread and updated a property in my ViewModel. In that scenario I got an exception and digging into the inner exception found out the cross thread exception. For understanding I&#39;ve created a sample scenario that raises exception.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public partial class ThreadTest : UserControl, INotifyPropertyChanged
{        
    private string textValue;
    public string TextValue
    {
        get { return textValue; }
        set
        {
            textValue = value;
            NotifyPropertyChanged(&quot;TextValue&quot;);
        }
    }

    public ThreadTest()
    {
        InitializeComponent();

        InitControls();
    }

    private void InitControls()
    {
        this.DataContext = this;
    }

    private void Direct_Click(object sender, RoutedEventArgs e)
    {
        TextValue = &quot;direct text......&quot;;
    }

    private void UsingTask_Click(object sender, RoutedEventArgs e)
    {
        Thread secondaryThread = new Thread(SecondaryThreadWorker);
        secondaryThread.Start();
        
    }

    private void SecondaryThreadWorker()
    {
        TextValue = &quot;thread text.......&quot;;            
    }


    #region INotifyPropertyChanged Members

    protected void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Then examining the cause, realized that the specific property raises an property changed notification . Immediately recalled the excellent &lt;a href=&quot;http://10rem.net/blog/2012/01/10/threading-considerations-for-binding-and-change-notification-in-silverlight-5&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt; from Pete Brown in his 10rem.net blog.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The following implementation does the trick.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 2 (Just replace the INotifyPropertyChanged implementation)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;#region INotifyPropertyChanged Members

protected void NotifyPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        if (Deployment.Current.Dispatcher.CheckAccess())
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        else
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =&amp;gt;
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            });
        }
    }
}

public event PropertyChangedEventHandler PropertyChanged;

#endregion
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;When I typed &quot;&lt;span style=&quot;color: #0b5394;&quot;&gt;Deployment.Current.Dispatcher.&lt;/span&gt;&quot;, it didn&#39;t show up the &quot;&lt;span style=&quot;color: #0b5394;&quot;&gt;CheckAccess()&lt;/span&gt;&quot; method in the intellisense. But I verified it in the object which shows the existence of the method. So I manually typed the &amp;nbsp;&quot;&lt;span style=&quot;color: #0b5394;&quot;&gt;CheckAccess()&lt;/span&gt;&quot;&amp;nbsp;method name and got complied without error.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://10rem.net/blog/2012/01/10/threading-considerations-for-binding-and-change-notification-in-silverlight-5&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://10rem.net/blog/2012/01/10/threading-considerations-for-binding-and-change-notification-in-silverlight-5&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/1204776503008607230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2012/02/unauthorized-access-exception-when.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/1204776503008607230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/1204776503008607230'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2012/02/unauthorized-access-exception-when.html' title='Unauthorized access exception when value set for property using Secondary Thread - Silverlight'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-2991065759363817276</id><published>2012-02-06T11:37:00.000+05:30</published><updated>2012-02-06T11:37:18.200+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC 3"/><category scheme="http://www.blogger.com/atom/ns#" term="AsyncController"/><title type='text'>ASP.NET MVC 3 - Accessing Session inside Task of AsyncController</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Before getting into the core of this post, let us have a quick look at Async controller. The base thing that we need to understand is that, Async controllers are implemented to achieve the efficient service of the incoming requests rather than faster processing of individual request. Scenarios like the case of having a network call which consumes some time might block the thread (that is processing the current request) from processing other requests. For understanding the need for using the AsyncController, there exists several articles over the web. One such nicely explained article is &lt;a href=&quot;http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In order to implement the Async controller, we need to do the following.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Derive the controller from AsyncController.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Specify an &amp;lt;ActionName&amp;gt;Async and &amp;lt;ActionName&amp;gt;Completed methods for each Actions, where &amp;lt;ActionName&amp;gt;Async is of return type void and the relevant &amp;lt;ActionName&amp;gt;Completed returns the ActionResult.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Usually the network calls will be made in the &amp;lt;ActionName&amp;gt;Async method and the resultant is passed over to the &amp;lt;ActionName&amp;gt;Completed method as arguments.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Above specified info are fine enough to implement the Async controller. Apart from that, we also need to think of effectively handling the network calls and other time consuming items inside the &amp;lt;ActionName&amp;gt;Async method. In real case, usually we&#39;ll call the method in Model / ViewModel which then initiates the network call, &amp;nbsp;call to the Service Locator or Service Agent. For achieving this, we can alter the Model / ViewModel to expose the relevant methods async mode. Instead we can also seek help from the .Net built in library named &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd537609.aspx&quot; target=&quot;_blank&quot;&gt;Task Parallel Library (TPL)&lt;/a&gt;. Instead of explaining further, I directly dive into the code sample from which you can easily understand the base.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 1:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public void IndexAsync(int id)
{
    AsyncManager.OutstandingOperations.Increment();

    Task.Factory.StartNew(() =&amp;gt; {
        InfoViewModel moreViewModel = new InfoViewModel();
        InfoViewModel.MoreModel moreModel = moreViewModel.GetDetails(id);

        AsyncManager.Parameters[&quot;moreModel&quot;] = moreModel;
        AsyncManager.OutstandingOperations.Decrement();
    });
    
}

public ActionResult IndexCompleted(InfoViewModel.MoreModel moreModel)
{
    return View(&quot;Info&quot;, moreModel);
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The AsyncManager related operations specified in the above code helps us to achieve handling of &amp;nbsp;aysnc operations effectively. For example, the Increment(), Decrement() methods and Parameters property helps the controller to identify, when to make the call to relevant &amp;lt;ActionName&amp;gt;Completed method with specific parameters. As you guess, the Task.Factory.StartNew(Action) will be executed in a separate thread and in the mean time, statements following it got executed and waits until the AsyncManager.OutstandingOperations becomes zero after which &amp;lt;ActionName&amp;gt;Completed gets called.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;OK, now comes the core of the post. Think of a situation where we need to use access the Session values inside the method of Model / ViewModel which is initiated from Task.Factory.StartNew(Action). &amp;nbsp;Since the Task is executed in a separate thread, that thread won&#39;t hold the HttpContext that is System.Web.HttpContext.Current will be null. To make it work, we can assign the System.Web.HttpContext.Current with the HttpContext got from ControllerContext as follows.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 2:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;System.Web.HttpContext.Current = ControllerContext.HttpContext.ApplicationInstance.Context;

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Please note that the above specified fix is just a workaround. For such scenarios, we need to alter the method in the Model in such a way to receive the value retrieved from session as one of the parameter.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;As we might use this repeatedly, we can create a base class and make use it in places wherever required.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 3: (BaseAsyncController)&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public class BaseAsyncController : AsyncController
{
    protected void StartContextEnabledTask(Action action)
    {
        Task.Factory.StartNew(() =&amp;gt; {
            System.Web.HttpContext.Current = ControllerContext.HttpContext.ApplicationInstance.Context;
            action();
        });
    }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 4: (Full Implementation)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public class InfoController : BaseAsyncController
{
    public void IndexAsync(int id)
    {
        AsyncManager.OutstandingOperations.Increment();
    
        StartContextEnabledTask(() =&amp;gt; {
            InfoViewModel moreViewModel = new InfoViewModel();
            InfoViewModel.MoreModel moreModel = moreViewModel.GetDetails(id);
    
            AsyncManager.Parameters[&quot;moreModel&quot;] = moreModel;
            AsyncManager.OutstandingOperations.Decrement();
        });
        
    }
    
    public ActionResult IndexCompleted(InfoViewModel.MoreModel moreModel)
    {
        return View(&quot;Info&quot;, moreModel);
    }    
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;References:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx&quot;&gt;http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd537609.aspx&quot;&gt;http://msdn.microsoft.com/en-us/library/dd537609.aspx&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://craigcav.wordpress.com/2010/12/23/asynchronous-mvc-using-the-task-parallel-library/&quot;&gt;http://craigcav.wordpress.com/2010/12/23/asynchronous-mvc-using-the-task-parallel-library/&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/2991065759363817276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2012/02/aspnet-mvc-3-accessing-session-inside.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2991065759363817276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2991065759363817276'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2012/02/aspnet-mvc-3-accessing-session-inside.html' title='ASP.NET MVC 3 - Accessing Session inside Task of AsyncController'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-4650188315107032626</id><published>2011-12-21T22:32:00.000+05:30</published><updated>2011-12-21T22:32:08.778+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="VS2010"/><title type='text'>Upgrading Nuget 1.5 to 1.6 - Installation error</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;If you have the Nuget 1.5 extension installed, your Visual Studio (VS 2010) will prompt to update to Nuget 1.6 version. If you try to update to Nuget 1.6, you might run into installation error. If so, uninstall the older version - Nuget 1.5 and then try installing the new version - Nuget 1.6. In order to uninstall Nuget, you need to run the VS 2010 in &quot;administrator&quot; mode.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;For more details view the release notes &lt;a href=&quot;http://docs.nuget.org/docs/release-notes/nuget-1.6&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/4650188315107032626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2011/12/upgrading-nuget-15-to-16-installation.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/4650188315107032626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/4650188315107032626'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2011/12/upgrading-nuget-15-to-16-installation.html' title='Upgrading Nuget 1.5 to 1.6 - Installation error'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-7916999171922964125</id><published>2011-12-19T10:47:00.001+05:30</published><updated>2011-12-19T10:47:54.537+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>C# extension method - OrderBy sort expression as string</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Recently I came across a question in a forum where a part of the solution requires the sort expression as string type for the OrderBy extension method. The requirement is, upon passing a string of property name&amp;nbsp;separated&amp;nbsp;by comma, the respective sort need to be applied and returned.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Without explaining further, directly I dive into the implementation so that you can easily infer from that. I altered the snippet got from &lt;a href=&quot;http://www.extensionmethod.net/Details.aspx?ID=124&quot;&gt;http://www.extensionmethod.net/Details.aspx?ID=124&lt;/a&gt;&amp;nbsp;based on our needs. &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 1 (Core extension method for OrderBy and ThenBy)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public static class IEnumerableExtensions
{
    public static IOrderedEnumerable&amp;lt;T&amp;gt; OrderBy&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, string sortExpression)
    {
        sortExpression += &quot;&quot;;
        string[] parts = sortExpression.Split(&#39; &#39;);
        bool descending = false;
        string property = &quot;&quot;;

        if (!(parts.Length &amp;gt; 0 &amp;amp;&amp;amp; parts[0] != &quot;&quot;))
        {
            throw new Exception(&quot;Invalid sort expression.&quot;);
        }

        property = parts[0];

        if (parts.Length &amp;gt; 1)
        {
            descending = parts[1].ToLower().Contains(&quot;esc&quot;);
        }

        PropertyInfo prop = typeof(T).GetProperty(property);

        if (prop == null)
        {
            throw new Exception(&quot;No property &#39;&quot; + property + &quot;&#39; in + &quot; + typeof(T).Name + &quot;&#39;&quot;);
        }

        if (descending)
            return list.OrderByDescending(x =&amp;gt; prop.GetValue(x, null));
        else
            return list.OrderBy(x =&amp;gt; prop.GetValue(x, null));
    }

    public static IOrderedEnumerable&amp;lt;T&amp;gt; ThenBy&amp;lt;T&amp;gt;(this IOrderedEnumerable&amp;lt;T&amp;gt; list, string sortExpression)
    {
        sortExpression += &quot;&quot;;
        string[] parts = sortExpression.Split(&#39; &#39;);
        bool descending = false;
        string property = &quot;&quot;;

        if (!(parts.Length &amp;gt; 0 &amp;amp;&amp;amp; parts[0] != &quot;&quot;))
        {
            throw new Exception(&quot;Invalid sort expression.&quot;);
        }

        property = parts[0];

        if (parts.Length &amp;gt; 1)
        {
            descending = parts[1].ToLower().Contains(&quot;esc&quot;);
        }

        PropertyInfo prop = typeof(T).GetProperty(property);

        if (prop == null)
        {
            throw new Exception(&quot;No property &#39;&quot; + property + &quot;&#39; in + &quot; + typeof(T).Name + &quot;&#39;&quot;);
        }

        if (descending)
            return list.ThenByDescending(x =&amp;gt; prop.GetValue(x, null));
        else
            return list.ThenBy(x =&amp;gt; prop.GetValue(x, null));
    }

    public static IEnumerable&amp;lt;T&amp;gt; OrderByStringExpression&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; queryObj, string orderByProperties)
    {
        if (string.IsNullOrWhiteSpace(orderByProperties))
        {
            //throw new Exception(&quot;Invalid sort expression&quot;);
            return queryObj;
        }

        string[] orderByPropertyArray = orderByProperties.Split(new char[] { &#39;,&#39; }, StringSplitOptions.RemoveEmptyEntries);
        IOrderedEnumerable&amp;lt;T&amp;gt; orderedItem = null;

        if (orderByPropertyArray.Length &amp;gt; 0)
        {
            orderedItem = queryObj.OrderBy(orderByPropertyArray[0]);

            if (orderByPropertyArray.Length &amp;gt; 1)
            {
                for (int i = 1; i &amp;lt; orderByPropertyArray.Length; i++)
                {
                    orderedItem = orderedItem.ThenBy(orderByPropertyArray[i]);
                }

            }
        }

        return orderedItem;
    }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Snippet 2 (Example code)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;var sortResult = listInst.OrderByStringExpression(&quot;Id,Name desc&quot;);
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;As you see, each property name should be separated by comma and if required you can specify the sort mode (asc/desc) followed by a blank space with the respective parameter.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Now with the above specified method, we can pass simple comma separated string as sort expression and get the related instance sorted. This will helpful in scenarios like implementing the Repository pattern as I did &lt;a href=&quot;http://info.titodotnet.com/2011/11/n-layer-web-app-with-entity-framework.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. &amp;nbsp;Hope this helps.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.extensionmethod.net/Details.aspx?ID=124&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://www.extensionmethod.net/Details.aspx?ID=124&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/7916999171922964125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2011/12/c-extension-method-orderby-sort.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/7916999171922964125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/7916999171922964125'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2011/12/c-extension-method-orderby-sort.html' title='C# extension method - OrderBy sort expression as string'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-2373509093911462978</id><published>2011-12-04T18:45:00.001+05:30</published><updated>2011-12-04T19:14:18.190+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Windows Phone"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows Phone 7.1"/><title type='text'>Windows Phone 7.1 - Things to know about Dormant and Tombstone states</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In WP 7.1, if we click on the start button when an application is running, the application will have the &lt;span style=&quot;color: #0b5394;&quot;&gt;Deactivated&lt;/span&gt; event got fired. Usually developers will save any application state in this event handler into the application level dictionary object represented through the PhoneApplicationService.State property and make use of it in the Activated state again.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;After the &lt;span style=&quot;color: #0b5394;&quot;&gt;Deactivated&lt;/span&gt; event got invoked, the application which is in running state is moved to the &lt;span style=&quot;color: #0b5394;&quot;&gt;Dormant&lt;/span&gt; state. Most developers get this state unnoticed. In this &lt;span style=&quot;color: #0b5394;&quot;&gt;Dormant&lt;/span&gt; state, application still remain in memory but without processing happen and without application getting terminated. Based on the memory resource requirements for other applications, the application in the Dormant state has the possibility to get into the &lt;span style=&quot;color: #0b5394;&quot;&gt;Tombstone&lt;/span&gt; state. The &lt;span style=&quot;color: #0b5394;&quot;&gt;Tombstone&lt;/span&gt; state for an application represents the application as terminated, in the meantime, it holds the state info of the application. By state info we mean, the application state which is represented through the &lt;span style=&quot;color: #0b5394;&quot;&gt;PhoneApplicationService.State&lt;/span&gt; property (as specified above) and the page state which is represented through &lt;span style=&quot;color: #0b5394;&quot;&gt;PhoneApplicationPage.State&lt;/span&gt; property.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The main thing we need to notice is the reactivation scenario of an application. The application might get&amp;nbsp; reactivated from both the states directly. In both the cases, it raises the &lt;span style=&quot;color: #0b5394;&quot;&gt;Activated&lt;/span&gt; event, where we need to identify whether the application is activated from the Tombstone state. If so, we can get values from the application level state dictionary (&lt;span style=&quot;color: #0b5394;&quot;&gt;PhoneApplicationService.State&lt;/span&gt;) and make use of it. If it was from &lt;span style=&quot;color: #0b5394;&quot;&gt;Dormant&lt;/span&gt; state, we don&#39;t need to do anything as the OS automatically preserves the state.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Since both scenarios raises the &lt;span style=&quot;color: #0b5394;&quot;&gt;Activated&lt;/span&gt; event, there needs to be a mechanism to identify whether the immediate previous state is &lt;span style=&quot;color: #0b5394;&quot;&gt;Dormant&lt;/span&gt; or &lt;span style=&quot;color: #0b5394;&quot;&gt;Tombstone&lt;/span&gt; state. It is the &lt;span style=&quot;color: #0b5394;&quot;&gt;IsApplicationInstancePreserved&lt;/span&gt; property of the &lt;span style=&quot;color: #0b5394;&quot;&gt;ActivatedEventArgs&lt;/span&gt; which helps us to achieve this. As you might guess, if the &lt;span style=&quot;color: #0b5394;&quot;&gt;IsApplicationInstancePreserved&lt;/span&gt; is true then it was from &lt;span style=&quot;color: #0b5394;&quot;&gt;Dormant&lt;/span&gt; state and if it is false, then it was form &lt;span style=&quot;color: #0b5394;&quot;&gt;Tombstone&lt;/span&gt; state.&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;While debugging your application you can validate both these &lt;span style=&quot;color: #0b5394;&quot;&gt;Dormant&lt;/span&gt; and &lt;span style=&quot;color: #0b5394;&quot;&gt;Tombstone&lt;/span&gt; state scenarios by clicking on the start button of your emulator when your application is running . When you click on the start button of the emulator, by default, the application will move to the &lt;span style=&quot;color: #0b5394;&quot;&gt;Dormant&lt;/span&gt; state. If you want to validate the &lt;span style=&quot;color: #0b5394;&quot;&gt;Tombstone&lt;/span&gt; state, check the &quot;&lt;em&gt;Tombstone upon deactivation while debugging&lt;/em&gt;&quot; check box in the &lt;em&gt;Debug tab of the project properties&lt;/em&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Following snippet helps you to understand handling of &lt;span style=&quot;color: #0b5394;&quot;&gt;Dormant&lt;/span&gt; and &lt;span style=&quot;color: #0b5394;&quot;&gt;Tombstone&lt;/span&gt; states:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Snippet 1 (App.xaml.cs)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;private void Application_Launching(object sender, LaunchingEventArgs e)
{
    Debug.WriteLine(&quot;Application launching event&quot;);
}

private void Application_Activated(object sender, ActivatedEventArgs e)
{
    Debug.WriteLine(&quot;Application activated event&quot;);
    
    if (e.IsApplicationInstancePreserved)
    {
        Debug.WriteLine(&quot;Application activated from Dormant state....&quot;);
    }
    else
    {
        Debug.WriteLine(&quot;Application activated from Tombstone state.....&quot;);
    }
}

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
    Debug.WriteLine(&quot;Application deactivated event&quot;);
}

private void Application_Closing(object sender, ClosingEventArgs e)
{
    Debug.WriteLine(&quot;Application closing event&quot;);
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/2373509093911462978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2011/12/windows-phone-71-things-to-know-about.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2373509093911462978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/2373509093911462978'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2011/12/windows-phone-71-things-to-know-about.html' title='Windows Phone 7.1 - Things to know about Dormant and Tombstone states'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-9173728025102255441</id><published>2011-11-19T22:11:00.001+05:30</published><updated>2011-11-19T22:53:31.129+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight"/><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight 4"/><title type='text'>ScrollToBottom extension method in ScrollViewer - Silverlight 4</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;ScrollViewer is one among the commonly used Silverlight control. When you develop Silverlight application, at some time, you&#39;ll come across using ScrollViewer. Using ScrollViewer is straightforward in most of the cases. In some scenarios (like displaying chat history messages, stock history update), we might want to bind values to elements inside the ScrollViewer and then scroll to the bottom in order to make the latest message appear in the visible region.&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;ScrollToBottom() is one among the several extension methods available for ScrollViewer which helps us to achieve scrolling vertically to the end of the ScrollViewer content. While using this ScrollToBottom() method some developers won&#39;t see the ScrollViewer scrolls upto the bottom. So, why it is like that what need to be done to make it work? Let us dive into the implementation of ScrollToBottom() method and find out the solution.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Snippet 1: (ScrollToBottom() implementation)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public static void ScrollToBottom(this ScrollViewer viewer)
{
    if (viewer == null)
    {
        throw new ArgumentNullException(&quot;viewer&quot;);
    }

    viewer.ScrollToVerticalOffset(viewer.ExtentHeight);
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;As most of us might guess, it scrolls the veritical offset to the height of the content inside the ScrollViewer. Actually the values for properties like ScrollViewer.ExtentHeight, ScrollViewer.VerticalOffset are not recalculated immediately. It seems that they placed such restrictions due to performance considerations.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;We can force to recalculate and update values of related properties by calling the&amp;nbsp;UpdateLayout() method of the ScrollViewer. Anyhow be sure to call the UpdateLayout() only required. Please view the remarks section &lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.updatelayout(v=vs.95).aspx&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt; at msdn documentation.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Ultimately, calling the UpdateLayout() method on the ScrollViewer before ScrollToBottom() is called will solve the obstacle.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Following is a sample snippet to help you understand the above specified scenario. Try executing the following snippet and inspect the value of ExtentHeight(and related properties) property by inserting the breakpoint in the call to UpdateLayout() method.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Snippet 2:&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;ScrollViewerTest.xaml&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;&amp;lt;UserControl x:Class=&quot;TestSilverlightApplication1.ScrollViewerTest&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable=&quot;d&quot;
    d:DesignHeight=&quot;500&quot; d:DesignWidth=&quot;500&quot;&amp;gt;
    &amp;lt;Grid Background=&quot;DeepSkyBlue&quot;&amp;gt;
        &amp;lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;SkyBlue&quot; Height=&quot;300&quot; Width=&quot;400&quot;&amp;gt;
            &amp;lt;Grid.RowDefinitions&amp;gt;
                &amp;lt;RowDefinition&amp;gt;&amp;lt;/RowDefinition&amp;gt;
                &amp;lt;RowDefinition Height=&quot;Auto&quot;&amp;gt;&amp;lt;/RowDefinition&amp;gt;
                &amp;lt;RowDefinition Height=&quot;70&quot;&amp;gt;&amp;lt;/RowDefinition&amp;gt;
                &amp;lt;RowDefinition Height=&quot;Auto&quot;&amp;gt;&amp;lt;/RowDefinition&amp;gt;
                &amp;lt;RowDefinition Height=&quot;70&quot;&amp;gt;&amp;lt;/RowDefinition&amp;gt;
                &amp;lt;RowDefinition&amp;gt;&amp;lt;/RowDefinition&amp;gt;
            &amp;lt;/Grid.RowDefinitions&amp;gt;
            &amp;lt;StackPanel&amp;gt;
                &amp;lt;TextBlock Text=&quot;ScrollToBottom Check&quot; HorizontalAlignment=&quot;Center&quot; FontWeight=&quot;Bold&quot; &amp;gt;&amp;lt;/TextBlock&amp;gt;

            &amp;lt;/StackPanel&amp;gt;
            &amp;lt;TextBlock Grid.Row=&quot;1&quot; Text=&quot;Enter multiline text here......&quot;&amp;gt;&amp;lt;/TextBlock&amp;gt;
            &amp;lt;ScrollViewer Grid.Row=&quot;2&quot;&amp;gt;
                &amp;lt;TextBox AcceptsReturn=&quot;True&quot; Text=&quot;{Binding SampleTextString, Mode=TwoWay}&quot;&amp;gt;&amp;lt;/TextBox&amp;gt;
            &amp;lt;/ScrollViewer&amp;gt;
            &amp;lt;Button Content=&quot;...and click here....&quot; Click=&quot;ScrollDownCheck_Click&quot; Width=&quot;150&quot; Grid.Row=&quot;3&quot; Margin=&quot;10&quot;&amp;gt;&amp;lt;/Button&amp;gt;
            &amp;lt;ScrollViewer Grid.Row=&quot;4&quot; Name=&quot;TestScrollControl&quot;&amp;gt;
                &amp;lt;TextBox AcceptsReturn=&quot;True&quot; Name=&quot;TestTextBox&quot; Text=&quot;{Binding AlteredTextString}&quot;&amp;gt;&amp;lt;/TextBox&amp;gt;
            &amp;lt;/ScrollViewer&amp;gt;
        &amp;lt;/Grid&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;ScrollViewerTest.xaml.cs&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;

namespace TestSilverlightApplication1
{
    public partial class ScrollViewerTest : UserControl, INotifyPropertyChanged
    {
        public ScrollViewerTest()
        {
            InitializeComponent();
            InitControls();
        }

        private string sampleTextString;

        public string SampleTextString
        {
            get { return sampleTextString; }
            set
            {
                sampleTextString = value;
                NotifyPropertyChanged(&quot;SampleTextString&quot;);
            }
        }

        private string alteredTextString;

        public string AlteredTextString
        {
            get { return alteredTextString; }
            set
            {
                alteredTextString = value;
                NotifyPropertyChanged(&quot;AlteredTextString&quot;);
            }
        }
         
        private void ScrollDownCheck_Click(object sender, RoutedEventArgs e)
        {
            ManipulateScrollDownCheck();
        }

        private void InitControls()
        {
            this.DataContext = this;
        }

        private void ManipulateScrollDownCheck()
        {
            this.AlteredTextString = this.SampleTextString;
            //Insert breakpoint here and validate the value of 
            //ExtentHeight before and after the execution of UpdateLayout().
            TestScrollControl.UpdateLayout();
            TestScrollControl.ScrollToBottom();
        }

        #region INotifyPropertyChanged Members

        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;You can infer from the above example that the call to UpdateLayout() is made before calling ScrollToBottom() and after assinging the value to the property bound to the content(UIElement contained inside the ScrollViewer) of the ScrollViewer. Since developers will face such problem only at certain workflows, call the UpdateLayout() only when you encounter that problem.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.scrolltoverticaloffset(v=vs.95).aspx&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.scrolltoverticaloffset(v=vs.95).aspx&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.scrolltobottom.aspx&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.scrolltobottom.aspx&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://epiinfo.svn.codeplex.com/svn/Silverlight.Controls.Toolkit/Controls.Toolkit/Common/ScrollViewerExtensions.cs&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;https://epiinfo.svn.codeplex.com/svn/Silverlight.Controls.Toolkit/Controls.Toolkit/Common/ScrollViewerExtensions.cs&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/9173728025102255441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2011/11/scrolltobottom-extension-method-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/9173728025102255441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/9173728025102255441'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2011/11/scrolltobottom-extension-method-in.html' title='ScrollToBottom extension method in ScrollViewer - Silverlight 4'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-7296735396445112752</id><published>2011-11-13T16:41:00.001+05:30</published><updated>2011-11-17T22:27:08.434+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="EntityFramework4.1"/><category scheme="http://www.blogger.com/atom/ns#" term="nLayerArchitecture"/><title type='text'>n layer web app with Entity Framework 4.1/4.2 - Things to consider</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;With Entity Framework 4.1, it releases DbContext API and CodeFirst development model. It is recommended to work with DbContext which exposes the commonly used features of ObjectContext.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Creating object context in DatabaseFirst or ModelFirst approach can be done with the help of ADO.NET DbContext Genrator template in Visual Studio. To achieve that open the .edmx file and right click the base surface &amp;gt;&amp;gt; Add Code Generation Item &amp;gt;&amp;gt; Code &amp;gt;&amp;gt; ADO.NET DbContext Generator. This template is available only when you install EF 4.1 directly. If you install the EF4.1 with NuGet packages, the reference will get added but the ADO.NET DbContext Generator template won&#39;t be available. You can use NuGet packages for adding(and managing) the reference to the specific project or solution.&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Repository pattern suits best for this case, so that we can create an individual repository for each entity. For details on repository pattern please visit &lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff649690.aspx&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;msdn&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;() and &lt;/span&gt;&lt;a href=&quot;http://martinfowler.com/eaaCatalog/repository.html&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Martin Fowler&#39;s explanation&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;. Following is a&amp;nbsp;simple and common representation of repository that developers adopt&amp;nbsp;using EF4.1. Please note that following snippet is just to understand the concept.&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Snippet 1&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public class CompanyRepository: IDisposable
{
    private HSMDBEntities Context { get; set; }

    public CompanyRepository()
    {
        this.Context = new HSMDBEntities();
    }

    public void Create(Company company)
    {
        this.Context.Companies.Add(company);
        this.Context.SaveChanges();
    }

    public Company GetCompanyById(int id)
    {
        //this.Context.Companies.Load();
        //return this.Context.Companies.Where(c =&amp;gt; c.Id == id).Single();
        return this.Context.Companies.Find(id);
        
    }

    public IEnumerable&amp;lt;Company&amp;gt; GetAll()
    {
        return this.Context.Companies.ToList();
    }
    
    public void Update(Company company)
    {
        Company currentEntry = this.Context.Companies.Where(c =&amp;gt; c.Id == company.Id).First();

        //Client wins model.
        this.Context.Entry(currentEntry).CurrentValues.SetValues(company);
        this.Context.SaveChanges();
    }

    public void Remove(Company company)
    {
        Remove(company.Id);
    }

    public void Remove(int id)
    {
        Company currentEntry = this.Context.Companies.Where(c =&amp;gt; c.Id == id).Single();
        this.Context.Companies.Remove(currentEntry);
    }

    public void Dispose()
    {
        this.Context.Dispose();
    }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The above Repository snippet exposes the basic operations performed over the entity. Most of the methods are straight forward to understand and the two methods we need to&amp;nbsp;concentrate are GetCompanyById() and Update().&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;GetCompanyById()&amp;nbsp; - The DbSet&amp;lt;T&amp;gt; property of&amp;nbsp;the DbContext instance exposes a Find method which uses the primary key to find the entity. The speciality of this method is that the database will be hit only if the entity with the specific key is not found in the context. If the specific entity already got loaded, that entity will be returned upon request without hitting the database. That&#39;s why I&#39;ve commented out the default way of retrieving the entity.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Update() - Consider the following scenario. In n layer architecture, the data model/entity retrieved will be converted into domain specific model and other DTOs(Data Transfer Objects), while passing across the layer to reach the client application(like web app). Similarly the modified data from the client reaches the data tier passing several transitions, and we simply update the database with the values from client. If any other request updates some column value of the entity in the interim time, those changes won&#39;t be respected, and whatever value reaches the data tier is updated in a brutal manner. This approach is called as client wins approach which is used common among n layer web applications. I restrict myself ending this update scenario with this short detail as this discussion itself can extend as a separate article. This client wins model is achieved in the above snippet by fetching the current status from the database and overwriting&amp;nbsp;the values got from the client and continue saving it. The highlight here is the SetValues() method of the property DbPropertyValue, which assigns all the current values of individual properties with that of the properties of the parameter object supplied to it. This eradicates the great work of reassigning the individual property values explicitly.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;this.Context.Entry(currentEntry).CurrentValues.SetValues(company);


&lt;/pre&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;in the place of&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;var entityEntry = this.Context.Entry(currentEntry);
entityEntry.Property(p =&amp;gt; p.Id).CurrentValue = 1;
entityEntry.Property(p =&amp;gt; p.CompanyName).CurrentValue = &quot;Company name altered&quot;;

 
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Now comes the reason for implementing the IDisposable. The best practice regarding the creation of DbContext instance when handling with a web application is - one context instance per request. Hence in n layer web application architecture, components in other layer(most of the times will be Business components) should take the responsibility of handling the lifetime of the context. This can be achieved by handling the respective repository instance with the using construct which automatically calls the dispose method of the repository instance.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;using (CompanyRepository companyRepository = new CompanyRepository())
{
...............................
}

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In real cases a base and a generic repository will be created based on the project nature and repository&amp;nbsp; created for each entities will be extended from the base repository. At that situation the base repository class will implement the IDisposable which handles the context instance creation and its lifetime.&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;public class CompanyRepository : BaseRepository
{        
    public CompanyRepository()
        :base()
    {
        
    }

    public void Create(Company company)
    {
        this.Context.Companies.Add(company);
        this.Context.SaveChanges();
    }

    public Company GetCompanyById(int id)
    {
        //this.Context.Companies.Load();
        //return this.Context.Companies.Where(c =&amp;gt; c.Id == id).Single();
        return this.Context.Companies.Find(id);

    }

    public IEnumerable&amp;lt;Company&amp;gt; GetAll()
    {
        return this.Context.Companies.ToList();
    }

    public void Update(Company company)
    {
        Company currentEntry = this.Context.Companies.Where(c =&amp;gt; c.Id == company.Id).First();

        //Client wins model.
        this.Context.Entry(currentEntry).CurrentValues.SetValues(company);
        this.Context.SaveChanges();
    }

    public void Remove(Company company)
    {
        Remove(company.Id);
    }

    public void Remove(int id)
    {
        Company currentEntry = this.Context.Companies.Where(c =&amp;gt; c.Id == id).Single();
        this.Context.Companies.Remove(currentEntry);
    }

}

public class BaseRepository : IDisposable
{
    protected HSMDBEntities Context { get; set; }

    public BaseRepository()
    {
        this.Context = new HSMDBEntities();
    }

    public void Dispose()
    {
        this.Context.Dispose();
    }
}

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The BaseRepository also&amp;nbsp;need to be extended further. Its good to have the above things in mind while developing n layer web application.&lt;/span&gt;&amp;nbsp;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/7296735396445112752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2011/11/n-layer-web-app-with-entity-framework.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/7296735396445112752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/7296735396445112752'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2011/11/n-layer-web-app-with-entity-framework.html' title='n layer web app with Entity Framework 4.1/4.2 - Things to consider'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-3559287719250210296</id><published>2011-10-29T15:49:00.000+05:30</published><updated>2011-10-29T15:57:38.307+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net MVC 3"/><category scheme="http://www.blogger.com/atom/ns#" term="Razor"/><title type='text'>ASP.NET MVC 3 - Representing contents in Razor View</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The Razor view engine in ASP.NET MVC 3, throws error when we specify the content block directly without enclosing it in tags especially inside the coding constructs like if, for loop and so on.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Following Snippet throws error&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;@if(condition) {
    Any direct content.......
}

&lt;/pre&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;In such cases, developers usually specify tags like &amp;lt;span&amp;gt; as a workaround in order to specify the contents. But there exists two ways for directly represent this case.&lt;/span&gt;&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;@: - for indicating the characters following it are content items and usually used for representing single line content.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&amp;lt;text&amp;gt;....&amp;lt;/text&amp;gt; - entire content block is enclosed within the &amp;lt;text&amp;gt;....&amp;lt;/text&amp;gt; element and usually used for representing multi line contents.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;@if(condition) {
    &amp;lt;text&amp;gt;Multi line statement 1
    Multi line statement 1
    ..................
    Multi line statement n&amp;lt;/text&amp;gt;
}


@if(condition) {
    @:single line content goes here....
}

&lt;/pre&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;This is a straight forward feature but unexposed to several developers. It is simple but effective.&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/3559287719250210296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2011/10/aspnet-mvc-3-representing-contents-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/3559287719250210296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/3559287719250210296'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2011/10/aspnet-mvc-3-representing-contents-is.html' title='ASP.NET MVC 3 - Representing contents in Razor View'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4734008815438417747.post-9165933958298187369</id><published>2011-10-23T16:49:00.000+05:30</published><updated>2011-10-23T16:49:45.407+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>Parsing and Manipulating HTML strings - C#</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Recently I came across a situation, where I need to retrieve an HTML string created and stored by an ASP application. Upon retrieving the html string, I need to parse the string and manipulate html string by removing some deprecated attributes and us some other equivalent alternate instead. For instance the size attribute in the font element need to be replaced with css font-size attribute.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Snippet 1:&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;&amp;lt;font size=&quot;1&quot;&amp;gt;......&amp;lt;/font&amp;gt;

to 

&amp;lt;font style=&quot;font-size: 9px;&quot;&amp;gt;......&amp;lt;/font&amp;gt;

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;One additional thing we need to note here is, since we don&#39;t have any direct equivalent of the unit and value for the size attribute, I simply changed it to the expected size for the invoking applications.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Fine, now comes core of the issue about how to manipulate the HTML string. Initially I thought of using &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx&quot;&gt;regex&lt;/a&gt;. Suddenly, I remembered of the nice tool Html Agility Pack which I explored few months back. Its an HTML parser that allows us to select an HTML element and manipulate it very easily. It uses the XPath to navigate through the elements. If you don&#39;t know XPath, no problem. You can refer to examples over the net (like in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms256086.aspx&quot;&gt;msdn&lt;/a&gt; and &lt;a href=&quot;http://www.w3schools.com/xpath/xpath_syntax.asp&quot;&gt;w3schools&lt;/a&gt; ) and find the XPath that suits better your requirement in less than a minute.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Following is the code for the situation I mentioned above.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Snippet 2:&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; ruler: true; toolbar: false; smart-tabs: false;&quot;&gt;private string RestructureDeprecatedAttributes(string htmlText)
{
    HtmlDocument document = new HtmlDocument();
    HtmlNodeCollection fontNodeCollection;
    
    document.LoadHtml(htmlText);
    fontNodeCollection = document.DocumentNode.SelectNodes(&quot;//font[@size]&quot;);

    if (fontNodeCollection != null)
    {
        foreach (HtmlNode fontNode in fontNodeCollection)
        {
            HtmlAttribute sizeAttribute = fontNode.Attributes[&quot;size&quot;];

            if (!string.IsNullOrWhiteSpace(sizeAttribute.Value) &amp;amp;&amp;amp; int.Parse(sizeAttribute.Value) &amp;gt; 0)
            {
                if (sizeAttribute.Value.Equals(&quot;1&quot;))
                {
                    fontNode.SetAttributeValue(&quot;style&quot;, &quot;font-size: 9px;&quot;);
                }
                else
                {
                    fontNode.SetAttributeValue(&quot;style&quot;, &quot;font-size: 11px;&quot;);
                }
                
                fontNode.Attributes[&quot;size&quot;].Remove();
            }
        }
    }

    return document.DocumentNode.WriteTo();
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;The selectors are really powerful which allows us to select the nodes that perfectly matches our criteria. The Html Agility Pack provides several methods that supports the manipulation of HTML strings in a very easy manner. You can infer this from the above code.&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://info.titodotnet.com/feeds/9165933958298187369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://info.titodotnet.com/2011/10/parsing-and-manipulating-html-strings-c.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/9165933958298187369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4734008815438417747/posts/default/9165933958298187369'/><link rel='alternate' type='text/html' href='http://info.titodotnet.com/2011/10/parsing-and-manipulating-html-strings-c.html' title='Parsing and Manipulating HTML strings - C#'/><author><name>Tito</name><uri>http://www.blogger.com/profile/14345562180742182906</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>