tag:blogger.com,1999:blog-78193314735602895232024-03-13T22:50:21.386+05:30dotnetExpertGuide.comNandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comBlogger110125tag:blogger.com,1999:blog-7819331473560289523.post-51745057519917572142017-09-12T18:08:00.000+05:302017-10-02T17:58:53.679+05:30ASP.NET Core MVC Value Provider for Encrypted Route Parameter<p>Back in <a title="ASP.NET MVC Value Provider for encrypted query string" href="http://www.dotnetexpertguide.com/2013/01/aspnet-mvc-value-provider-for-encrypted-query-string.html">January 2013</a> & <a title="ASP.NET 4.5 Model Binding: Creating Custom Value Provider" href="http://www.dotnetexpertguide.com/2013/03/aspnet-45-model-binding-creating-custom-value-provider.html">March 2013</a>, I had published a detailed articles on this blog on how to create a custom Value Provider for <a title="Articles related to ASP.NET" href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> MVC and ASP.NET 4.5 Model Binding respectively. In normal scenario it is not required to create custom Value Provider but sometime we require to process incoming request parameter values before default value providers feed it to model binder. For e.g. in an ecommerce application encrypted invoice id is passed in as a query string parameter or route parameter so that end-user can see and download invoice without login but as invoice id is encrypted they cannot manipulate it by guessing other possible value. In such case, we can access this encrypted query string or route parameter value from within <a title="Articles related to MVC" href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a> action method and decrypt it there and utilize decrypted values. This is fairly straightforward for relatively small application with only a handful of MVC actions accepting encrypted values. But consider a use case where you have plenty of action methods which need to accept encrypted values either passed as a query string or route parameter. Here instead of decrypting it manually from within each and every MVC actions, we can create custom Value Provider (I’ve named it as CryptoValueProvider) to do the job. CryptoValueProvider should read encrypted query string or route parameter, decrypt it and feed plain decrypted value to default model binder so that we can get direct value in action parameter. Here in this article, we will see how to create custom CryptoValueProvider in <a title="Articles related to ASP.NET Core" href="http://www.dotnetexpertguide.com/search/label/ASP.NET Core">ASP.NET Core</a>.</p>
<a name='more'></a>
<p>Before we go into nitty-gritty of how CryptoValueProvider is built, here is the quick <a href="https://github.com/NandipMakwana/AspNetCoreMvcCryptoValueProvider" target="_blank">link to GitHub repo</a> with sample project and link to how to <a title="examples of CryptoValueProvider" href="https://www.nandipmakwana.com/AspNetCoreMvcCryptoValueProvider/?utm_source=deg_blog&utm_medium=referral" target="_blank">get started with example</a>.</p><p>When I started building CryptoValueProvider, I have considered three situations which is</p><ol><li>Existing default value providers and model binder should not be affected or break in any way</li><li>CryptoValueProvider should support action method with all parameters as encrypted</li></ol>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt">[CryptoValueProvider]</pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> IActionResult Example1(<span class="kwrd">int</span> param1, <span class="kwrd">string</span> param2)</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>In above Example1 action, both parameter param1 & param2 values are passed as a encrypted and it is decrypted by CryptoValueProvider on the fly right before model binding happen. </p><ol start="3"><li>CryptoValueProvider should support action method with only some of the parameters as encrypted</li></ol>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd">public</span> IActionResult Example2([FromCrypto]<span class="kwrd">int</span> secretPersonId, [FromCrypto]<span class="kwrd">string</span> secretParam2, <span class="kwrd">int</span> visibleParam1, Person person)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>Here in Example2, we can see that I have not marked method with <em>CryptoValueProvider</em> attribute instead I have marked only secretPersonId & secretParam2 with <em>FromCrypto</em> attribute. FromCrypto is a binding source metadata object representing a source of data for model binding and it is similar to FromBody, FromQuery, etc. FromCrypto essentially direct the ASP.NET Core MVC that this particular parameter must be bound through CryptoValueProvider and not other value providers even though it is passed as query string, request body, form body, etc. just ignore the other value providers.</p><p>Now that we have discussed what we are aiming to achieve with CryptoValueProvider, we will start looking into actual code.</p><h4>CryptoBindingSource.cs</h4>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CryptoBindingSource</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> BindingSource Crypto = <span class="kwrd">new</span> BindingSource(</pre><!--CRLF--><pre class="alteven"> <span class="str">"Crypto"</span>,</pre><!--CRLF--><pre class="alt"> <span class="str">"BindingSource_Crypto"</span>,</pre><!--CRLF--><pre class="alteven"> isGreedy: <span class="kwrd">false</span>,</pre><!--CRLF--><pre class="alt"> isFromRequest: <span class="kwrd">true</span>);</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>CryptoBindingSource class has read only object of BindingSource named as Crypto. We will require this Crypto object while creating CryptoValueProvider and FromCrypto parameter binding attribute.</p><h4>CryptoParamsProtector.cs</h4><p>Next required class is the one which enable us to encrypt parameters dictionary into single string which we can pass as a route parameter and decrypt it back to parameter dictionary.</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CryptoParamsProtector</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> IDataProtector _protector;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> CryptoParamsProtector(IDataProtectionProvider dataProtectionProvider)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> _protector = dataProtectionProvider.CreateProtector(GetType().FullName);</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">string</span> EncryptParamDictionary(Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> parameters)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> var paramsInSingleString = <span class="kwrd">string</span>.Join(<span class="str">"+"</span>, parameters</pre><!--CRLF--><pre class="alt"> .Select(p => <span class="kwrd">string</span>.Format(<span class="str">"{0}={1}"</span>, p.Key.ToLower(), p.Value)));</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> _protector.Protect(paramsInSingleString);</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> DecryptToParamDictionary(<span class="kwrd">string</span> encryptedParameters)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> var paramsInSingleString = <span class="kwrd">string</span>.Empty;</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">try</span></pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> paramsInSingleString = _protector.Unprotect(encryptedParameters);</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">catch</span></pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="rem">//return empty dictionary when string encryptedParameters is not protected with _protector</span></pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> <span class="kwrd">new</span> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>>();</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> paramsInSingleString.Split(<span class="str">'+'</span>)</pre><!--CRLF--><pre class="alteven"> .Select(p => p.Split(<span class="str">'='</span>))</pre><!--CRLF--><pre class="alt"> .ToDictionary(p => p[0], p => p[1]);</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>As we can see that I have used <a title="Articles related to ASP.NET Core" href="http://www.dotnetexpertguide.com/search/label/ASP.NET Core">ASP.NET Core</a> Data Protection API for the encryption/decryption purpose. More information on Data Protection API is available <a href="https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/" target="_blank">here</a>.</p><h4>CryptoValueProvider.cs</h4><p>This is actual implementation of CryptoValueProvider. We need to implement <em>IValueProvider</em> interface to create custom value provider but as we also want to support parameter level binding through <em>FromCrypto</em> attribute (implementation later in this article) hence we inherited it from BindingSourceValueProvider abstract class which can filter value provider based on binding source metadata of parameter.</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CryptoValueProvider : BindingSourceValueProvider</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">string</span> _encryptedParameters;</pre><!--CRLF--><pre class="alteven"> CryptoParamsProtector _protector;</pre><!--CRLF--><pre class="alt"> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> _values;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> CryptoValueProvider(BindingSource bindingSource, CryptoParamsProtector protector, <span class="kwrd">string</span> encryptedParameters)</pre><!--CRLF--><pre class="alteven"> : <span class="kwrd">base</span>(bindingSource)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> _encryptedParameters = encryptedParameters;</pre><!--CRLF--><pre class="alt"> _protector = protector;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">bool</span> ContainsPrefix(<span class="kwrd">string</span> prefix)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">if</span> (_values == <span class="kwrd">null</span>)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">if</span> (<span class="kwrd">string</span>.IsNullOrEmpty(_encryptedParameters))</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> _values = <span class="kwrd">new</span> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>>();</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">else</span></pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> _values = _protector.DecryptToParamDictionary(_encryptedParameters);</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> _values.ContainsKey(prefix.ToLower());</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">override</span> ValueProviderResult GetValue(<span class="kwrd">string</span> key)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">if</span> (_values.ContainsKey(key.ToLower()))</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> <span class="kwrd">new</span> ValueProviderResult(<span class="kwrd">new</span> StringValues(_values[key.ToLower()]));</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> <span class="kwrd">else</span></pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> ValueProviderResult.None;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>If we look at the third parameter of constructor, it is encrypted string. We are decrypting it with the help of CryptoParamsProtector object passed in as second parameter of constructor and storing it as dictionary. GetValue method will return plain decrypted value when invoked by model binder right before it bind the model. Hence we do not require to decrypt it from within action methods.</p><h4>CryptoValueProviderFactory.cs</h4><p>CryptoValueProvider is ready to instantiate and plug it into <a title="Articles related to ASP.NET Core" href="http://www.dotnetexpertguide.com/search/label/ASP.NET Core">ASP.NET Core</a> model binding pipeline. And it is where CryptoValueProviderFactory comes in picture.</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="lnum" id="lnum1"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">class</span> CryptoValueProviderFactory : IValueProviderFactory</pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum2"> 2:</span> {</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum3"> 3:</span> <span class="kwrd">public</span> Task CreateValueProviderAsync(ValueProviderFactoryContext context)</pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum4"> 4:</span> {</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum5"> 5:</span> var paramsProtector = (CryptoParamsProtector)context.ActionContext.HttpContext</pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum6"> 6:</span> .RequestServices.GetService(<span class="kwrd">typeof</span>(CryptoParamsProtector));</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum7"> 7:</span> </pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum8"> 8:</span> context.ValueProviders.Add(<span class="kwrd">new</span> CryptoValueProvider(CryptoBindingSource.Crypto</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum9"> 9:</span> , paramsProtector</pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum10"> 10:</span> , context.ActionContext.RouteData.Values[<span class="str">"id"</span>]?.ToString()));</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum11"> 11:</span> </pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum12"> 12:</span> <span class="kwrd">return</span> Task.CompletedTask;</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum13"> 13:</span> }</pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum14"> 14:</span> }</pre><!--CRLF--></div></div>
<p>Here when we are adding CryptoValueProvider to context at line no 8, we are passing 3 parameters as</p><ol><li>CryptoBindingSource.Crypto – this is the same read only binding source object which we created as first step in this article. This <em>Crypto</em> binding source object indicate that only CryptoValueProvider can act as an data source for parameter with <em>FromCrypto</em> attribute.</li><li>paramsProtector – it is instance of <em>CryptoParamsProtector</em> used for encryption/decryption.</li><li>Routedata.Values["id"] – here we are passing encrypted string as route parameter id hence we are reading encrypted string from route parameter id and passing it to value provider.</li></ol><p>Below is the code of ConfigureServices of Startup.cs file. We are adding CryptoValueProviderFactory at the end of existing value provider factory list hence giving default value provider a higher preference. We have also added scoped service for CryptoParamsProtector so that we can inject it in controller or through instance of IServiceProvider.</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="lnum" id="lnum1"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">void</span> ConfigureServices(IServiceCollection services)</pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum2"> 2:</span> {</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum3"> 3:</span> services.AddScoped(<span class="kwrd">typeof</span>(CryptoParamsProtector));</pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum4"> 4:</span> </pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum5"> 5:</span> services.AddMvc(mvcOptions =></pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum6"> 6:</span> {</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum7"> 7:</span> mvcOptions.ValueProviderFactories.Add(<span class="kwrd">new</span> CryptoValueProviderFactory());</pre><!--CRLF--><pre class="alteven"><span class="lnum" id="lnum8"> 8:</span> });</pre><!--CRLF--><pre class="alt"><span class="lnum" id="lnum9"> 9:</span> }</pre><!--CRLF--></div></div>
<p>We have configured CryptoValueProvider during application startup in ConfigureService. Next step is to create attribute to mark action method or method parameter.</p><h4>CryptoValueProviderAttribute.cs</h4><p>By using CryptoValueProviderAttribute we can denote that all the parameters of this action method can accept only encrypted values from route parameter or query string.</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt">[AttributeUsage(AttributeTargets.Method)]</pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> <span class="kwrd">class</span> CryptoValueProviderAttribute : Attribute, IResourceFilter</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">void</span> OnResourceExecuted(ResourceExecutedContext context)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">void</span> OnResourceExecuting(ResourceExecutingContext context)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> context.ValueProviderFactories.Clear();</pre><!--CRLF--><pre class="alt"> context.ValueProviderFactories.Add(<span class="kwrd">new</span> CryptoValueProviderFactory());</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>Here we are implementing IResourceFilter interface which allow us to implement code that can be executed just right before and immediate after model binding. Purpose of this attribute is to indicate that all the parameters are accepting only encrypted values hence we do not require default value providers and hence we are removing it from list and then adding back only CryptoValueProvider. By this way we can ensure that for this particular request processing only CryptoValueProvider is used and not other.</p><h4>FromCryptoAttribute.cs</h4><p>FromCrypto attribute is used at parameter level when data source of some of the action parameters are other than CryptoValueProvider.</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt">[AttributeUsage(AttributeTargets.Parameter)]</pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> <span class="kwrd">class</span> FromCryptoAttribute : Attribute, IBindingSourceMetadata</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> BindingSource BindingSource => CryptoBindingSource.Crypto;</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>This attribute implements IBindingSourceMetadata interface, which is used to specify data source for model binding. Here we are using same CryptoBindingSource.Crypto object which we have used in value provider factory and subsequently it is passed to BindingSourceValueProvider constructor so that it can filter CryptoValueProvider in conjunction with IBindingSourceMetadata or FromCrypto attribute here.</p><h4>Examples</h4><p>I have uploaded sample project on my <a href="https://github.com/NandipMakwana/AspNetCoreMvcCryptoValueProvider" target="_blank">GitHub repo here</a>. You can clone it and run it with Visual Studio 2017 and <a title="Articles related to ASP.NET Core" href="http://www.dotnetexpertguide.com/search/label/ASP.NET Core">ASP.NET Core</a> 2.0 installed. Here is a <a href="https://www.nandipmakwana.com/AspNetCoreMvcCryptoValueProvider/?utm_source=deg_blog&utm_medium=referral" target="_blank">link to example</a> to get started with. Below is the quick simple usage. For more example please visit <a href="https://www.nandipmakwana.com/AspNetCoreMvcCryptoValueProvider/?utm_source=deg_blog&utm_medium=referral" target="_blank">example page</a>.</p><ol><li>Create action method and mark it with CryptoValueProvider attribute or mark some of the parameter with FromCrypto attribute</li></ol>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt">[CryptoValueProvider]</pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> IActionResult Example1(<span class="kwrd">int</span> param1, <span class="kwrd">string</span> param2)</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--><pre class="alt"><span class="rem">/*OR*/</span></pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> IActionResult Example2([FromCrypto]<span class="kwrd">int</span> param1, <span class="kwrd">string</span> param2, [FromCrypto]<span class="kwrd">string</span> param3)</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<ol start="2"><li>Create parameter dictionary and encrypt it with CryptoParamsProtector</li></ol>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> HomeController : Controller</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> CryptoParamsProtector _protector;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> HomeController(CryptoParamsProtector protector)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> _protector = protector;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> IActionResult Index()</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> var paramDictionary = <span class="kwrd">new</span> Dictionary();</pre><!--CRLF--><pre class="alt"> paramDictionary.Add(<span class="str">"param1"</span>, 1234.ToString());</pre><!--CRLF--><pre class="alteven"> paramDictionary.Add(<span class="str">"param2"</span>, <span class="str">"Hello World!"</span>);</pre><!--CRLF--><pre class="alt"> ViewBag.encryptedRouteParam1 = _protector.EncryptParamDictionary(paramDictionary);</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> View();</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<ol start="3"><li>Use encrypted string as route parameter to generate link</li></ol>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><a asp-controller=<span class="str">"demo"</span> asp-action=<span class="str">"example1"</span> asp-route-id=<span class="str">"@ViewBag.encryptedRouteParam1"</span>><h4>Example 1 Demo</h4></a></pre><!--CRLF--></div></div>
Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-28942412728554153892017-05-17T01:57:00.001+05:302017-05-17T09:37:09.511+05:30C#: The request was aborted: Could not create SSL/TLS secure channel<p>Last month we noticed that crawler on which I worked earlier was unable to crawl some of the HTTPS websites. Crawler was built in C# and deployed on several environments running Windows Server 2012 R2. Crawler was running fine on all environments except one where it was unable to connect with few HTTPS websites and it kept raising below exception</p>
<blockquote><p><font size="3">The request was aborted: Could not create SSL/TLS secure channel.</font></p></blockquote>
<p>Here in this blog post, I will explain how I troubleshot to identify root cause of this exception and its possible solution.</p>
<a name='more'></a>
<p>Looking at the exception, it is clear that issue is due to SSL certificate and for some reason, server is unable to connect this particular website with HTTPS. Also as mentioned earlier that we were facing this issue in one environment or server only. Crawler was able to crawl same websites from another environment. So my first guess was that, there must be some server level configurations which is preventing connection to this website. Most probably configuration related to SSL/TLS. For e.g. website is using HTTPS certificate with unsupported or outdated protocol such as SSL 3.0 or it can be some issue with SSL certificate it self (chances of this was almost none as we were able to browse website from browser but still as I was debugging I considered all the possibilities). I fired up Visual Studio to create separate test application and run it on server.</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper">
<div class="csharpcode" id="codeSnippet"><pre class="alt"><span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">bool</span> AllwaysGoodCertificate(<span class="kwrd">object</span> sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> <span class="kwrd">true</span>;</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--><pre class="alt"><span class="kwrd">static</span> <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[] args)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;</pre><!--CRLF--><pre class="alteven"> ServicePointManager.ServerCertificateValidationCallback += <span class="kwrd">new</span> RemoteCertificateValidationCallback(AllwaysGoodCertificate);</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">var</span> httpClient = <span class="kwrd">new</span> HttpClient();</pre><!--CRLF--><pre class="alt"> <span class="rem">//other code removed</span></pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>Within test application, I enabled all the protocols, SSL 3.0 to TLS 1.2 and also attached ServerCertificateValidationCallback so that I can examine various parameter passed to callback such as certificate, if there are any SSL policy errors, etc. But in our case, exception was thrown even before it hit ServerCertificateValidationCallback. This gave me further indication that definitely it must be some server level configurations or may be bug which is preventing SSL/TLS connection. To start investigation, I opened Chrome on the server to browse same website and to my surprise it worked like a charm! But soon I realize that Chrome do not use <a title="Microsoft Schannel" href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa380123(v=vs.85).aspx" target="_blank">Microsoft Schannel</a> for it’s SSL/TLS implementation. Chrome uses <a title="BoringSSL" href="https://boringssl.googlesource.com/boringssl/" target="_blank">BoringSSL</a>, it’s own fork of OpenSSL, library. .NET framework uses Microsoft Schannel implementation, so to verify against Microsoft Schannel implementation, I fired up Internet Explorer. And as I rightly expected, IE was unable to connect with this website. It shows below error message.</p>
<p><img width="941" height="402" title="ie" class="img-responsive" style="margin: 0px auto; border: 0px currentcolor; border-image: none; float: none; display: block; background-image: none;" alt="ie" src="https://lh3.googleusercontent.com/-wsBHhE2tArQ/WRtgmX85nAI/AAAAAAAACZs/v19CtKzlYy8o7U3tADuEbjzrkZgSfNp1ACHM/ie%255B4%255D?imgmax=800" border="0"></p>
<p>It is asking to enable TLS 1.0 to TLS 1.2 in IE advanced settings and still if this error continue, it is possible that this site uses an unsupported protocol or cipher suite. Now if we look at advanced settings, TLS 1.0, 1.1 & 1.2 is already enabled</p>
<p><img width="420" height="538" title="ie option" class="img-responsive" style="margin: 0px auto; border: 0px currentcolor; border-image: none; float: none; display: block; background-image: none;" alt="ie option" src="https://lh3.googleusercontent.com/-kJrIrGLD4Gc/WRtgnbbpsuI/AAAAAAAACZw/PRGrPbzCLJUteBlKlR0pOz7Ykud2P53PwCHM/ie%2Boption?imgmax=800" border="0"></p>
<p>And also if we look at SSL certificate overview in Chrome developer tool</p>
<p><img width="463" height="374" title="ssl" class="img-responsive" style="margin: 0px auto; border: 0px currentcolor; border-image: none; float: none; display: block; background-image: none;" alt="ssl" src="https://lh3.googleusercontent.com/-Xep1osoasgY/WRtgohniRhI/AAAAAAAACZ0/Px0Xp1iTuiw3xYuKUKgadZsiLENbcCeAwCHM/ssl%255B4%255D?imgmax=800" border="0"></p>
<p>It clearly stat that this site is using strong protocol (TLS 1.2) and in previous step, we also verified that TLS 1.2 is enabled in IE settings. At this stage it looks like that SSL protocol is not the real culprit as it is already enabled on server. To further investigate, I again looked at error message (screenshot provided earlier) displayed in IE which read as</p>
<blockquote><p><font size="3">…this site uses an unsupported protocol or cipher suite…</font></p></blockquote>
<p>Also whenever we tried to open this website from IE, it added system error entry in Event Viewer with Schannel as source.</p><p><img width="714" height="123" title="event viewer" class="img-responsive" style="margin: 0px auto; float: none; display: block; background-image: none;" alt="event viewer" src="https://lh3.googleusercontent.com/-oKvrZq6v6YM/WRtgpQ1CuTI/AAAAAAAACZ4/7Y-Pqp5atS8LNB9P3r-2i9-WzeYBsGV1wCHM/event%2Bviewer%255B2%255D?imgmax=800" border="0"></p><p>As per the quoted error message earlier, either it can be unsupported protocol, which do not seem the oblivious case as it is already enabled, or it can be unsupported cipher suite. Here cipher suite caught my attention that this is something we are yet to verify. So In order to find supported cipher suite by website certificate, I analyzed website with <a title="SSL Labs online service" href="https://www.ssllabs.com/ssltest/" target="_blank">SSL Labs online service</a>.</p>
<p><img width="956" height="394" title="ssllabs" class="img-responsive" style="margin: 0px auto; float: none; display: block; background-image: none;" alt="ssllabs" src="https://lh3.googleusercontent.com/-qwjPNB_XHro/WRtgqdzMUaI/AAAAAAAACZ8/Yc7EhaZr_Bo7swv-NiGDl1XlVSKCV543gCHM/ssllabs%255B53%255D?imgmax=800" border="0"></p>
<p>My next step was to find out which all cipher suites are supported by IE or more precisely by Microsoft Schannel Client on this server and compare it with cipher suites supported by website certificate. I came across <a title="https://cc.dcsec.uni-hannover.de/" href="https://cc.dcsec.uni-hannover.de/" target="_blank">https://cc.dcsec.uni-hannover.de/</a> which list out all the cipher suites supported by browser, in our case IE and hence Microsoft Schannel Client. </p><p><img width="846" height="541" title="ie cipher suite" class="img-responsive" style="margin: 0px auto; float: none; display: block; background-image: none;" alt="ie cipher suite" src="https://lh3.googleusercontent.com/-RYR41HYzd4o/WRtgranZpCI/AAAAAAAACaA/eoWYzzKWDv8c0_4dWtjbXabCIkpbPs-vgCHM/ie%2Bcipher%2Bsuite%255B2%255D?imgmax=800" border="0"></p><p>We can clearly see that cipher suites supported by certificate is either disabled or not supported by Schannel. </p><p>While I was figuring out, how to address this, initially I believed that this issue could be due to <a title="Microsoft TLS Session Resumption bug" href="https://technet.microsoft.com/library/security/3109853.aspx" target="_blank">Microsoft TLS Session Resumption bug</a> as explained in this <a title="Cloudflare blog" href="https://blog.cloudflare.com/microsoft-tls-downgrade-schannel-bug/#part3abortingtheconnection" target="_blank">Cloudflare blog</a>. But later I found, from IT infrastructure team, that security update for this bug is already installed on server. We were unable to identify exact reason that why some cipher suites were disabled only on this server and not on another environment but to address this issue we used <a title="IIS Crypto" href="https://www.nartac.com/Products/IISCrypto" target="_blank">IIS Crypto</a> utility which give fine grain control to enable or disable protocols, ciphers, hashes and key exchange algorithms on Windows Server.</p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-41783873350416650342016-11-25T09:09:00.000+05:302016-12-06T07:18:02.713+05:30ASP.NET: Sharing OWIN Authentication Cookie across IIS Applications<p>It's been almost 3 years since I've shared my learning experience on this blog. During this past 3 years, I worked on various technology right from fixing some classic ASP pages in legacy application to ASP.NET Core, Visual Studio Team System (VSTS), Single-Sign-On (SSO) with CAS, Shibboleth, Azure AD and other related SSO technology/protocol, and much more. I'll try to post articles on some of the interesting learning experience later. But here in this post we will see how we can share OWIN authentication cookie across IIS application within same website.</p>
<a name='more'></a>
<p>Recently I was tasked with revamp of an existing intranet application. An existing application was already deployed with several modules from last year and an half. Few months back we decided to add some more modules and as a result of addition of these new proposed modules, application would become almost double in term of it's features. As application become large, it is also necessary that it maintain it’s user friendliness and end-user must not confused/struggle between so many features and it's different workflow. And this, application becoming large, was one of the key factor for revamp of existing modules. One of the major overhaul was to change entire HTML template and hence user experience & re organize existing modules url (controller action) so that admin can configure which user will have access to which module and this access can be to entire module or some of the functionality of module. As it was an intranet application to be used within organization only, application was deployed as an IIS application for e.g. http://10.0.0.1/App However we decided that this new revamped application will be deployed as another IIS application for e.g. http://10.0.0.1/AppV2 and as and when we complete migration of existing module we will move it from App to AppV2 and eventually old deployment i.e. http://10.0.0.1/App will become obsolete. Here comes our very first challenge that during this short time of transition how to share OWIN authentication cookie between these two IIS application and this post is all about how I implemented it.</p><h4>Configuring OWIN cookie authentication</h4><p>In-depth explanation of configuring OWIN cookie authentication is beyond the scope of this post. However to address our scenario, very first step is to make sure that both old and new application use cookie authentication and both application use the same name for authentication cookie. </p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> Startup</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">void</span> Configuration(IAppBuilder app)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> app.UseCookieAuthentication(<span class="kwrd">new</span> CookieAuthenticationOptions</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> AuthenticationType = <span class="str">"AppCookieName"</span>,</pre><!--CRLF--><pre class="alteven"> LoginPath = <span class="kwrd">new</span> PathString(<span class="str">"/Account/LogIn"</span>)</pre><!--CRLF--><pre class="alt"> });</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>We have to make sure that we use same cookie name in OWIN startup class while configuring authentication. Above configuration will make sure that both old and new application will redirect unauthenticated user to their respective Account/Login action. In next section we will see how to redirect new application to login page of old application.</p>
<h4>Redirection to appropriate login page</h4><p>Now we have two separate version of application, we need to make sure that when user browse either of the version old or new, it redirect to appropriate login page and after successful login it redirect back to originally requested version. Here we decided that whenever user browse new application (i.e. http://10.0.0.1/AppV2) we will redirect it to login page of older application (i.e. http://10.0.0.1/App) In older application we have login logout action as </p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd">public</span> ActionResult LogIn(<span class="kwrd">string</span> returnUrl)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> ViewBag.ReturnUrl = returnUrl;</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> View();</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> ActionResult LogOut()</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven"> AuthenticationManager.SignOut(<span class="str">"AppCookieName"</span>);</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> Redirect(<span class="str">"~/"</span>);</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>In new application we have added below app setting key</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd"><</span><span class="html">appSettings</span><span class="kwrd">></span></pre><!--CRLF--><pre class="alteven"> <span class="kwrd"><</span><span class="html">add</span> <span class="attr">key</span><span class="kwrd">="LoginUrl"</span> <span class="attr">value</span><span class="kwrd">="http://10.0.0.1/App/Account/LogIn?ReturnUrl="</span> <span class="kwrd">/></span></pre><!--CRLF--><pre class="alt"> <span class="kwrd"><</span><span class="html">add</span> <span class="attr">key</span><span class="kwrd">="LogoutUrl"</span> <span class="attr">value</span><span class="kwrd">="http://10.0.0.1/App/Account/LogOut"</span> <span class="kwrd">/></span></pre><!--CRLF--><pre class="alteven"><span class="kwrd"></</span><span class="html">appSettings</span><span class="kwrd">></span></pre><!--CRLF--></div></div>
<p>And we added below login logout action in new application</p>
<div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd">public</span> ActionResult LogIn()</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> Redirect(<span class="kwrd">string</span>.Format(<span class="str">"{0}{1}"</span>, ConfigurationManager.AppSettings[<span class="str">"LoginUrl"</span>], HttpRuntime.AppDomainAppVirtualPath));</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--><pre class="alt"><span class="kwrd">public</span> ActionResult LogOut()</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> Redirect(ConfigurationManager.AppSettings[<span class="str">"LogoutUrl"</span>]);</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>Above all code will ensure that whenever unauthenticated user browse old or new application it will always redirect to old application login page with appropriate ReturnUrl value. This ReturnUrl value is important because when user browse new application, even though login page is of old application it should redirect to new application.</p><h4>Setting Up a Machine Key</h4><p>When I started with this task actually, I was pretty sure on above two step that I have to configure same cookie name and redirect both to either old or new login page. But to be frank at that moment I was not sure how I’ll handle authentication cookie encryption/decryption. Of course we do not need to write code for this, but I was not sure how OWIN cookie authentication middleware will handle this encryption/decryption as both are separate IIS application. But as I implement above two steps, I remember that earlier for other project when we implemented round robin load balancer, we kept machine key in sync across servers. Bottom line is we also need to use same machine key for both old and new deployment. Below is the minimal web.config changes to set custom machine key.</p><div class="csharpcode-wrapper" id="codeSnippetWrapper"><div class="csharpcode" id="codeSnippet">
<pre class="alt"><span class="kwrd"><</span><span class="html">system.web</span><span class="kwrd">></span></pre><!--CRLF--><pre class="alteven"> <span class="kwrd"><</span><span class="html">machineKey</span> <span class="attr">decryptionKey</span><span class="kwrd">="85F7ABF05FD7713140FB4A6E1A402F68FDCC0330CED20080"</span> <span class="attr">validationKey</span><span class="kwrd">="BA4C9F70AB3AC0A6CB2AF7753982378244269374CDE3C5A7BA07F78583CF882551D5144C4425D10C05AA96701AA1A0680E318DD99C4D14AAB4A780E0783E60D0"</span> <span class="kwrd">/></span></pre><!--CRLF--><pre class="alt"><span class="kwrd"></</span><span class="html">system.web</span><span class="kwrd">></span></pre><!--CRLF--></div></div><p>Please do not use above machine key and keep your machine key private and backed up in case for security and recovery. </p><p>We can also generate machine key from IIS. To generate machine key, select website or IIS application, in our case select old IIS application from left pane and open Machine Key</p><p><img width="586" height="254" title="Machine Key" class="img-responsive" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="1" src="https://lh3.googleusercontent.com/-hI9N72ZAxWY/WDex2lzfR5I/AAAAAAAACVE/O00hnprm_C0/1%25255B14%25255D.png?imgmax=800" border="0"></p>
<p>Now click on Generate Keys on Right pane and it should generate Machine Keys for selected website/IIS application. Copy and paste it to new application web.config and we are done.</p><p><img width="550" height="418" title="Machine Key" class="img-responsive" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="2" src="https://lh3.googleusercontent.com/-CYk3jHkNqCE/WDex3JxrctI/AAAAAAAACVI/_xx6wEQCot0/2%25255B4%25255D.png?imgmax=800" border="0"></p>
<p>Now our both application can share authentication cookie. Hope this post helpful! </p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-61577967351452935522014-02-27T02:06:00.000+05:302014-07-13T21:15:42.519+05:30Visual Studio 2013: New ASP.NET Project with Windows Azure Site<p>Yesterday Microsoft released Visual Studio 2013 Update 2 CTP2 along with Team Foundation Server 2013 Update 2 RC and TypeScript 1.0 RC. More detail of the same can be found on <a target="_blank" href="http://blogs.msdn.com/b/somasegar/archive/2014/02/25/visual-studio-2013-update-2-ctp2.aspx">Somasegar's blog here</a>.</p>
<p>As far as web development is concerns, this preview update includes, support for SASS, JSON project item and editor, ASP.NET Scaffolding, One ASP.NET Template changes. Complete list of web development enhancement can be <a target="_blank" href="http://blogs.msdn.com/b/webdev/archive/2014/02/25/announcing-new-web-features-in-visual-studio-2013-update-2-ctp2.aspx">found here</a>.</p>
<p>As far as this blog post is concern, we will see step by step guide on how to create remote azure resource while creating new web project in Visual Studio 2013. At the end of tutorial, we will also see how we can edit any file of remote azure site from Visual Studio itself. Before we continue please download & install this preview update <a target="_blank" rel="nofollow" href="http://go.microsoft.com/fwlink/?LinkId=390521">from here</a>. Once you install, we are ready for step by step tutorial as follow!</p>
<a name='more'></a>
<p>Ahh wait... If you have not subscribed to Azure service then you can subscribe for <a target="_blank" rel="nofollow" href="http://www.windowsazure.com/en-us/pricing/free-trial/">free trial from here</a>.</p>
<h4>Create Windows Azure Site while Creating New Project in Visual Studio 2013</h4>
<p>Open Visual Studio 2013 & create new web project. In New ASP.NET Project dialog, right bottom side you will find windows azure settings. Check the Create remote resources & click on Show Settings.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-du6PL1Ksalk/Uw5Kyu3cIMI/AAAAAAAABoQ/WUJmhQVkAMU/s1600/2.+VS2013+new+project+options.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-du6PL1Ksalk/Uw5Kyu3cIMI/AAAAAAAABoQ/WUJmhQVkAMU/s1600/2.+VS2013+new+project+options.png" /></a></div>
<p>If you have not connected windows azure accounts from Visual Studio then it will show an authentication error as in above image. Click on Configure these settings. It will open Configure Windows Azure Site Settings dialog.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-uIJdE-xJQHo/Uw5Ky1nKPnI/AAAAAAAABoM/vZ5TGkOrTck/s1600/3.+Configure+new+azure+website+in+VS2013.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-uIJdE-xJQHo/Uw5Ky1nKPnI/AAAAAAAABoM/vZ5TGkOrTck/s1600/3.+Configure+new+azure+website+in+VS2013.png" /></a></div>
<p>Click on Sign In... button & it will ask you to sign into windows azure account.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-oh6wBED-wTM/Uw5KzLolIpI/AAAAAAAABoY/3F6ZGvHQv7U/s1600/4.+Sign+in+to+windows+azure.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-oh6wBED-wTM/Uw5KzLolIpI/AAAAAAAABoY/3F6ZGvHQv7U/s1600/4.+Sign+in+to+windows+azure.png" /></a></div>
<p>Once you sign into Azure account, New ASP.NET Project dialog will display azure resource detail such as site name, database name, location.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-21tMWYvdiLE/Uw5Kzhamc4I/AAAAAAAABoc/Ens-c0NAxDI/s1600/5.+Project+option+dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-21tMWYvdiLE/Uw5Kzhamc4I/AAAAAAAABoc/Ens-c0NAxDI/s1600/5.+Project+option+dialog.png" /></a></div>
<p>To customize this azure site settings, click on Configure these settings, it will open site settings dialog where you can select azure subscription, configure database, location, etc.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-KVxdtFDIpBo/Uw5Kz9uh93I/AAAAAAAABok/d5MftpvfMfg/s1600/6.+Fill+azure+website+configuration.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-KVxdtFDIpBo/Uw5Kz9uh93I/AAAAAAAABok/d5MftpvfMfg/s1600/6.+Fill+azure+website+configuration.png" /></a></div>
<p>Once you configure remote azure resource, click on ok to create new web project. Along with project creation on your local machine, it will also create configured remote azure resource and you can see status in Web Publish Activity as displayed in below image.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-o0bs5ECPbpc/Uw5K0G47Z4I/AAAAAAAABpE/Fs8MN7ydits/s1600/7.+Web+publish+activity.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-o0bs5ECPbpc/Uw5K0G47Z4I/AAAAAAAABpE/Fs8MN7ydits/s1600/7.+Web+publish+activity.png" /></a></div>
<p>As we have created remote azure resource for this web project, so it has also created pre-configured publish profile with these azure resource. Unlike web project without azure resource, when we publish this project it will directly pick pre-configured publish profile and publish wizard directly jump to last step as we can see in below image.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-zkxWWAXc66U/Uw5K0ePIyGI/AAAAAAAABos/zQK35Im47Hs/s1600/8.+Publish+dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-zkxWWAXc66U/Uw5K0ePIyGI/AAAAAAAABos/zQK35Im47Hs/s1600/8.+Publish+dialog.png" /></a></div>
<p>Click on Publish & we are done with publishing to azure site & database!</p>
<h4>Editing File on Azure Site</h4>
<p>Once we publish our site to azure, we can edit remote file right from Visual Studio. To edit remote azure site file, open Server Explorer and expand Windows Azure node as in below image.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-mnzvjSyBPTI/Uw5K0l1xR_I/AAAAAAAABo0/peXU1Ye0UzU/s1600/9.+Azure+website+explorer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-mnzvjSyBPTI/Uw5K0l1xR_I/AAAAAAAABo0/peXU1Ye0UzU/s1600/9.+Azure+website+explorer.png" /></a></div>
<p>Here we can click on any (text) file and it will download & open in Visual Studio.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-RnAV3B8U1kg/Uw5Kx-P14TI/AAAAAAAABoA/JBioxU7YzDk/s1600/10.+Azure+site+editing+in+VS2013.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-RnAV3B8U1kg/Uw5Kx-P14TI/AAAAAAAABoA/JBioxU7YzDk/s1600/10.+Azure+site+editing+in+VS2013.png" /></a></div>
<p>Once we edit this remote file and try to save it again, it will show confirmation dialog that This will save your changes to Windows Azure.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-88w__vdj-C8/Uw5Kx_n7UuI/AAAAAAAABn0/jt-_vxEdlKg/s1600/11.+Remote+save+confirm+dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-88w__vdj-C8/Uw5Kx_n7UuI/AAAAAAAABn0/jt-_vxEdlKg/s1600/11.+Remote+save+confirm+dialog.png" /></a></div>
<p>Click on Save Changes...</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-00qVunc0H5Q/Uw5KyJtjYKI/AAAAAAAABn4/lp1An03rJeY/s1600/12.+Saving+to+azure+website.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-00qVunc0H5Q/Uw5KyJtjYKI/AAAAAAAABn4/lp1An03rJeY/s1600/12.+Saving+to+azure+website.png" /></a></div>
<p> ... & it will save changes to Windows Azure.</p>
<p>Hope this quick post will help. Stay tuned for next post till then check out my post <a href="http://www.dotnetexpertguide.com/2013/10/step-by-step-guide-on-creating-Publishing-Monitoring-Windows-Azure-Website-from-Visual-Studio-2013.html">Step by Step Guide: Create, Publish & Monitor a Windows Azure Website from Visual Studio 2013</a>.</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-68512799865046949712013-11-23T18:15:00.000+05:302013-11-23T21:32:27.861+05:30IIS: Enable Compression for HTTP 1.0 Request<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-SsWHgKujqmI/UpCfZjLeghI/AAAAAAAABks/5CoqnY10ucI/s1600/iis+icon.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="http://3.bp.blogspot.com/-SsWHgKujqmI/UpCfZjLeghI/AAAAAAAABks/5CoqnY10ucI/s200/iis+icon.jpg" width="147" /></a></div>
<p>Recently I was integrating Amazon CloudFront CDN in this blog. During the integration I found that default IIS configuration do not compress static resource when requested with HTTP 1.0. So in this quick & short post we will see how to enable static resource compression for HTTP 1.0 request in IIS.</p>
<a name='more'></a>
<p>In amazon, I have configured IIS 8.0 as a custom origin server and uploaded static resource over there. During configuration I noticed that CloudFront endpoint was serving an un-compressed static resource I was bit surprise because in CloudFront documentation, it is mentioned that it will forward request header to origin server as well response header back to requestor/client i.e. web browser here. To verify, I opened fiddler and requested static resource directly from origin server i.e. IIS 8.0. As I assumed IIS returned compressed response and appropriate response header. I was bit puzzled where to configure CloudFront to serve compressed resource as in CloudFront console I do not find any specific settings related to compression because as per documentation it was as easy as forwarding request header to origin server and forwarding response header back to requestor.</p>
<p>Suddenly I decided to look into IIS log and I found that Amazon CloudFront uses HTTP 1.0 to request custom origin server.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-jk7xDH-c5Kg/UpCglZTTnWI/AAAAAAAABlA/07CJu920-VU/s1600/IIS.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-jk7xDH-c5Kg/UpCglZTTnWI/AAAAAAAABlA/07CJu920-VU/s1600/IIS.png" /></a></div>
<p>I did not expected HTTP 1.0 request here so once again I requested origin server with HTTP 1.0 using fiddler and as a surprise IIS returned un-compressed response. In IIS by default compression for HTTP 1.0 request is disabled. We need to explicitly enable compression for HTTP 1.0 request. To Enable compression for HTTP 1.0 request we need to change web.config as below.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><configuration></pre><!--CRLF--><pre class="alteven"> <system.webServer></pre><!--CRLF--><pre class="alt"> <httpCompression noCompressionForHttp10=<span class="str">"false"</span> noCompressionForProxies=<span class="str">"false"</span>></httpCompression></pre><!--CRLF--><pre class="alteven"> </system.webServer></pre><!--CRLF--><pre class="alt"></configuration></pre><!--CRLF--></div></div>
<p>After changing web.config as above, IIS started to server compressed response for HTTP 1.0. Hope this quick and short post would be helpful!</p>
<p>Read all post on <a href="http://www.dotnetexpertguide.com/2011/10/iis-7-tutorial-posts-link.html">IIS Configuration here</a>.<i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-24413838533519605512013-11-17T20:14:00.000+05:302013-11-17T23:53:53.346+05:30[Updated] ASP.NET Web Optimization Framework & Cookieless Domain<p>In last week, one reader of this blog <a target="_blank" href="https://twitter.com/XqShimron/status/400506623954649088">asked on twitter</a> how to use Scripts.Render & Styles.Render with cookieless domain. Ahh wait... Still if you have not read my original post then please first read how to setup <a href="http://www.dotnetexpertguide.com/2012/10/aspnet-mvc-4-cookieless-domain-for-bundling-and-static-resources.html">ASP.NET & MVC 4: Cookieless domain for bundling and static resources</a>. Earlier in that post I have explained for both static & bundled resource but in that post I have used HTML Link & Script tag to serve bundled resource from static domain. Because Scripts.Render & Styles.Render generate Script & Link tag same as requested domain whereas in case of static domain Script & Link tag should not refer to requested domain but it should refer static domain. Here in this post we will see how to configure ASP.NET Web Optimization framework to use cookieless domain with Scripts.Render & Style.Render.</p>
<a name='more'></a>
<h4>Why Scripts.Render & Styles.Render?</h4>
<p>In general it really does not matter whether we use Script tag or Scripts.Render for bundled script. But yes Scripts.Render provide more control over ASP.NET Web Optimization framework. Two important of them is listed below.</p>
<ul>
<li><b>Whether Debugging is Enabled or not</b> Scripts.Render & Styles.Render check whether debugging is enable or not and accordingly it generate bundled url or individual Scripts or Link tag for each file in bundle.</li>
<li><b>Bundle Optimizations is Enabled or not</b> Same way Scripts.Render & Styles.Render also check whether Optimizations is enabled or not and if it is enabled then it will generate bundled url and if it is disabled then it will generate separate Link & Script tag for each file in bundle.</li>
</ul>
<h4>Configure ASP.NET Web Optimization framework to use Cookieless Domain with Scripts.Render & Styles.Render</h4>
<p>With earlier version of ASP.NET Web Optimization framework it was not possible to override default tag template for bundled scripts and styles so it was always referring requested domain while using Scripts.Render & Styles.Render. But in later version (1.1.2 when I'm writing this post) it is possible to override default tag template and hence we can override it to refer static domain with Scripts.Render & Styles.Render. So below is the steps to achieve the same.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-lr99iueezuI/UojP7MOaN8I/AAAAAAAABkc/vmFjm9VooXo/s1600/Snap+2013-11-17+at+18.30.27.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-lr99iueezuI/UojP7MOaN8I/AAAAAAAABkc/vmFjm9VooXo/s1600/Snap+2013-11-17+at+18.30.27.png" /></a></div>
<ul>
<li>Make sure that latest version (1.1.2 when I'm writing this) of ASP.NET Web Optimization framework installed. If earlier version is installed then first uninstall older version and then install latest version again.</li>
<li>Once latest version is installed open BundleConfig.cs and modify it to include overridden tag template as explained below.</li>
</ul>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> BundleConfig</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> RegisterBundles(BundleCollection bundles)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> Styles.DefaultTagFormat = <span class="str">"<link href='http://static.domain.com{0}' rel='stylesheet'/>"</span>;</pre><!--CRLF--><pre class="alteven"> Scripts.DefaultTagFormat = <span class="str">"<script src='http://static.domain.com{0}'></script>"</span>;</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>Yeah you are right. We have done! Here we are overriding default tag template so that whenever Scripts.Render & Styles.Render is used it will render static domain.</p>
<h4>Allowing Bundled & Original Files to Serve from Static Domain.</h4>
<p>Original article already explain how to allow Bundled & Static resource through static domain then also let me post more detailed code snippet. Below code snippet show bundle configuration.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> RegisterBundles(BundleCollection bundles)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> bundles.Add(<span class="kwrd">new</span> ScriptBundle(<span class="str">"~/bundles/custom"</span>).Include(</pre><!--CRLF--><pre class="alteven"> <span class="str">"~/Scripts/script1.js"</span>,</pre><!--CRLF--><pre class="alt"> <span class="str">"~/Scripts/script2.js"</span>));</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>And below updated code snippet show how to allow bundled url (i.e. ~/bundles/custom) and original files (i.e. ~/Scripts/script1.js, ~/Scripts/script2.js ) through Cookieless domain. For complete setup please first read <a href="http://www.dotnetexpertguide.com/2012/10/aspnet-mvc-4-cookieless-domain-for-bundling-and-static-resources.html">original article here</a>.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> StaticResource : IHttpModule</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">void</span> Init(HttpApplication context)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> context.BeginRequest += <span class="kwrd">new</span> EventHandler(context_BeginRequest);</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">void</span> context_BeginRequest(<span class="kwrd">object</span> sender, EventArgs e)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> HttpContext context = HttpContext.Current;</pre><!--CRLF--><pre class="alt"> <span class="kwrd">string</span> strUrl = context.Request.Url.OriginalString.ToLower();</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> List<<span class="kwrd">string</span>> allowedUrls = <span class="kwrd">new</span> List<<span class="kwrd">string</span>>();</pre><!--CRLF--><pre class="alteven"> allowedUrls.Add(<span class="str">"/bundles/"</span>); <span class="rem">// FOR BUNDLED RESOURCE</span></pre><!--CRLF--><pre class="alt"> allowedUrls.Add(<span class="str">"/scripts/"</span>); <span class="rem">// FOR ORIGINAL FILES</span></pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="rem">//HERE WE CAN CHECK IF REQUESTED URL IS FOR STATIC OR BUNDLED RESOURCE OR NOT</span></pre><!--CRLF--><pre class="alteven"> <span class="kwrd">if</span> (allowedUrls.Any(u => strUrl.Contains(u)) == <span class="kwrd">false</span>)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">string</span> strMainDomain = ConfigurationManager.AppSettings[<span class="str">"MainDomain"</span>];</pre><!--CRLF--><pre class="alt"> context.Response.Redirect(strMainDomain);</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">void</span> Dispose()</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<h4>Reference</h4>
<ul>
<li><a href="http://www.dotnetexpertguide.com/2012/10/aspnet-mvc-4-cookieless-domain-for-bundling-and-static-resources.html">ASP.NET & MVC 4: Cookieless domain for bundling and static resources</a></li>
<li><a href="http://www.dotnetexpertguide.com/2013/04/aspnet-web-optimization-framework-article-series.html">ASP.NET Web Optimization Framework (Bundling & Minification) Articles</a></li>
</ul>
<p>Hope this helpful! <i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-55614365384388627312013-10-21T02:40:00.000+05:302014-07-13T21:15:23.720+05:30Step by Step Guide: Create, Publish & Monitor a Windows Azure Website from Visual Studio 2013<p>With the release of Visual Studio 2013, now we can Create, Publish & Monitor Windows Azure websites from within Visual Studio itself without opening Windows Azure portal. So far it was possible to publish directly Azure website from Visual Studio 2012 but with this release it is even easier to create & monitor Azure website from within Visual Studio. All you require is only to have Windows Azure Subscription. If you have not subscribed to Azure service then you can subscribe for <a href="http://www.windowsazure.com/en-us/pricing/free-trial/" target="_blank">free trial from here</a>. This whole post is divided in three sections, <b>Creating Azure Website, Publishing to Azure Website & Monitoring Azure Website</b> from Visual Studio 2013.</p>
<a name='more'></a>
<h4>Creating Azure Website</h4>
<p>To create new Azure Website, open Server Explorer and right click on Windows Azure node and click on <b>Import Subscriptions…</b></p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-N12Zg5lv5Kc/UmRAilyhnLI/AAAAAAAABiQ/MqQUzeFW5HI/s1600/1.+Import+Windows+Azure+Subscriptions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-N12Zg5lv5Kc/UmRAilyhnLI/AAAAAAAABiQ/MqQUzeFW5HI/s1600/1.+Import+Windows+Azure+Subscriptions.png" /></a></div>
<p>In Import Subscription dialog box click on <b>Download subscription file</b>. It will open Windows Azure Portal and download configuration file. Browse to downloaded file and click on Import.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-aPX1PSIFVk8/UmRAkqd9viI/AAAAAAAABjE/xG_SW402aHk/s1600/2.+Download+Subscription+File.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-aPX1PSIFVk8/UmRAkqd9viI/AAAAAAAABjE/xG_SW402aHk/s1600/2.+Download+Subscription+File.png" /></a></div>
<p>Clicking on Import button, it will import subscription detail. Here we can manage Mobile Service, SQL Database, and Website on Azure. To create new Azure Website, right click on Web Sites node and click on <b>Add New Site…</b></p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-lwr9tgfWLt0/UmRAk8WHkRI/AAAAAAAABjA/wc24yYACZ8A/s1600/3.+Add+New+Windows+Azure+Web+Site.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-lwr9tgfWLt0/UmRAk8WHkRI/AAAAAAAABjA/wc24yYACZ8A/s1600/3.+Add+New+Windows+Azure+Web+Site.png" /></a></div>
<p>In Create Site on Windows Azure dialog, Provide necessary website detail and click on Create.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1VulreDgGus/UmRAlpdMVdI/AAAAAAAABjc/vc7gy0Uf3x0/s1600/4.+Create+Web+Site+On+Windows+Azure.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-1VulreDgGus/UmRAlpdMVdI/AAAAAAAABjc/vc7gy0Uf3x0/s1600/4.+Create+Web+Site+On+Windows+Azure.png" /></a></div>
<p>It will take few minute to create & configure website on Azure. Now right click on newly created website in Server Explorer and click on <b>Open in Browser</b>.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-5gWnQZL08sE/UmRAl9MmzvI/AAAAAAAABjY/YX2tCt-Pkz0/s1600/5.+Windows+Azure+Web+Site+Settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-5gWnQZL08sE/UmRAl9MmzvI/AAAAAAAABjY/YX2tCt-Pkz0/s1600/5.+Windows+Azure+Web+Site+Settings.png" /></a></div>
<p>It will open browser and we can see default homepage for newly created website as displayed in below image.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-KeUlfUYb2vc/UmRAmRFt8-I/AAAAAAAABjg/OrmCzspY47A/s1600/6.+Azure+Web+Site+Preview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="440" src="http://1.bp.blogspot.com/-KeUlfUYb2vc/UmRAmRFt8-I/AAAAAAAABjg/OrmCzspY47A/s640/6.+Azure+Web+Site+Preview.png" width="640" /></a></div>
<p>So our Azure website is up with just few clicks in Visual Studio. Now it’s time to learn how to publish ASP.NET application directly to Azure server.</p>
<h4>Publishing to Azure Website</h4>
<p>To create and configure One ASP.NET project in Visual Studio 2013, <a href="http://www.dotnetexpertguide.com/2013/10/visual-studio-2013-getting-started-with-one-aspnet.html">read my post here</a>. Once application is ready then, right click on ASP.NET application and click on <b>Publish…</b></p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-_RHhpT1lEyU/UmRAm4Nwu8I/AAAAAAAABj4/Q7njQsgcLfU/s1600/7.+Publish+Web.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="502" src="http://3.bp.blogspot.com/-_RHhpT1lEyU/UmRAm4Nwu8I/AAAAAAAABj4/Q7njQsgcLfU/s640/7.+Publish+Web.png" width="640" /></a></div>
<p>It will bring Publish wizard. Click on Import button and select Windows Azure website from dropdown and click on OK.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-IdJExwPetpA/UmRAm7y0AiI/AAAAAAAABjw/su6fuw8gd30/s1600/8.+Import+Windows+Azure+Web+Site+Publish+Settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-IdJExwPetpA/UmRAm7y0AiI/AAAAAAAABjw/su6fuw8gd30/s1600/8.+Import+Windows+Azure+Web+Site+Publish+Settings.png" /></a></div>
<p>It will fetch necessary detail for web deployment in publish wizard.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Svrp3HnD6yk/UmRAnV2IyiI/AAAAAAAABj0/QjXQ9_bDf_Q/s1600/9.+Publish+Web+Site+Settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="500" src="http://3.bp.blogspot.com/-Svrp3HnD6yk/UmRAnV2IyiI/AAAAAAAABj0/QjXQ9_bDf_Q/s640/9.+Publish+Web+Site+Settings.png" width="640" /></a></div>
<p>Clicking on <b>Publish</b> button start publishing to Azure server. It can take few minute. Once publish is completed. We can open website in browser to verify whether it is published successfully or not.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-cmFMs5nUlek/UmRAjKc3YdI/AAAAAAAABiY/JfG97x7-bo8/s1600/10.+Azure+Web+Site+Preview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="440" src="http://1.bp.blogspot.com/-cmFMs5nUlek/UmRAjKc3YdI/AAAAAAAABiY/JfG97x7-bo8/s640/10.+Azure+Web+Site+Preview.png" width="640" /></a></div>
<p>So we are done with publishing our website to Azure server. In next section, we will examine how we can monitor Azure Website from within Visual Studio.</p>
<h4>Monitoring Azure Website</h4>
<p>To monitor Azure website, right click on website and click on <b>View Settings</b>.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-_sdy1g0nOAk/UmRAiy1Gd6I/AAAAAAAABiU/YSHr5L5-Cmo/s1600/11.+Windows+Azure+Web+Site+Settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-_sdy1g0nOAk/UmRAiy1Gd6I/AAAAAAAABiU/YSHr5L5-Cmo/s1600/11.+Windows+Azure+Web+Site+Settings.png" /></a></div>
<p>It will open website setting panel, here we can manage & configure Azure website. For e.g. start/stop/restart website, configuring framework version, enabling logging on Azure website. We can also open Windows Azure portal directly from here.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-7O51Swo9NBE/UmRAjfyFhJI/AAAAAAAABiw/hhVf9ndKQ9U/s1600/12.+Configure+Windows+Azure+Web+Site.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-7O51Swo9NBE/UmRAjfyFhJI/AAAAAAAABiw/hhVf9ndKQ9U/s1600/12.+Configure+Windows+Azure+Web+Site.png" /></a></div>
<p>To monitor website, enable logging as highlighted in above image. After enabling logging move to <b>Logs</b> tab in settings panel.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-63kJZn0xvBg/UmRAjueGifI/AAAAAAAABio/6d4vPDSlGEI/s1600/13.+Configure+Log.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-63kJZn0xvBg/UmRAjueGifI/AAAAAAAABio/6d4vPDSlGEI/s1600/13.+Configure+Log.png" /></a></div>
<p>Here we can download logs detail by clicking on <b>Download Logs</b>. For real time website monitoring click on <b>Stream Logs</b>.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-nMJvEmh0Z78/UmRAj2Hm_xI/AAAAAAAABis/tHxGzLwEYqk/s1600/14.+Log+Stream+Settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="http://1.bp.blogspot.com/-nMJvEmh0Z78/UmRAj2Hm_xI/AAAAAAAABis/tHxGzLwEYqk/s640/14.+Log+Stream+Settings.png" width="640" /></a></div>
<p>It will open Output window. As highlighted in above image, click on setting button in output window and select <b>All Logs</b> so that output window start capturing and display real time log of Azure website. To see real time log in action, start capturing log as described above and visit 2-3 pages of newly created and published Azure website and observe output window.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-QPmOWeopHjU/UmRAkugFK-I/AAAAAAAABjI/z_MYLIBJlzc/s1600/15.+Output+Log.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://1.bp.blogspot.com/-QPmOWeopHjU/UmRAkugFK-I/AAAAAAAABjI/z_MYLIBJlzc/s640/15.+Output+Log.png" width="640" /></a></div>
<p>Here we can see that output window is capturing and displaying website log in real time manner.</p>
<p>Hope this detailed post would be helpful!</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-16194437835063118632013-10-20T08:50:00.000+05:302013-11-06T18:39:52.060+05:30Visual Studio 2013 : Getting Started with One ASP.NET Project<p>Day before yesterday Microsoft released Visual Studio 2013. Visual Studio 2013 is shipped with new version of ASP.NET which focuses on One ASP.NET goal. With One ASP.NET, now developer can add MVC and/or Web API controller in Web Form application or vice-versa. This newer version of ASP.NET also include an update to ASP.NET MVC 5, Razor 3, ASP.NET Web API 2, Entity Framework 6 and SignalR 2. Here in this quick post, we will see how to configure project and theme with One ASP.NET.</p>
<p>Yeah still if you have not installed Visual Studio 2013, first <a target="_blank" href="http://www.microsoft.com/visualstudio/eng/downloads">download it from here</a> and get it installed.</p>
<a name='more'></a>
<p>Create new project and here in new project dialog we can notice that unlike previous version of Visual Studio, here is only one project type under web category. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-xXLnjRayfuY/UmNHz-UXlNI/AAAAAAAABh4/YXBZ9T0cSVA/s1600/1.+New+Project.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="388" src="http://4.bp.blogspot.com/-xXLnjRayfuY/UmNHz-UXlNI/AAAAAAAABh4/YXBZ9T0cSVA/s640/1.+New+Project.png" width="640" /></a></div>
<p>So where is other project type? As mentioned earlier, new version of ASP.NET focuses on One ASP.NET goal hence now onward it will be considered as ASP.NET application which is referencing one or more framework including Web Forms, ASP.NET MVC, ASP.NET Web API, etc. Click on OK to create new project.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-fpHofv7oTjw/UmNHw-k9lTI/AAAAAAAABhU/DzAZjiAcnp4/s1600/2.+Configure+Project.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="425" src="http://1.bp.blogspot.com/-fpHofv7oTjw/UmNHw-k9lTI/AAAAAAAABhU/DzAZjiAcnp4/s640/2.+Configure+Project.png" width="640" /></a></div>
<p>In the next dialog, you can select template whether it will be Web Forms, MVC, etc and can select multiple framework reference to add in project. We can also add unit test project in the solution. Apart from template & core framework reference, we can configure authentication also. Click on Change Authentication.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-UNwTAWW2irE/UmNHwnzHBNI/AAAAAAAABhQ/BmvREgS2-2c/s1600/3.+Authentication.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="306" src="http://3.bp.blogspot.com/-UNwTAWW2irE/UmNHwnzHBNI/AAAAAAAABhQ/BmvREgS2-2c/s640/3.+Authentication.png" width="640" /></a></div>
<p>Here we can configure authentication for this project. Authentication could be Individual User Accounts or Windows Authentication or it could be Organizational Accounts leveraging Windows Azure Active Directory or On Premises setup. Select appropriate authentication method and click on OK.</p>
<p>New project template leverage Bootstrap 3 for responsive layout. Run application and see how it looks in desktop browser</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-IM1OGrrBEqE/UmNHxji-6AI/AAAAAAAABhg/YlqztDwaf-A/s1600/4.+Desktop+Site.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="447" src="http://2.bp.blogspot.com/-IM1OGrrBEqE/UmNHxji-6AI/AAAAAAAABhg/YlqztDwaf-A/s640/4.+Desktop+Site.png" width="640" /></a></div>
<p>and how it is scaled to fit in mobile or tablet device.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-r-DkjJXYxXE/UmNHyYUyhxI/AAAAAAAABhk/r5T1t_0Ow0k/s1600/5.+Mobile+Site.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="398" src="http://3.bp.blogspot.com/-r-DkjJXYxXE/UmNHyYUyhxI/AAAAAAAABhk/r5T1t_0Ow0k/s400/5.+Mobile+Site.png" width="400" /></a></div>
<p>Bootstrap 3 comes with <a target="_blank" rel="nofollow" href="http://getbootstrap.com/components/">various components</a>. One of the great advantage of using Bootstrap is that it is themeable and we can create our theme. One of the nice tool I found is <a target="_blank" rel="nofollow" href="http://pikock.github.io/bootstrap-magic/">pikock.github.io/bootstrap-magic/</a> Otherwise, you will also find plenty of free theme availble. <a target="_blank" rel="nofollow" href="http://Bootswatch.com">Bootswatch.com</a> is of the website from where we can download free bootstrap theme.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-bDhuqIRaCMo/UmNHzHLf_lI/AAAAAAAABh8/Z06jKYki114/s1600/6.+Bootswatch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="194" src="http://3.bp.blogspot.com/-bDhuqIRaCMo/UmNHzHLf_lI/AAAAAAAABh8/Z06jKYki114/s400/6.+Bootswatch.png" width="400" /></a></div>
<p>Download bootstrap.css and replace it with one in content directory of project and refresh browser to see it in action. Here we do not require to download .less files for theme. It is only required if we are planning to customize this theme.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-RwqgugEOGmY/UmNHzSlHFMI/AAAAAAAABhw/XV9_lxErubo/s1600/7.+Updated+Theme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="446" src="http://4.bp.blogspot.com/-RwqgugEOGmY/UmNHzSlHFMI/AAAAAAAABhw/XV9_lxErubo/s640/7.+Updated+Theme.png" width="640" /></a></div>
<p>Ahh we can see new them applied!</p>
<p>Hope this quick post would be helpful and stay tuned for more post on One ASP.NET!</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-22168713225168179762013-09-01T23:13:00.000+05:302013-11-06T18:39:21.169+05:30ASP.NET: Detecting User/Browser Languages<p>Multilingual application, provide a way, so that user can select preferable language and application adopt culture based on selected language. But intelligent web application should auto detect user browser language and accordingly adopt culture settings for application. In this quick & short post, we will see how to detect user or browser language in ASP.NET application.</p>
<a name='more'></a>
<p><a href="http://msdn.microsoft.com/en-us/library/system.web.httprequest.userlanguages.aspx" target="_blank">Request.UserLanguages</a> return a array of string consisting list of languages set in user browser. We can use Request.UserLanguages in ASP.NET application, to determine user's preferable language. Below is the code snippet for the same.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> InitializeCulture()</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> CultureInfo cul;</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">try</span></pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> cul = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">catch</span></pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> cul = CultureInfo.CreateSpecificCulture(<span class="str">"en-US"</span>);</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> System.Threading.Thread.CurrentThread.CurrentCulture = cul;</pre><!--CRLF--><pre class="alt"> System.Threading.Thread.CurrentThread.CurrentUICulture = cul;</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>In above code snippet, we are using try catch to set en-US as fallback language in case culture initialization fail. Some browser client allow user to set custom language header. In such case culture initialization may fail.</p>
<h4>How Request.UserLanguages Is Populated?</h4>
<p>We have utilized Request.UserLanguages to determine user's preferable language but it is nice to also know that how Request.UserLanguages values is populated. To check it out, first let add one additional language in browser.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-ZO_wt3JZC0k/UiN6V7mBLYI/AAAAAAAABfw/qjMlDbumzGI/s1600/1.+Chrom+Language+Settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-ZO_wt3JZC0k/UiN6V7mBLYI/AAAAAAAABfw/qjMlDbumzGI/s1600/1.+Chrom+Language+Settings.png" /></a></div>
<p>We have added Gujarati language and setting its preference higher than other two language. Now request any webpage and examine Accept-Language request header.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-vJnOdVqTBC0/UiN6Vysjf8I/AAAAAAAABf0/JQ7cHie96kU/s1600/2.+Accept-Language+Request+Header.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-vJnOdVqTBC0/UiN6Vysjf8I/AAAAAAAABf0/JQ7cHie96kU/s1600/2.+Accept-Language+Request+Header.png" /></a></div>
<p>As we can see in above image browser language is sent to server with Accept-Language header. Each user selected language is sent with coma separated.</p>
<h4>What Is Quality Value?</h4>
<p>If we examine above image carefully, we can see that it is also appending some numeric value to some of language. For e.g. en-US<b>;q=0.8</b> in above image. This value is called quality value. As <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4" target="_blank">described here</a>, quality value represent user's preference of choice. Default value is 1 and generally it is not appended. As we can see in above image we have set Gujarati as a preferable language so in request header it is not appending quality value for it. Although this behavior can be different from browser to browser.</p>
<p>Below image show the value of Request.UserLanguages which is populated from Accept-Language request header.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-XnGPNiNhiP8/UiN6V8mS-2I/AAAAAAAABf8/fBl5Ba6GqXE/s1600/3.+HttpRequest.UserLanguages.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-XnGPNiNhiP8/UiN6V8mS-2I/AAAAAAAABf8/fBl5Ba6GqXE/s1600/3.+HttpRequest.UserLanguages.png" /></a></div>
<p>Hope this quick & short post would be helpful!</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-78711537396216651892013-08-06T16:19:00.000+05:302013-11-06T18:38:47.798+05:30ASP.NET: Office Automation on Web Server (IIS)<p>Often in web application, we require to automate office application. One common such requirement is Export To Excel. Here in this article, we will discuss different approaches for automating office application on web server and will try to conclude which is recommended approach with respect to technical & licensing feasibility along with reference link and available open source library from community. However for simplicity we will discuss around Export To Excel functionality as it is most common and required feature in any web application but approaches discussed here and external references given here apply to other office application as well including Word and Power Point. </p>
<a name='more'></a>
<p>If we Google it out for Export To Excel in ASP.NET, we will find plenty of solution. Each solution has its own pros and cons. Sometime some of the solutions are not feasible with respect to application requirement or sometime it is not feasible with respect to production deployment scenario. Let start discussion by listing few common approach which I observed for Export To Excel. </p>
<h4>Export As CSV</h4>
<p>If application requirement is only to export tabular data, then often I have observed that developer are exporting it as CSV rather than getting into generating excel file. However in this approach we don’t get luxury of cell formatting, merging etc. </p>
<h4>Grid View Rendered HTML</h4>
<p>Another most common scenario, I have seen is using Grid View control, write Grid View rendered HTML into HTML writer and flush that HTML to response stream with appropriate ContentType response header. Here we can have little flexibility over cell formatting but it is very tedious programming task to set proper cell formatting via Grid View. Apart from cell formatting sometime based on requirement we even require more control for e.g. cell merge, column width, word-wrap in case of descriptive content in particular cell, etc and lot more which is not possible or feasible with Grid View control. </p>
<h4>Grid View & ASP.NET MVC Razor View</h4>
<p>Again if application is built with ASP.NET MVC & Razor View and when we are bound to use Razor view only at that time we will not find Grid View control handy. Here what we can do is we can generate HTML table and flush it into response stream with appropriate ContentType response header. </p>
<h4>Office Interop Library</h4>
<p>In some of the reference, I found that some developers are using Office Interop Library on web server. Office Interop Library gives full control over office application but It is strongly recommended to NOT USE Office Interop Library on web server or ASP.NET application. It requires office to be installed on web server and other various settings which is not recommended on web server and sometime even denied on production server by server admin. These settings include additional permission, setting interactive desktop user profile because most of the time production server will be logged off. Sometime it even requires setting interactive user or user identity under Component Service as displayed in below image. </p>
<div class="separator" style="clear: both; text-align: center;">
<a rel="nofollow" target="_blank" href="http://4.bp.blogspot.com/-XvJmP9Xl0to/UgDQXAPopNI/AAAAAAAABfM/5tvuf8LdkSA/s1600/Office+Interop+Component+Service.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="http://4.bp.blogspot.com/-XvJmP9Xl0to/UgDQXAPopNI/AAAAAAAABfM/5tvuf8LdkSA/s400/Office+Interop+Component+Service.png" width="400" /></a></div>
<p>Full list of Problems using server-side Automation of Office is given here in this link <a rel="nofollow" target="_blank" href="http://support.microsoft.com/kb/257757">http://support.microsoft.com/kb/257757</a>. Apart from technical issue there can be issue with licensing also. As mentioned on above link-</p>
<p class="updated-text">Besides the technical problems, we must also consider licensing issues. Current licensing guidelines prevent Office applications from being used on a server to service client requests, unless those clients themselves have licensed copies of Office. Using server-side Automation to provide Office functionality to unlicensed workstations is not covered by the End User License Agreement (EULA). </p>
<p>P.S. above reference is quoted from <a rel="nofollow" target="_blank" href="http://support.microsoft.com/kb/257757">http://support.microsoft.com/kb/257757</a> as on while I published this post. i.e. 06-Aug-13. </p>
<p>Conclusion is we SHOULD NOT USE Office Interop Library for office automation on web server & ASP.NET application.</p>
<h4>Open XML SDK (Recommended Approach) </h4>
<p>Ahhh… after long discussion we finally stepped at recommended approach, but I believe this long discussion was required to understand as requirement evolve (from simple data extract in CSV to formatted well aligned excel file) how we knowingly or unknowingly fall into situation which can lead to technical as well licensing issues over the time. Covering Open XML SDK tutorial is beyond the scope of this post. But let me quickly discuss few things with reference article from MSDN and Microsoft Knowledge Base. </p>
<ul>
<li><a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/bb739834.aspx">Manipulating Excel 2007 and PowerPoint 2007 Files with the Open XML Format API (Part 1 of 2)</a></li>
<li><a rel="nofollow" target="_blank" href="http://support.microsoft.com/kb/931866">How to use the Office XML file format and the packaging components from the .NET Framework 3.0 to create a simple Excel 2007 workbook or a simple Word 2007 document</a></li>
</ul>
<p>If we look into above beginner level link, we will find using Open XML SDK means dealing with package and XML document manipulation. Apart from here also <a rel="nofollow" target="_blank" href="http://support.microsoft.com/kb/257757">http://support.microsoft.com/kb/257757</a> we can find few links which show how to use Open XML SDK with Excel, Word & Power Point. </p>
<h4>Open Source Library</h4>
<p>Apart from above MSDN tutorials, I came across few open source library on codeplex one of the best I found is <a rel="nofollow" target="_blank" href="https://closedxml.codeplex.com/">https://closedxml.codeplex.com/</a> which is wrapper over Open XML SDK. A benefit with this library is that you do not need to deal with raw package and XML document. <a rel="nofollow" target="_blank" href="https://closedxml.codeplex.com/documentation">Here on documentation page on codeplex</a> we can find step by step tutorial for auto sum, auto filter, pivot table, etc. Apart from above wrapper over Open XML SDK I found few other projects on codeplex which is as below but I have not tested its functionality thoroughly. </p>
<ul>
<li><a rel="nofollow" target="_blank" href="https://npoi.codeplex.com/">https://npoi.codeplex.com/</a></li>
<li><a rel="nofollow" target="_blank" href="https://epplus.codeplex.com/">https://epplus.codeplex.com/</a></li>
</ul>
<p> Hope this post would be helpful! <i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-74336032315980518782013-07-14T17:14:00.000+05:302013-11-06T18:38:14.508+05:30ASP.NET MVC: Drag & Drop File Upload with Fallback Browser Support with dropzone js<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-D6Mbz8_bZa4/UeKJLh0hi2I/AAAAAAAABeA/jpto0gDTouE/s1600/1.+dropzone+js.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="100" src="http://2.bp.blogspot.com/-D6Mbz8_bZa4/UeKJLh0hi2I/AAAAAAAABeA/jpto0gDTouE/s200/1.+dropzone+js.png" width="95" /></a></div>
<p>Recently I came across <a href="http://www.dropzonejs.com/" target="_blank">dropzone js</a> library. It enables developer to add drag & drop file upload support in any web application very easily. So here will try to see how we can add drag & drop file upload support in ASP.NET MVC application with dropzone js. </p>
<a name='more'></a>
<div style="clear:both;"></div>
<h4>Why dropzone js?</h4>
<ul>
<li>It runs without jQuery or other JavaScript framework</li>
<li>It also handle old browser nicely and we can add fallback form elements which will be used in older browser</li>
<li>It supports image preview</li>
<li>Do not requires additional JavaScript code</li>
</ul>
<p><a href="https://github.com/enyo/dropzone/tree/master/downloads" target="_blank">Download dropzone js</a> from here and include dropzone.js, css, images in MVC project and follow below step by step guide to add support for drag & drop file upload in ASP.NET MVC. </p>
<h4>Step by Step Guide</h4>
<p>First step is to include JavaScript & default CSS in MVC view as displayed in below code snippet. </p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><link href=<span class="str">"~/Dropzone/css/basic.css"</span> rel=<span class="str">"stylesheet"</span> /></pre><!--CRLF--><pre class="alteven"><link href=<span class="str">"~/Dropzone/css/dropzone.css"</span> rel=<span class="str">"stylesheet"</span> /></pre><!--CRLF--><pre class="alt"><script src=<span class="str">"~/Dropzone/dropzone.min.js"</span>></script></pre><!--CRLF--></div></div>
<p>Once we linked above JS & CSS next step is to add form element. Best thing with dropzone js is that we just need to add form element with class "dropzone", rest will be handled by dropzone js itself. </p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><form action=<span class="str">"~/Home/SaveUploadedFile"</span> method=<span class="str">"post"</span> </pre><!--CRLF--><pre class="alteven"> enctype=<span class="str">"multipart/form-data"</span> <span class="kwrd">class</span>=<span class="str">"dropzone"</span> </pre><!--CRLF--><pre class="alt"> id=<span class="str">"dropzoneForm"</span>></pre><!--CRLF--><pre class="alteven"></form></pre><!--CRLF--></div></div>
<p>As dropzone js is client library, it adds client side support in browser. For server side handling of uploaded file we need to write code for it. So below is the code snippet of how to handle uploaded file in MVC controller. </p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> ActionResult SaveUploadedFile()</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">bool</span> isSavedSuccessfully = <span class="kwrd">true</span>;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">foreach</span> (<span class="kwrd">string</span> fileName <span class="kwrd">in</span> Request.Files)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> HttpPostedFileBase file = Request.Files[fileName];</pre><!--CRLF--><pre class="alteven"> <span class="rem">//Save file content goes here</span></pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">if</span> (isSavedSuccessfully)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> Json(<span class="kwrd">new</span> { Message = <span class="str">"File saved"</span> });</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> <span class="kwrd">else</span></pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> Json(<span class="kwrd">new</span> { Message = <span class="str">"Error in saving file"</span> });</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>Yes we done for first test! Press Ctrl + F5 and navigate to view, we can see dropzone created where user can drag and drop file to upload it. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-hOFDcu1qUMQ/UeKJLNC000I/AAAAAAAABd4/289RWjCbCDU/s1600/2.+dropzone+in+modern+browser.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-hOFDcu1qUMQ/UeKJLNC000I/AAAAAAAABd4/289RWjCbCDU/s1600/2.+dropzone+in+modern+browser.png" /></a></div>
<p>Dropzone also support image preview, drag some files in dropzone and you can see how it is uploaded to server along with image preview. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Mr6CEalV8Uk/UeKJVfTxTbI/AAAAAAAABeg/-pqa0CFYOcw/s1600/3.+when+file+dropped.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-Mr6CEalV8Uk/UeKJVfTxTbI/AAAAAAAABeg/-pqa0CFYOcw/s1600/3.+when+file+dropped.png" /></a></div>
<h4>Handling Server Response</h4>
<p>Now here we will see how we can handle server response with dropzone js. To handle server response, we need to add on complete event handler for dropzone. Below is the code snippet of how to add on complete event handler in dropzone. </p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><script type=<span class="str">"text/javascript"</span>></pre><!--CRLF--><pre class="alteven"> Dropzone.options.dropzoneForm = {</pre><!--CRLF--><pre class="alt"> init: function () {</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">this</span>.on(<span class="str">"complete"</span>, function (data) { </pre><!--CRLF--><pre class="alt"> var res = eval(<span class="str">'('</span> + data.xhr.responseText + <span class="str">')'</span>);</pre><!--CRLF--><pre class="alteven"> alert(res.Message);</pre><!--CRLF--><pre class="alt"> });</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> };</pre><!--CRLF--><pre class="alteven"></script></pre><!--CRLF--></div></div>
<p>In on complete even handler, we can access XHR (XmlHTTPRequest) object with <b>data.xhr</b>. So in above code snippet we are accessing server response with <b>data.xhr.responseText</b> and parsing it into JSON and displaying it in browser. We can also get HTTP status of server request while upload files with <b>data.status</b>. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-LuX-yfXCq7w/UeKJMXo0nzI/AAAAAAAABeI/P54iRGXN7fM/s1600/4.+handling+sesrver+reponse.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-LuX-yfXCq7w/UeKJMXo0nzI/AAAAAAAABeI/P54iRGXN7fM/s1600/4.+handling+sesrver+reponse.png" /></a></div>
<h4>Fallback for older browser</h4>
<p>We can add support for fallback browser very easily just by embedding container element with class "fallback" inside form element. Modify above HTML form markup with below markup to add support for older browser. </p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><form action=<span class="str">"~/Home/SaveUploadedFile"</span> method=<span class="str">"post"</span> </pre><!--CRLF--><pre class="alteven"> enctype=<span class="str">"multipart/form-data"</span> <span class="kwrd">class</span>=<span class="str">"dropzone"</span> </pre><!--CRLF--><pre class="alt"> id=<span class="str">"dropzoneForm"</span>></pre><!--CRLF--><pre class="alteven"> <div <span class="kwrd">class</span>=<span class="str">"fallback"</span>></pre><!--CRLF--><pre class="alt"> <input name=<span class="str">"file"</span> type=<span class="str">"file"</span> multiple /></pre><!--CRLF--><pre class="alteven"> <input type=<span class="str">"submit"</span> <span class="kwrd">value</span>=<span class="str">"Upload"</span> /></pre><!--CRLF--><pre class="alt"> </div></pre><!--CRLF--><pre class="alteven"></form></pre><!--CRLF--></div></div>
<p>Now navigate to page through older browser and we can see file upload control. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-pYClEOxFYrE/UeKJMxi4BRI/AAAAAAAABeQ/AtMIrWyzzqs/s1600/5.+fallback+browser.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-pYClEOxFYrE/UeKJMxi4BRI/AAAAAAAABeQ/AtMIrWyzzqs/s1600/5.+fallback+browser.png" /></a></div>
<h4>Older Browser & Post Upload Redirection</h4>
<p>Earlier we implemented action method which handle file upload on server side and return JSON object. While in case of older browser, on form submit, browser will be redirected to action URL but our earlier implementation sends JSON object as a response. So we need to modify that implementation so that in case of older browser, it sends HTML response. So below is the updated implementation of action method, which also handle older browser. </p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> ActionResult SaveUploadedFile()</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">bool</span> isSavedSuccessfully = <span class="kwrd">true</span>;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">foreach</span> (<span class="kwrd">string</span> fileName <span class="kwrd">in</span> Request.Files)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> HttpPostedFileBase file = Request.Files[fileName];</pre><!--CRLF--><pre class="alteven"> <span class="rem">//Save file content goes here</span></pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">if</span> (Request.IsAjaxRequest())</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">if</span> (isSavedSuccessfully)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> Json(<span class="kwrd">new</span> { Message = <span class="str">"File saved"</span> });</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> <span class="kwrd">else</span></pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> Json(<span class="kwrd">new</span> { Message = <span class="str">"Error in saving file"</span> });</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">else</span></pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> RedirectToAction(<span class="str">"PostUpload"</span>);</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>Here we are checking if it is AJAX response then we are sending JSON object as response while in case of non-AJAX request it will return HTML response i.e. View Result and it will redirect browser to post upload view. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-VvNC4M-5v6M/UeKJMx2Z4NI/AAAAAAAABeU/hPyp0Zfn8lM/s1600/6.+fallback+browser+response.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-VvNC4M-5v6M/UeKJMx2Z4NI/AAAAAAAABeU/hPyp0Zfn8lM/s1600/6.+fallback+browser+response.png" /></a></div>
<p>So here we have to try to discuss how to integrate dropzone js with ASP.NET MVC application along with fallback support for older browser. For more configuration option visit <a href="http://www.dropzonejs.com/" target="_blank">http://www.dropzonejs.com/</a> Hope this post would be helpful. </p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-70547879751414618522013-06-16T22:45:00.000+05:302013-11-06T18:37:41.480+05:30ASP.NET MVC View Model: Entity Framework & JSON Serialization<p>Many times I came across an ASP.NET MVC application, where Entity Framework Model (or Database Model) is being used as view model as well. No this post is not about to discuss whether entity model should be used as view model or not but in this post we will discuss one tip with respect to JSON Serialization which will help to improve <a href="http://www.dotnetexpertguide.com/search/label/Performance">performance</a> in terms of CPU processing and bandwidth usage while using entity model as view model.</p>
<a name='more'></a>
<p>Before we get into implementation scenario, let me list down few points which leads to use entity model as view model. Once again please note that this post is not to discuss or justify whether entity model should be used as view model or not.</p>
<ul>
<li>One argument I heard is that not in all cases but most of the time your view model would be almost ditto as entity model or database model and in such case why should we maintain another type for view model.</li>
<li>While we are maintaining separate type for view model, we need to convert entity model into view model each and every time view is rendered. Yes of course we can use AutoMapper or something similar mapper library for type mapping and conversion but still personally I believe why this extra overhead of type conversion?</li>
</ul>
<p>So above is two major concern which leads to use entity model itself as a view model. So now we will try to understand whole scenario by formulating one example. Below is application/project setup.</p>
<ul>
<li>MVC 3/4</li>
<li>Use of AJAX wherever possible for better user experience</li>
<li>Entity Framework with Entity Context or Entity Object (Default EDMX template with Visual Studio 2010, DbContext scenario is also covered later in this post)</li>
<li>Newtonsoft.Json for JSON Serialization</li>
</ul>
<p>For this post demo we will use Northwind Database Category & Product table. Following is the diagram of Entity Designer with Category & Product table.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zb494QvXxss/Ub3pWNI21sI/AAAAAAAABcA/vTWN4idIvyM/s1600/1+Model+Designer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-zb494QvXxss/Ub3pWNI21sI/AAAAAAAABcA/vTWN4idIvyM/s1600/1+Model+Designer.png" /></a></div>
<p>Entity Framework creates Navigation Properties for parent/child table. Now whenever we will try to serialize entity model it will also populate & serialize navigation properties. For better understanding consider the Category Listing page with paging which will refresh category list via AJAX call and server response is in JSON format. Look at the below two images.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-l6t5Z_he9Gk/Ub3pWYQIlMI/AAAAAAAABcE/1ClmPAR2-uE/s1600/2+Category+List.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-l6t5Z_he9Gk/Ub3pWYQIlMI/AAAAAAAABcE/1ClmPAR2-uE/s1600/2+Category+List.png" /></a></div>
<p>As we can see that it is populating & serializing each navigation properties while in this specific scenario we are not going to use child record i.e. Products record. Along with child record it is also serializing details of Entity Keys for category have a look at below image.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-0-gNA54UPb0/Ub3pWjIrvNI/AAAAAAAABcQ/0W0yr4KVKro/s1600/3+Category+List.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-0-gNA54UPb0/Ub3pWjIrvNI/AAAAAAAABcQ/0W0yr4KVKro/s1600/3+Category+List.png" /></a></div>
<p>In this specific case or most cases, we are not going to use child records or entity keys because most of the time our strategy would be on demand loading. And more importantly serialization of child records also leads to increases response size see marked box in above both images. Here there are two scope for improvements one <b>Stop Serializing of Child Records to reduce response size</b>. And eventually when we are omitting child records from serialization, it will <b>reduce CPU processing</b> as well. Before we look into actual implementation have a look at below image which shows response detail after optimization.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-_QRJE4NWCHc/Ub3pXQmO9BI/AAAAAAAABcY/U_c10qw5xec/s1600/4+Category+List.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-_QRJE4NWCHc/Ub3pXQmO9BI/AAAAAAAABcY/U_c10qw5xec/s1600/4+Category+List.png" /></a></div>
<p>Voila we have reduced response size <b>from 37.3 KB to 1.1 KB :)</b> yes this is oblivious because in this case we are not serializing child records of entity framework model. In this demo post there are only 8 records in Category Table but consider real time application scenario where there can be few hundreds or more records. So below is the implementation for the same how we achieved this.</p>
<p>As earlier noted, we are using Newtonsoft.Json library for JSON serialization. To achieve above optimization in JSON serialization we have created <b>custom JSON Converter</b> by deriving Newtonsoft.Json.JsonConverter. Below is the actual implementation of custom JSON Converter.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> EFNavigationPropertyConverter : Newtonsoft.Json.JsonConverter</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">bool</span> CanConvert(Type objectType)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">bool</span> isValid = <span class="kwrd">false</span>;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">if</span> (objectType.FullName == <span class="str">"System.Data.EntityKey"</span>)</pre><!--CRLF--><pre class="alteven"> isValid = <span class="kwrd">true</span>;</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">if</span> (objectType.IsGenericType &&</pre><!--CRLF--><pre class="alt"> objectType.GetGenericTypeDefinition().FullName</pre><!--CRLF--><pre class="alteven"> .Contains(<span class="str">"System.Data.Objects.DataClasses.EntityCollection"</span>))</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> isValid = <span class="kwrd">true</span>;</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> isValid;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">object</span> ReadJson(JsonReader reader, Type objectType, </pre><!--CRLF--><pre class="alt"> <span class="kwrd">object</span> existingValue, JsonSerializer serializer)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> existingValue;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> WriteJson(JsonWriter writer, <span class="kwrd">object</span> <span class="kwrd">value</span>, JsonSerializer serializer)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> writer.WriteNull();</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>In above custom JSON converter we are checking if target object type is of EntityKey or EntityCollection then we are serializing NULL. That’s it and below is the code snippet of how to use this custom JSON converter with JSON.NET.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> ActionResult GetCategory()</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> EF.EO.Northwind40Entities e = <span class="kwrd">new</span> EF.EO.Northwind40Entities();</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> List<EF.EO.Category> categoryList = e.Categories.ToList();</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">string</span> strJSON = JsonConvert.SerializeObject(categoryList, </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">new</span> EFNavigationPropertyConverter());</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> Content(strJSON, <span class="str">"application/json"</span>);</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<h4>Entity Framework & DbContext Approach</h4>
<p>We have discussed optimization with Entity Framework Entity Context or Entity Object approach as the application was built with Visual Studio 2010. But with Visual Studio 2012 default EDMX templates generate classes based on DbContext approach so here we will see how to optimize entity model serialization with DbContext. </p>
<h4>Serializing DbContext Entity Model Class</h4>
<p>When we try to serialize DbContext model class into JSON it will throw an exception as displayed in below image.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-kPGuf4e99Tc/Ub3pYfp8q6I/AAAAAAAABcg/Mwm-UoQA6Ms/s1600/5+EF+DC+Error.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-kPGuf4e99Tc/Ub3pYfp8q6I/AAAAAAAABcg/Mwm-UoQA6Ms/s1600/5+EF+DC+Error.png" /></a></div>
<p>For clear separation of topic, we are not discussing here why this exception thrown with DbContext while it was working fine with Entity Context approach but for now it is preventing us to serialize DbContext model class into JSON. So what’s solution for it? Custom JSON Converter yes again custom JSON converter can be used to resolve this exception. So below is the code of Custom JSON Converter which will allow us to serialize DbContext model class into JSON.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> EFNavigationPropertyConverter : Newtonsoft.Json.JsonConverter</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">bool</span> CanConvert(Type objectType)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">bool</span> isValid = <span class="kwrd">false</span>;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">if</span> (objectType.IsGenericType && </pre><!--CRLF--><pre class="alteven"> objectType.GetGenericTypeDefinition().FullName.</pre><!--CRLF--><pre class="alt"> Contains(<span class="str">"System.Collections.Generic.HashSet"</span>))</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> isValid = <span class="kwrd">true</span>;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> isValid;</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="rem">// other code removed for clarity</span></pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>DbContext model populates navigation property with System.Collections.Generic.HashSet collection. So we are serializing NULL for it and below is the image which shows response with above custom JSON Converter.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Z11YhJkJYqI/Ub3pYqkSYBI/AAAAAAAABco/PkvbDKJNNj0/s1600/6+EF+DC+Response.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-Z11YhJkJYqI/Ub3pYqkSYBI/AAAAAAAABco/PkvbDKJNNj0/s1600/6+EF+DC+Response.png" /></a></div>
<p>In above image we can see that how custom JSON converter enable us to serialize DbContext model and omitting serialization of Navigation Property for child table.</p>
<h4>Separate View Model & Mapper Library</h4>
<p>Yes we can create separate view model and can get rid from all above custom JSON converter and etc. but what are the things we need to take care in such cases. Below is the list of prime points.</p>
<ul>
<li>Whenever any new property is added in entity model we need to sync our view model with it.</li>
<li><b>Entity Model to View Model Conversion:</b> if we are manually handling this conversion then we need to alter code at each place and if we are using mapper library than it might requires to change configuration of Object Mapping. This depends on newly added property sometime we even do not require to alter Object Mapping.</li>
<li><b>Processing Overhead:</b> if we are creating separate type for View Model then <b>first it will populate custom View Model and then after it will serialize it into JSON</b>. While in case of Entity Model as a View Model, it will take care of omitting Navigation Property on the fly at a time of serialization <b>so there is less processing overhead in Entity Model as a View Model</b>.</li>
</ul>
<h4>Conclusion</h4>
<p>As noted in starting, this post is not to discuss or justify whether Entity Model should be used as View Model or not but here we have tried to discuss small but useful tip which can lead <a href="http://www.dotnetexpertguide.com/search/label/Performance">performance</a> improvements while JSON serializing in ASP.NET MVC application with Entity Framework. Hope this would be helpful.</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-2445052853136042342013-06-15T20:00:00.000+05:302013-11-06T18:37:07.927+05:30IIS: Create & Configure Self-Signed Certificate in IIS 7 or Later<p>In past one of my friends asked me how to configure self-signed SSL certificate in local IIS 7 or later. Steps for creating & configuring SSL in IIS 7 or later is pretty much straight forward. Before few days I received same <a href="http://www.dotnetexpertguide.com/2012/10/aspnet-mvc-requirehttps-action-filter.html#comment-919405107">comment</a> on <a href="http://www.dotnetexpertguide.com/2012/11/aspnet-mvc-action-filter-series.html">ASP.NET MVC Action Filter Series</a> that how to setup SSL in local IIS websites. So here in this post, we are going to address it as part of <a href="http://www.dotnetexpertguide.com/2011/10/iis-7-tutorial-posts-link.html">IIS administration & configuration posts series</a>. Yes yes this post is going to be very basic and straight forward few clicks configuration but you can stay tuned for more post in next week and later.</p>
<a name='more'></a>
<p>Steps here mentioned are based on IIS 8, but it would be almost same on IIS 7 as well. Ok so to get started open IIS and select <b>Server Certificates</b> feature.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-MdjL2e6Gmro/Ubx11JzC0OI/AAAAAAAABbI/UvXA3BR-P1I/s1600/1+IIS+Server+Certificates.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-MdjL2e6Gmro/Ubx11JzC0OI/AAAAAAAABbI/UvXA3BR-P1I/s1600/1+IIS+Server+Certificates.png" /></a></div>
<p>It will display list of all installed Server Certificate on web server. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-CpmdeJ7KBq0/Ubx10_DyOQI/AAAAAAAABa4/2k32wMcyNaY/s1600/2+IIS+Server+Certificates.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-CpmdeJ7KBq0/Ubx10_DyOQI/AAAAAAAABa4/2k32wMcyNaY/s1600/2+IIS+Server+Certificates.png" /></a></div>
<p>To create new self-signed certificate, click on <b>Create Self-Signed Certificate..</b>. in action pane. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Ai-CN6mlQxQ/Ubx101HFltI/AAAAAAAABa8/aoBHkroVr30/s1600/3+IIS+Action+Pane.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-Ai-CN6mlQxQ/Ubx101HFltI/AAAAAAAABa8/aoBHkroVr30/s1600/3+IIS+Action+Pane.png" /></a></div>
<p>It will open dialog box where you can specify friendly name for server certificate and certificate store for newly created SSL certificate.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-NlsIF_jOsaw/Ubx12HSjG6I/AAAAAAAABbQ/KBKiz4IvHX4/s1600/4+IIS+Self+Signed+Certificate.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" width="600" src="http://3.bp.blogspot.com/-NlsIF_jOsaw/Ubx12HSjG6I/AAAAAAAABbQ/KBKiz4IvHX4/s1600/4+IIS+Self+Signed+Certificate.png" /></a></div>
<p>Specify name of the certificate, certificate store and click on OK. So we are half way done, we have created Self-Signed Certificate with IIS, but still half way to go. After creating certificate, we need to bind it with websites then only we will be able to browse local IIS website with HTTPS.</p>
<p>To bind websites with this certificate, select website in IIS and right click on it and select <b>Edit Bindings...</b></p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-yLxa_CsYyJY/Ubx12joc03I/AAAAAAAABbc/UpeOequy0iU/s1600/5+IIS+Edit+Binding.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-yLxa_CsYyJY/Ubx12joc03I/AAAAAAAABbc/UpeOequy0iU/s1600/5+IIS+Edit+Binding.png" /></a></div>
<p>It will open Site Bindings dialog where we can see binding information for selected websites. By default you will find one HTTP binding listed here.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-bsln1b3gpSM/Ubx12u6jBPI/AAAAAAAABbU/gGYvPHOSyas/s1600/6+IIS+Add+Binding.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" width="600" src="http://3.bp.blogspot.com/-bsln1b3gpSM/Ubx12u6jBPI/AAAAAAAABbU/gGYvPHOSyas/s1600/6+IIS+Add+Binding.png" /></a></div>
<p>Click on Add button to Add new binding for selected website.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-LcXSXmVUBFg/Ubx13YLpfHI/AAAAAAAABbo/A5doo9PbpOE/s1600/7+IIS+HTTPS+Site+Binding.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-LcXSXmVUBFg/Ubx13YLpfHI/AAAAAAAABbo/A5doo9PbpOE/s1600/7+IIS+HTTPS+Site+Binding.png" /></a></div>
<p>Here, select <b>binding type HTTPS</b> and select newly <b>created SSL certificate from drop down</b> and click on OK. So we have added HTTPS binding to website which uses self-signed certificate in local IIS. To verify open and browse https://localhost.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-huTF-8xeOxg/Ubx15EwHpDI/AAAAAAAABbw/Yk1gOJUsyAA/s1600/8+localhost+with+HTTPS.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-huTF-8xeOxg/Ubx15EwHpDI/AAAAAAAABbw/Yk1gOJUsyAA/s1600/8+localhost+with+HTTPS.png" /></a></div>
<p>Hope this quick post would be helpful and <a href="http://www.dotnetexpertguide.com/2011/10/iis-7-tutorial-posts-link.html">for more post on IIS checkout this index page</a>.</p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-29715984753174156732013-05-11T11:59:00.000+05:302013-11-06T18:36:11.505+05:30ASP.NET MVC: HandleError action filter<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Lscfd1NvnVY/UY3iJLOwKmI/AAAAAAAABZ4/l4cZ6XcrllM/s1600/HandleError.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="ASP.NET MVC: HandleError" border="0" src="http://4.bp.blogspot.com/-Lscfd1NvnVY/UY3iJLOwKmI/AAAAAAAABZ4/l4cZ6XcrllM/s1600/HandleError.png" title="ASP.NET MVC: HandleError" /></a></div>
<p>HandleError attribute is used to catch unhandled exception in controller action method. In default MVC template, HandleError attribute is already added to GlobalFilterCollection. In MVC 3, we can see it in <b>Global.asax</b> while in MVC 4 we can see it in <b>App_Start/FilterConfig.cs</b>. One thing to keep in mind is that HandleError will handle exception only if customErrors mode="On" is set in web.config.</p>
<div style="clear:both;"></div>
<a name='more'></a>
<p><b>Attribute Usage:</b> Controller & method</p>
<p><b>Sample Code:</b></p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<div id="codeSnippet" class="csharpcode"><pre class="alt">[HandleError]</pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> ActionResult Index()</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">"HandleError Exception"</span>);</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> View();</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>As noted earlier, if we have not set customErrors mode="On" then HandleError will not catch this exception and it will show default YSOD(Yellow Screen Of Death).</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-rquPUJfS4w0/UY3iMziRFGI/AAAAAAAABaA/_k-RsLIz6Io/s1600/YSOD-asp.net.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="YSOD(Yellow Screen Of Death) ASP.NETA" border="0" src="http://1.bp.blogspot.com/-rquPUJfS4w0/UY3iMziRFGI/AAAAAAAABaA/_k-RsLIz6Io/s1600/YSOD-asp.net.png" title="YSOD(Yellow Screen Of Death) ASP.NETA" /></a></div>
<p>To enable exception catching, enable customErrors in web.config as below.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><system.web></pre><!--CRLF--><pre class="alteven"> <customErrors mode=<span class="str">"On"</span>></customErrors></pre><!--CRLF--><pre class="alt"></system.web></pre><!--CRLF--></div></div>
<p>Now again run application, it should catch exception & it should display error.cshtml as displayed below.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-hwiLI2t3-LI/UY3iNxBypTI/AAAAAAAABaI/ZbIjS49xiCg/s1600/handleerror-aspnet-mvc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-hwiLI2t3-LI/UY3iNxBypTI/AAAAAAAABaI/ZbIjS49xiCg/s1600/handleerror-aspnet-mvc.png" /></a></div>
<p>With HandleError we can also specify <b>ExceptionType</b> for which to catch unhandled exception, <b>View</b> to display when exception is caught, and <b>Master</b> view.</p>
<p>Check out <a href="http://www.dotnetexpertguide.com/2012/11/aspnet-mvc-action-filter-series.html">ASP.NET MVC: Action filter series</a> post to read about other available action filters.</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-9019778913126777232013-04-14T14:06:00.000+05:302013-11-17T20:31:21.379+05:30ASP.NET Web Optimization Framework (Bundling & Minification) Articles <p>Right from developer preview version of ASP.NET 4.5 & MVC 4 (vNext), I have covered ASP.NET Web Optimization Framework (a.k.a Bundling & Minification) in my <a href="http://www.dotnetexpertguide.com/2011/09/aspnet-mvc-4-article-series.html">MVC 4 article series</a>. Later on I have posted several articles covering different aspects of ASP.NET Web Optimization Framework and how I implemented it. So I'm writing this post as an index post of articles covering ASP.NET Web Optimization Framework. So it would be easier to access all posts under one roof. In upcoming days I'm planning to add few more articles on this topic, as and when I will add new articles I will update this index post as well.</p>
<a name='more'></a>
<p>If you come across any good article on this topic then do comment here, I will include it in this list.</p>
<ul>
<li><a href="http://www.dotnetexpertguide.com/2011/12/bundling-and-minification-aspnet-mvc4.html">Bundling and Minification in ASP.NET MVC 4</a> This post cover how to use bundling & minification in MVC 4 application.</li>
<li><a href="http://www.dotnetexpertguide.com/2012/10/aspnet-45-mvc-4-revisiting-IBundleTransform-in-bundling.html">ASP.NET 4.5 & MVC 4: Revisiting IBundleTransform</a> In this article, we will discuss how to implement custom bundle transform with ASP.NET Web Optimization Framework. We will also discuss how to address caching with ASP.NET Web Optimization Framework.</li>
<li><a href="http://www.dotnetexpertguide.com/2012/11/aspnet-45-mvc-4-bundling-next-approach.html">ASP.NET 4.5 & MVC 4 Bundling: Next Approach</a> Default bundle accepts file path as bundle input and bundle & minimize it in one resource. This post describe how to pass additional parameter to custom bundle transform and how to utilize whilte processing custom bundle transform.</li>
<li><a href="http://www.dotnetexpertguide.com/2012/11/aspnet-mvc-bundling-auto-sync-javascript-model-with-mvc-model.html">ASP.NET MVC Bundling: Auto sync JavaScript model with MVC model</a> This post explain how to create custom bundle transform which is used to generate JavaScript Model from C# model class.</li>
<li><a href="http://www.dotnetexpertguide.com/2012/11/aspnet-web-optimization-framework-with-mvc3-aspnet-40-web-forms.html">ASP.NET Web Optimization Framework with MVC 3 & ASP.NET 4.0 web form</a> ASP.NET Web Optimization Framework is built on top of ASP.NET 4.0. This article shows how to implement bundling & minification in ASP.NET 4.0 web form & MVC 3 application.</li>
<li><a href="http://www.dotnetexpertguide.com/2013/11/updated-aspnet-web-optimization-framework-and-cookieless-domain.html">[Updated] ASP.NET Web Optimization Framework & Cookieless Domain</a> Updated article on how to configure ASP.NET Web Optimization Framework & setup Cookieless Domain in an ASP.NET web application.</li>
</ul>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-49610465226544831362013-04-05T22:02:00.001+05:302013-11-06T18:33:36.902+05:30[Picture] ASP.NET MVC: Flow between Model-View-Controller<p>Many times I'm asked this very basic question that how the <a href="http://www.dotnetexpertguide.com/search/label/MVC">ASP.NET MVC</a> application flows between Model-View-Controller. So here we will try to understand it with <a href="http://www.dotnetexpertguide.com/search/label/Picture%20Post">Picture Post</a>.</p>
<a name='more'></a>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-n_atH6DVGqQ/UV76sJQsF1I/AAAAAAAABYk/tvS4wFnbPWE/s1600/Model-View-Controller+Flows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Flow between Model-View-Controller in ASP.NET MVC" border="0" src="http://3.bp.blogspot.com/-n_atH6DVGqQ/UV76sJQsF1I/AAAAAAAABYk/tvS4wFnbPWE/s1600/Model-View-Controller+Flows.png" title="Flow between Model-View-Controller in ASP.NET MVC" /></a></div>
<ul>
<li>User requests URL</li>
<li>Request is mapped to Controller('s Action Method)</li>
<li>Action Method process Model and select View(Result Type)</li>
<li>Processed Model is passed to View or Result Type</li>
<li>Generated response sent back to user</li>
</ul>
<p>Hope this would be helpful. Stay tuned for more post.</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-61367598775011929752013-03-12T00:41:00.000+05:302013-11-06T18:32:55.991+05:30ASP.NET 4.5 Model Binding: Creating Custom Value Provider<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-tVA1SCmrfrg/UT4moISIobI/AAAAAAAABYE/4wBQrId11a4/s1600/ASP.NET.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="http://4.bp.blogspot.com/-tVA1SCmrfrg/UT4moISIobI/AAAAAAAABYE/4wBQrId11a4/s200/ASP.NET.png" width="150" /></a></div>
<p>With ASP.NET 4.5, ASP.NET introduced model binding for web forms as well. Model binding helps to simplify code focused data access logic within web forms. Check out <a href="http://www.asp.net/vnext/overview/aspnet-web-forms/aspnet-45-web-forms-model-binding" target="_blank">this video</a> by Scott Hanselman to know more on ASP.NET 4.5 Web Forms Model Binding.</p>
<div style="clear:both;"></div>
<a name='more'></a>
<p>Here in this post, we will see how we can create our own custom value provider (read <a href="http://www.dotnetexpertguide.com/2013/01/aspnet-mvc-value-provider-for-encrypted-query-string.html">my post</a> on how I used value provider for encrypted query string in MVC application). We will also examine inbuilt class of ASP.NET 4.5 model binding framework which can be useful in creating custom value provider more easily with focused approach.</p>
<p>Before we look into actual interfaces and classes, let us examine few basics of model binding framework. All model binding framework and corresponding classes are resides in <a href="http://msdn.microsoft.com/en-us/library/system.web.modelbinding.aspx" target="_blank">System.Web.ModelBinding</a> namespace which is newly introduced with ASP.NET 4.5. For any value provider to work with model binder it requires two components one is implementation of <b>value provider</b> which reads data from request and forward it to model binder and other one is <b>value provider source attribute</b> which expose the actual value provider instance. Have a look at below code snippet here QueryStringAttribute is value provider source attribute which expose object of QueryStringValueProvider so model binder can use it to fetch data.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> IQueryable<Blog> SelectMethod([QueryString]<span class="kwrd">int</span>? id)</pre><!--CRLF--></div></div>
<h4>Creating Value Provider Source Attribute</h4>
<p>To create custom value provider attribute we can derive Attribute class and implement <b>IValueProviderSource</b> interface as displayed in below code snippet. </p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CustomValueProviderAttribute : Attribute, IValueProviderSource</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> IValueProvider GetValueProvider(ModelBindingExecutionContext modelBindingExecutionContext)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> <span class="kwrd">new</span> CustomValueProvider(modelBindingExecutionContext);</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>Here we can have access of <b>ModelBindingExecutionContext</b> and we can pass same to value provider if it is required. Through ModelBindingExecutionContext we can also have access of <b>HttpContextBase</b> and <b>ModelStateDictionary</b>. </p>
<h4>Creating Value Provider</h4>
<p>Same way we can create Custom Value Provider by implementing <b>IValueProvider</b> interface. Below code snippet shows pseudo code for the same.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CustomValueProvider : IValueProvider</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> ModelBindingExecutionContext _modelBindingExecutionContext;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> CustomValueProvider(ModelBindingExecutionContext modelBindingExecutionContext)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">this</span>._modelBindingExecutionContext = modelBindingExecutionContext;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">bool</span> ContainsPrefix(<span class="kwrd">string</span> prefix)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="rem">// validate if requested key is exist or not</span></pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> ValueProviderResult GetValue(<span class="kwrd">string</span> key)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="rem">// return ValueProviderResult object we </span></pre><!--CRLF--><pre class="alteven"> <span class="rem">// can use ModelBindingExecutionContext</span></pre><!--CRLF--><pre class="alt"> <span class="rem">// to access request data</span></pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>Once we are ready we can use created value provider as </p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt">SelectMethod([CustomValueProvider]<span class="kwrd">int</span>? id, [CustomValueProvider]<span class="kwrd">string</span> name)</pre><!--CRLF--></div></div>
<p>As noted earlier, there are few inbuilt classes in ASP.NET 4.5 model binding framework which give more focused control over custom business logic. Here we will also examine one of its which is <b>SimpleValueProvider</b>. Here we will examine how we can focus on core logic and leaving other responsibility on core framework.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CustomValueProvider : SimpleValueProvider</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> CustomValueProvider(ModelBindingExecutionContext modelBindingExecutionContext)</pre><!--CRLF--><pre class="alteven"> : <span class="kwrd">base</span>(modelBindingExecutionContext)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">object</span> FetchValue(<span class="kwrd">string</span> key)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="rem">// here we can access this.ModelBindingExecutionContext</span></pre><!--CRLF--><pre class="alt"> <span class="rem">// and can look into request data. Once we fetch requested</span></pre><!--CRLF--><pre class="alteven"> <span class="rem">// data we just need to return actual value for e.g. </span></pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> <span class="str">"dotnetExpertGuide.com"</span>;</pre><!--CRLF--><pre class="alteven"> <span class="rem">// NOTE: WE ARE NOT RETURNING ValueProviderResult INSTANCE</span></pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>Earlier with IValueProvider, we had to check if requested key exist or not and if it is then instantiating ValueProviderResult and return it. While with SimpleValueProvider we only need to return actual value of requested key or null incase if it does not exist rest will be taken care by SimpleValueProvider class. Another such framework class is <b>NameValueCollectionValueProvider</b> which act as a base class to create value provider from name value collection. Here I am not demonstrating it. I am leaving it for reader <b>:)</b>.</p>
<h4> SimpleValueProvider and ASP.NET MVC</h4>
<p>Can’t we have/introduce SimpleValueProvider class for MVC in upcoming version?</p>
<h4>ModelStateDictionary</h4>
<p>Once model binding is done for parameter it is added to ModelStateDictionary dictionary along with its value. For e.g.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt">SelectMethod([CustomValueProvider]<span class="kwrd">int</span>? id, [CustomValueProvider]<span class="kwrd">string</span> name)</pre><!--CRLF--></div></div>
<p>In above code once model binding is done for parameter id, it is added to ModelStateDictionary and it is accessible in rest of the parameter model binding i.e. parameter name here.</p>
<p>Hope this would be helpful. Stay tuned for more post.</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-550339392582641942013-02-28T20:58:00.000+05:302013-11-06T18:30:43.956+05:30[Picture] ASP.NET MVC: Action Filter Life Cycle<p>
It is said that <b>A picture is worth a thousand words</b>, so this time I come up with Picture Post to discuss action filter life cycle in ASP.NET MVC. Hope reader would like it. So do share it and stay connected for more post on Action Filter.
</p>
<a name='more'></a>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-HTqI6Xlmd68/US9yhFT1ZYI/AAAAAAAABXc/3GH4hFjLCik/s1600/action+filter+life+cycle.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="ASP.NET MVC: Action Filter Life Cycle" border="0" src="http://4.bp.blogspot.com/-HTqI6Xlmd68/US9yhFT1ZYI/AAAAAAAABXc/3GH4hFjLCik/s1600/action+filter+life+cycle.png" title="ASP.NET MVC: Action Filter Life Cycle" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;font-size: 20px;">ASP.NET MVC: Action Filter Life Cycle</td></tr>
</tbody></table>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-83432349492196032522013-02-15T23:32:00.000+05:302013-11-06T18:30:09.609+05:30PowerShell: Accessing static member in PowerShell Script<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-TVJesIgJoIc/UR50zTxJhwI/AAAAAAAABWc/-Hww47khc1E/s1600/powershell+logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-TVJesIgJoIc/UR50zTxJhwI/AAAAAAAABWc/-Hww47khc1E/s200/powershell+logo.png" width="200" /></a></div>
<p>Recently I created <a target="_blank" href="https://nuget.org/packages/UpgradeMvc3ToMvc4">NuGet package</a> which <a href="http://www.dotnetexpertguide.com/2013/02/aspnet-mvc-auto-upgrade-mvc-3-to-mvc-4-application.html">auto upgrade ASP.NET MVC 3 application to MVC 4</a> and while I was creating this package I worked with powershell. Before that I never worked with powershell so I learned a few thing so thought to share it with reader. If you are new to powershell then you can execute powershell script with command prompt or if you are GUI inclined then Windows 7 also have PowerShell ISE (Integrated Scripting Environment).</p>
<div style="clear:both;"></div>
<a name='more'></a>
<p>To open command prompt type <b>powershell in Run window</b> and press enter or search for powershell in Start all programs and open powershell ISE.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-COkNltoYpWM/UR51PKj3uWI/AAAAAAAABWk/H82QdFd9UKY/s1600/PowerShell+ISE.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-COkNltoYpWM/UR51PKj3uWI/AAAAAAAABWk/H82QdFd9UKY/s1600/PowerShell+ISE.png" /></a></div>
<p>In PowerShell ISE we can see two pane Command Pane & Output Pane. Both pane names are self explanatory so I'm leaving it upto you ;) But yes in command window we can fire any command which we can fire in Windows Command Prompt.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-6VhuSP8iacM/UR51axlTmqI/AAAAAAAABW0/NC6qxL9QQW4/s1600/PowerShell+ISE+pane.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="285" src="http://1.bp.blogspot.com/-6VhuSP8iacM/UR51axlTmqI/AAAAAAAABW0/NC6qxL9QQW4/s400/PowerShell+ISE+pane.png" width="400" /></a></div>
<h4>Accessing Static Member</h4>
<p>Sometime we need to access static member from powershell script as I required it while creating <a href="http://www.dotnetexpertguide.com/2013/02/aspnet-mvc-auto-upgrade-mvc-3-to-mvc-4-application.html">this NuGet package</a>. So in powershell, we can access static member with <b>Scope Resolution Operator (::)</b>. For e.g. type following command in powershell command pane</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-3NM2a2pmsmE/UR51ZH-iBFI/AAAAAAAABWs/cXmMpj9TAdc/s1600/Static+member+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-3NM2a2pmsmE/UR51ZH-iBFI/AAAAAAAABWs/cXmMpj9TAdc/s1600/Static+member+1.png" /></a></div>
<p>Upon hitting enter in command prompt we can see output in output pane</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-mJHE4uXNdak/UR51bAattNI/AAAAAAAABW4/UfV_-xI3Xc0/s1600/Static+member.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-mJHE4uXNdak/UR51bAattNI/AAAAAAAABW4/UfV_-xI3Xc0/s1600/Static+member.png" /></a></div>
<p>So in powershell we can access static member with the help of <b>Scope Resolution Operator (::)</b>. Hope this would be helpful!</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-70484721098204846472013-02-03T23:10:00.000+05:302013-11-06T18:29:51.813+05:30ASP.NET MVC: Auto upgrade MVC 3 to MVC 4 application<p>Yeah you read it right... Its NuGet package to upgrade existing ASP.NET MVC 3 application to ASP.NET MVC 4 application. From last month or two, I was planning to create NuGet package which automatically upgrade existing MVC 3 application to MVC 4 application but somehow I was keeping it at lower priority, but during last week I observed that many readers are redirected to <a href="http://www.dotnetexpertguide.com/2011/12/upgrade-aspnet-mvc-3-project-to-mvc-4.html">Upgrading an ASP.NET MVC 3 Project to ASP.NET MVC 4</a> from this <a target="_blank" href="http://stackoverflow.com/questions/12655808/asp-net-mvc3-to-mvc4-upgrade-tool">stackoverflow question</a> and I found that developer community are also looking for tool which automatically handle this upgrade. So I have created NuGet package and published it here <a href="https://nuget.org/packages/UpgradeMvc3ToMvc4" target="_blank">https://nuget.org/packages/UpgradeMvc3ToMvc4</a> and whole exported package is uploaded here <a href="https://github.com/NandipMakwana/UpgradeMvc3ToMvc4" target="_blank">https://github.com/NandipMakwana/UpgradeMvc3ToMvc4</a></p>
<a name='more'></a>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-A_yS2CTmqpg/UQ6WIRiEj0I/AAAAAAAABVA/IS8deD7V9m4/s1600/Upgrade.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/-A_yS2CTmqpg/UQ6WIRiEj0I/AAAAAAAABVA/IS8deD7V9m4/s200/Upgrade.jpg" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-0GTm3Taujl0/UQ6j3__CMGI/AAAAAAAABVY/_VImNPCd79I/s1600/upgrade.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" width="600" src="http://2.bp.blogspot.com/-0GTm3Taujl0/UQ6j3__CMGI/AAAAAAAABVY/_VImNPCd79I/s400/upgrade.png" /></a></div>
<p>I have upgraded few MVC 3 application to MVC 4 application with this package and it worked fine for me. <b>If solution is under source control then please make sure that all web.config are writable and checked out.</b> Along with upgradtion I have also included <a target="_blank" href="http://blogs.msdn.com/b/rickandy/archive/2012/09/17/asp-net-mvc-4-mobile-caching-bug-fixed.aspx">MVC 4 FixedDisplayModes</a>, <a href="http://www.dotnetexpertguide.com/2012/10/aspnet-45-mvc-4-revisiting-IBundleTransform-in-bundling.html">Web Optimization Framework</a>, DotNetOpenAuth packages for enabling <a href="http://www.dotnetexpertguide.com/2012/08/facebook-twitter-oauth-openid-login-with-aspnet-mvc-4-application.html">oAuth login</a> after upgrade. It will also add AuthConfig.cs & BundleConfig.cs in App_Start directory. To enable oAuth & Bundling, we need to add following line in Application_Start in global.asax.cs.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt">BundleConfig.RegisterBundles(BundleTable.Bundles);</pre><!--CRLF--><pre class="alteven">AuthConfig.RegisterAuth();</pre><!--CRLF--></div></div>
<p>Once we upgrade with this package, Visual Studio will ask to reload project as we are changing project type from MVC 3 to MVC 4.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-f-L0F7Mfjjo/UQ6YU2TdffI/AAAAAAAABVM/J2dg88m4pqk/s1600/project%2Breload.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="115" width="400" src="http://1.bp.blogspot.com/-f-L0F7Mfjjo/UQ6YU2TdffI/AAAAAAAABVM/J2dg88m4pqk/s400/project%2Breload.png" /></a></div>
<h4>How to test upgrade is success or not?</h4>
<p>Yes... here is quick tip. Copy any view let say <b>Index.cshtml</b> and copy it and rename it to <b>Index.mobile.cshtml</b>. Now browse upgraded MVC 4 application with mobile simulator or override user agent in browser.</p>
<p>Hope It will be helpful and do let me know your feedback here in comment.</p>
<p>Project URL: <a target="_blank" href="https://github.com/NandipMakwana/UpgradeMvc3ToMvc4">https://github.com/NandipMakwana/UpgradeMvc3ToMvc4</a></p>
<p>NuGet URL: <a target="_blank" href="https://nuget.org/packages/UpgradeMvc3ToMvc4">https://nuget.org/packages/UpgradeMvc3ToMvc4</a></p>
<p class="updated-text"><a href="https://twitter.com/NandipMakwana/status/301362923916386304" target="_blank">One of the reader</a> run in error <b>Could not load file or assembly 'System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.</b> solution to this error is answered on this <a href="http://stackoverflow.com/questions/9431975/could-not-load-file-or-assembly-system-net-http-version-2-0-0-0-in-mvc4-web-ap#10249823" target="_blank">Stack Overflow question</a></p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-52685364288944333032013-01-20T19:11:00.000+05:302013-11-06T18:28:33.013+05:30ASP.NET MVC: Order of view selection<p>Few days ago, I and one of my friends were discussing basic of <a href="http://www.dotnetexpertguide.com/search/label/MVC">ASP.NET MVC</a>. After some discussion we came on point in which order views are selected. Because there can be more than one view with same name. For e.g. we can have <b>index.aspx, index.ascx, index.cshtml, index.vbhtml and all this can be in controller specific folder as well shared folder</b>. So in which order view is getting selected? Which view has higher priority? So to getting it clearly, quickly I changed action method to return view which does not exists as mentioned below.</p>
<a name='more'></a>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> ActionResult Index()</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> View(<span class="str">"NotExists"</span>);</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>We built application and run it and it throw an exception <b>The view 'NotExists' or its master was not found or no view engine supports the searched locations. <u>The following locations were searched:</u></b></p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-XL96_ktyq_Y/UPvxJ1K3X-I/AAAAAAAABUg/_u9w-7cN00Q/s1600/Order%2Bof%2Bview%2Bselection.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-XL96_ktyq_Y/UPvxJ1K3X-I/AAAAAAAABUg/_u9w-7cN00Q/s1600/Order%2Bof%2Bview%2Bselection.png" /></a></div>
<p>"A picture is worth a thousand words" Based on above exception and image we can conclude following order of view selection.</p>
<ul>
<li>View/[CONTROLLER]/[VIEW].aspx</li>
<li>View/[CONTROLLER]/[VIEW].ascx</li>
<li>View/Shared/[VIEW].aspx</li>
<li>View/Shared/[VIEW].ascx</li>
<li>View/[CONTROLLER]/[VIEW].cshtml</li>
<li>View/[CONTROLLER]/[VIEW].vbhtml</li>
<li>View/Shared/[VIEW].cshtml</li>
<li>View/Shared/[VIEW].vbhtml</li>
</ul>
<p>So hope this quick post would be helpful to understand order of view selection in ASP.NET MVC. Stay tuned to upcoming post to know how we can change this order of view selection and how it could hit <a href="http://www.dotnetexpertguide.com/search/label/Performance">performance</a> gain.</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-17461841403063697342013-01-18T19:00:00.000+05:302013-11-06T18:28:05.197+05:30ASP.NET: JavaScript Source Maps with Microsoft Ajax Minifier<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-_rlleTuodNA/UNXc5XYO3xI/AAAAAAAABNA/TzyNfNuLeZM/s1600/ASP.NET.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="http://3.bp.blogspot.com/-_rlleTuodNA/UNXc5XYO3xI/AAAAAAAABNA/TzyNfNuLeZM/s200/ASP.NET.png" width="150" /></a></div>
<p>3 days back jQuery announced <a target="_blank" href="http://blog.jquery.com/2013/01/15/jquery-1-9-final-jquery-2-0-beta-migrate-final-released/">release of jQuery 1.9</a>. One of the great things with this release is that it is shipped with <a target="_blank" href="http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/">Source Maps</a>. However in general there are very rare scenarios where we require to debug jQuery but still this would be really helpful to vast community specially contributor. </p>
<div style="clear:both;"></div>
<a name='more'></a>
<p>Now as a being web developer (more specific <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> developer), first question arise is that how do I generate JavaScript source map for my custom component or JavaScript library in visual studio and <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> application? So here in this post we will see how to configure <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> web application to generate minified version of JavaScript and JavaScript source map at build time.</p>
<p>To get started, download & install <a target="_blank" href="http://ajaxmin.codeplex.com/">Microsoft Ajax Minifier</a>. Microsoft Ajax Minifier enables us to minify JavaScript and CSS. It also included Visual Studio build task so we can minify JavaScript and CSS at build time. Microsoft Ajax Minifier also supports <a target="_blank" href="http://ajaxmin.codeplex.com/wikipage?title=SourceMaps">source map generation</a>. Naming convention for source map is <b>output-min-filename.map</b>. </p>
<p>So to see it in action follow the below quick step and get sample ready! </p>
<ul>
<li>Create web application project</li>
<li>Add your JavaScript component file to project</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-o0cK5rmmri0/UPk7TUltZaI/AAAAAAAABTk/CBCkVT6J4H4/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-o0cK5rmmri0/UPk7TUltZaI/AAAAAAAABTk/CBCkVT6J4H4/s1600/1.png" /></a></div>
<ul>
<li>Open <b>.csproj</b> file in editor and add build task as mentioned below</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Vw66NcAErTU/UPk7T74RfCI/AAAAAAAABTw/4AK_EaH2fSk/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-Vw66NcAErTU/UPk7T74RfCI/AAAAAAAABTw/4AK_EaH2fSk/s1600/2.png" /></a></div>
<ul>
<li>Now build project and open windows explorer and navigate where JavaScript file is located. Here we can see generated minified file along with source map</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-V91UNGgE-wI/UPk7UXfZi9I/AAAAAAAABT8/r1sUxoTyqTE/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-V91UNGgE-wI/UPk7UXfZi9I/AAAAAAAABT8/r1sUxoTyqTE/s1600/3.png" /></a></div>
<p>So this was all about how we can generate JavaScript source map in ASP.NET application with Microsoft Ajax Minifier build task. </p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-37138194807663122172013-01-06T01:33:00.000+05:302013-11-06T18:27:38.780+05:30C#: String [Dictionary] encryption with cryptography<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-pGqtz3iBQdM/UOfmcmHUTbI/AAAAAAAABRA/LNW3Hl1QlBQ/s1600/encryption.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-pGqtz3iBQdM/UOfmcmHUTbI/AAAAAAAABRA/LNW3Hl1QlBQ/s1600/encryption.png" /></a></div>
<p>In last post, we have seen <a href="http://www.dotnetexpertguide.com/2013/01/aspnet-mvc-value-provider-for-encrypted-query-string.html">how we can leverage ASP.NET MVC framework extensibility to handle encrypted query string</a>. After reading that post one reader asked how to encrypt/decrypt query string (i.e. dictionary) in ASP.NET. We had <a href="http://www.dotnetexpertguide.com/2013/01/aspnet-mvc-value-provider-for-encrypted-query-string.html#comment-755683633">some discussion on post comment</a> and found that after encrypting query string user run in another error "The request filtering module is configured to deny a request that contains a double escape sequence" while using encrypted string as route value. So I thought to write post on string encryption/decryption which discuss precautions before using it as part of URL. However I cant post actual implementation here but we will look in other solution. (I am not much sound in cryptography still we will try to learn together <b>:)</b>.)</p>
<div style="clear:both;"></div>
<a name='more'></a>
<h4>Encryption, Cryptography & string</h4>
<p>All cryptographic operation is done on byte and not on string so we need to create byte array from string. And in case of encrypted query string, we need to create string from query string dictionary and I recommend to apply some cryptography operation on string rather than just applying plus/minus or similar operation on character.</p>
<h4>String Encryption</h4>
<p>So here we will try to understand string encryption with code snippet.</p>
<h4>1. Create string from dictionary</h4>
<p>Following code snippet show how to create string from dictionary.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<div id="codeSnippet" class="csharpcode"><pre class="alt"><span class="kwrd">static</span> <span class="kwrd">string</span> StringFromDictionary(Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> dictionary)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> <span class="kwrd">string</span>.Join(<span class="str">"-"</span>, dictionary.Select(d => d.Key + <span class="str">"+"</span> + d.Value));</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<h4>2. Convert string in byte array</h4>
<p>As we noted earlier, all cryptographic operation are done on byte and not on string so we need to create byte array from string.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<div id="codeSnippet" class="csharpcode"><pre class="alt"><span class="kwrd">byte</span>[] queryString = Encoding.UTF8.GetBytes(StringFromDictionary(dictionary));</pre><!--CRLF--></div></div>
<h4>3. Apply encryption on byte array</h4>
<p>Now we have byte array ready so we can apply cryptographic operation on it. For this post we are using .NET framework <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx" target="_blank">RijndaelManaged</a> class.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="rem">// Change keyBytes or generate based on some logic</span></pre><!--CRLF--><pre class="alteven"><span class="rem">// We are using IV (Initialization Vector) same as keyBytes </span></pre><!--CRLF--><pre class="alt"><span class="rem">// but strongly recommend to change or generate separate one</span></pre><!--CRLF--><pre class="alteven"><span class="kwrd">byte</span>[] keyBytes = <span class="kwrd">new</span> <span class="kwrd">byte</span>[16] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };</pre><!--CRLF--><pre class="alt">RijndaelManaged rijndaelManaged = <span class="kwrd">new</span> RijndaelManaged</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> Mode = CipherMode.CBC,</pre><!--CRLF--><pre class="alteven"> Padding = PaddingMode.PKCS7,</pre><!--CRLF--><pre class="alt"> KeySize = 128,</pre><!--CRLF--><pre class="alteven"> BlockSize = 128,</pre><!--CRLF--><pre class="alt"> Key = keyBytes,</pre><!--CRLF--><pre class="alteven"> IV = keyBytes</pre><!--CRLF--><pre class="alt">};</pre><!--CRLF--></div></div>
<p>Here we have initialized RijndaelManaged instance and now we can use it for encryption and decryption. <b>For demonstrate purpose, I am using same IV (Initialization Vector) as private key but it is strongly recommend to generate separate one</b>.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">static</span> <span class="kwrd">byte</span>[] EncryptBytes(<span class="kwrd">byte</span>[] bytes)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> rijndaelManaged.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length);</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>And we can retrieve encrypted byte as</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">byte</span>[] encryptedBytes = EncryptBytes(queryString);</pre><!--CRLF--></div></div>
<h4>4. Convert encrypted byte array in Base64 string</h4>
<p>Now we have encrypted byte array and we need to convert it in string, but as it is encrypted byte array we are converting it in Base64 format.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">static</span> <span class="kwrd">string</span> ToBase64(<span class="kwrd">byte</span>[] bytes)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">string</span> strBase64;</pre><!--CRLF--><pre class="alteven"> strBase64 = Convert.ToBase64String(bytes);</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> strBase64.Replace(<span class="str">'+'</span>, <span class="str">'-'</span>).Replace(<span class="str">'/'</span>, <span class="str">'_'</span>).Replace(<span class="str">'='</span>, <span class="str">','</span>);</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>After converting it in Base64 we are replacing <b>+/=</b> with <b>-_,</b> because <b>+/=</b> is the only symbol which is part of <a href="http://en.wikipedia.org/wiki/Base64#Examples" target="_blank">Base64 character set</a> and it could change the meaning of URL or it could return in error "The request filtering module is configured to deny a request that contains a double escape sequence". So we are replacing it with <b>-_,</b> and before decryption we will replace it back to <b>+/=</b>.</p>
<h4>String Decryption</h4>
<p>Decryption step is simply reverse of above. Let’s have a quick view of it.</p>
<h4>1. Convert encrypted Base64 string in byte array</h4>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">static</span> <span class="kwrd">byte</span>[] FromBase64(<span class="kwrd">string</span> encryptedText)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> encryptedText = encryptedText.Replace(<span class="str">'-'</span>, <span class="str">'+'</span>).Replace(<span class="str">'_'</span>, <span class="str">'/'</span>).Replace(<span class="str">','</span>, <span class="str">'='</span>);</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> Convert.FromBase64String(encryptedText);</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">byte</span>[] encryptedBytes = FromBase64(encryptedString);</pre><!--CRLF--></div></div>
<h4>2. Apply decryption on byte array</h4>
<p>Once we have encrypted byte array back we can decrypt it with RijndaelManaged.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">static</span> <span class="kwrd">byte</span>[] DecryptBytes(<span class="kwrd">byte</span>[] bytes)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> rijndaelManaged.CreateDecryptor().TransformFinalBlock(bytes, 0, bytes.Length);</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">byte</span>[] decryptedBytes = DecryptBytes(encryptedBytes);</pre><!--CRLF--></div></div>
<h4>3. Populated dictionary from decrypted bytes</h4>
<p>Now we can populate dictionary back from decrypted byte array as explained below.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">static</span> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> DictionaryFromBytes(<span class="kwrd">byte</span>[] bytes)</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">string</span> decryptedString = Encoding.UTF8.GetString(bytes);</pre><!--CRLF--><pre class="alteven"> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> dictionary = <span class="kwrd">new</span> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>>();</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">string</span>[] keyValuePair = decryptedString.Split(<span class="str">'-'</span>);</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">foreach</span> (<span class="kwrd">string</span> key <span class="kwrd">in</span> keyValuePair)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">string</span>[] keyValue = key.Split(<span class="str">'+'</span>);</pre><!--CRLF--><pre class="alt"> dictionary.Add(keyValue[0], keyValue[1]);</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> dictionary;</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<h4>Conclusion</h4>
<p>Here we have discussed how to encrypt string with cryptographic operation and what are the required precautions while using Base64 encoded string in URL. Along with this don’t forget to <a href="http://www.dotnetexpertguide.com/2013/01/aspnet-mvc-value-provider-for-encrypted-query-string.html">read how to implement encrypted query string in ASP.NET MVC application with lesser code</a>.</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-38642587616412667392013-01-01T14:58:00.000+05:302013-11-06T18:27:15.049+05:30ASP.NET MVC Value Provider for encrypted query string<p>By looking at the post title, it is quite clear that we are about to discuss, query string encryption in ASP.NET MVC application. But I am more interested in demonstrating extensibility of ASP.NET MVC framework and how we can leverage it by plugging our custom logic into ASP.NET MVC life cycle.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-e6I8CyF7AG4/UOKfFIZfoyI/AAAAAAAABNs/2L68gGJhvrg/s1600/asp.net%2Bmvc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-e6I8CyF7AG4/UOKfFIZfoyI/AAAAAAAABNs/2L68gGJhvrg/s200/asp.net%2Bmvc.png" width="200" /></a></div>
<p><a href="http://www.dotnetexpertguide.com/search/label/Featured">As always let me start with scratch</a>, recently I came across a <a href="http://www.dotnetexpertguide.com/search/label/MVC">ASP.NET MVC</a> application, where several action method were accepting query string parameter and later we identified that few of them must accept encrypted query string parameter. Along with this I also wanted to make sure that...</p>
<a name='more'></a>
<ul>
<li><b>We don’t want to decrypt query string manually in each action method</b> as there are numerous number of action method were already implanted and it could be increase in further development.</li>
<li><b>Model binding must not break due to this encryption</b> because application was running well without encryption and all code was done accordingly.</li>
<li><b>Once action method start accepting encrypted query string it must not accept plain query string. i.e. without encryption.</b> For e.g. earlier http://localhost/Invoice/ViewInvoice?invoiceid=123 after encryption it could be http://localhost/Invoice/ViewInvoice/ENCRYPTED-QUERY-STRING now it must not serve http://localhost/Invoice/ViewInvoice?invoiceid=123 (this could be possible due to default Value Provider)</li>
<li>In one sentence, <b>I don’t want to change anything in action method implementation not even decryption nor change in action parameter</b> and model binding must take care of this decryption wherever applicable (read <b>only wherever applicable</b>).</li>
</ul>
<p>So I created one Value Provider which handle this decryption logic. For those who don’t know what is Value Provider in ASP.NET MVC.</p>
<p class="updated-text">In one sentence, Value Provider feeds data to model binder.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">using</span> System.Web.Mvc;</pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> <span class="kwrd">class</span> CryptoValueProvider : IValueProvider</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">bool</span> ContainsPrefix(<span class="kwrd">string</span> prefix)</pre><!--CRLF--><pre class="alt"> { }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> ValueProviderResult GetValue(<span class="kwrd">string</span> key)</pre><!--CRLF--><pre class="alteven"> { }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CryptoValueProviderFactory : ValueProviderFactory</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">override</span> IValueProvider GetValueProvider(ControllerContext controllerContext)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> <span class="kwrd">new</span> CryptoValueProvider();</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>And registered this value provider in global.asax.cs as follow.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">protected</span> <span class="kwrd">void</span> Application_Start()</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> ValueProviderFactories.Factories.Insert(0, <span class="kwrd">new</span> CryptoValueProviderFactory());</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>Here we added CryptoValueProvide at 0<sup>th</sup> index because we wanted to give it utmost priority and it started working as we expected model binder took place after decrypting (if it is encrypted) query string. <b>Everything was agreed except point 3 mentioned above.</b> Because now whenever user enter http://localhost/Invoice/ViewInvoice?invoiceid=123 manually at that time CryptoValueProvider does not find valid encrypted query string hence model binder passes model binding request to next ValueProvider i.e. <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.querystringvalueprovider(v=vs.108).aspx" target="_blank">System.Web.Mvc.QueryStringValueProvider</a> (there are total 5 default value provider) and it found valid query string parameter and model binder took place! As per the point 3, this must not allow.</p>
<p>In this case, we need to ensure that for encrypted query string, there must be only one ValueProvider and that is CryptoValueProvider and default value provider must not act in the case of encrypted query string. <b>In other word, we need to change (and not add/insert in) value provider collection run time instead registering it globally via global.asax.cs.</b> </p>
<p>Again this is the point where you should be aware with ASP.NET MVC life cycle to decide where to alter value provider collection. Covering complete life cycle is beyond the scope of this post. I will try to cover in upcoming post but for this post we only require to know that <b>model binding take place after authorization</b>. So we created CryptoValueProviderAttribute <a href="http://www.dotnetexpertguide.com/2012/11/aspnet-mvc-action-filter-series.html">action filter</a> which implements IAuthorizationFilter interface and here in this action filter we can alter value provider collection and we can decorate respective action method (which require encrypted query string) with this attribute. So now with combination of CryptoValueProvider and CryptoValueProviderAttribute we can ensure that the only CryptoValueProvider (and not default 5 value provider) will act in case of encrypted query string and vice-versa.</p>
<h4>Conclusion</h4>
<p>The goal of this post is to demonstrate robust extensibility feature of ASP.NET MVC framework with which we can implement our custom logic out of the box way (Yes of course with lesser code and ease of maintainability). Hope this would be helpful. Comments are welcome and stay connected on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a>.</p>
<p><b>Crypto class which handle encryption and decryption</b></p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> Crypto</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span> Encrypt(Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> keyValue)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="rem">// encrypt query string key value pair</span></pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> <span class="kwrd">static</span> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> Decrypt(<span class="kwrd">string</span> encryptedText)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="rem">// decrypt encrypted query string into key value pair</span></pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p class="updated-text">
<b>Update</b><br/>
For detailed post on how to encrypt/decrypt string/dictionary <a href="http://www.dotnetexpertguide.com/2013/01/csharp-string-dictionary-encryption-with-cryptography.html">read this post</a>.</p>
<p><b>CryptoValueProvider</b></p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CryptoValueProvider : IValueProvider</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> RouteData routeData = <span class="kwrd">null</span>;</pre><!--CRLF--><pre class="alteven"> Dictionary<<span class="kwrd">string</span>, <span class="kwrd">string</span>> dictionary = <span class="kwrd">null</span>;</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">public</span> CryptoValueProvider(RouteData routeData)</pre><!--CRLF--><pre class="alt"> {</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">this</span>.routeData = routeData;</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">bool</span> ContainsPrefix(<span class="kwrd">string</span> prefix)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">if</span> (<span class="kwrd">this</span>.routeData.Values[<span class="str">"id"</span>] == <span class="kwrd">null</span>)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> <span class="kwrd">false</span>;</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">this</span>.dictionary = Crypto.Decrypt(<span class="kwrd">this</span>.routeData.Values[<span class="str">"id"</span>].ToString());</pre><!--CRLF--><pre class="alt"> </pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> <span class="kwrd">this</span>.dictionary.ContainsKey(prefix.ToUpper());</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> ValueProviderResult GetValue(<span class="kwrd">string</span> key)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> ValueProviderResult result;</pre><!--CRLF--><pre class="alteven"> result = <span class="kwrd">new</span> ValueProviderResult(<span class="kwrd">this</span>.dictionary[key.ToUpper()], </pre><!--CRLF--><pre class="alt"> <span class="kwrd">this</span>.dictionary[key.ToUpper()], CultureInfo.CurrentCulture);</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> result;</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p><b>CryptoValueProviderAttribute</b></p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> CryptoValueProviderAttribute : FilterAttribute, IAuthorizationFilter</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">void</span> OnAuthorization(AuthorizationContext filterContext)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> filterContext.Controller.ValueProvider = <span class="kwrd">new</span> CryptoValueProvider(filterContext.RouteData);</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p><b>Usage</b></p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt">[CryptoValueProvider]</pre><!--CRLF--><pre class="alteven"><span class="kwrd">public</span> ActionResult ViewInvoice(<span class="kwrd">int</span> invoiceid)</pre><!--CRLF--><pre class="alt">{</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> View();</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.comtag:blogger.com,1999:blog-7819331473560289523.post-46574195351368765492012-12-22T21:59:00.000+05:302013-11-06T18:24:15.903+05:30ASP.NET MVC: Accessing base controller from view<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-_rlleTuodNA/UNXc5XYO3xI/AAAAAAAABNA/TzyNfNuLeZM/s1600/ASP.NET.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-_rlleTuodNA/UNXc5XYO3xI/AAAAAAAABNA/TzyNfNuLeZM/s1600/ASP.NET.png" /></a></div>
<p>Today, I was examining one ASP.NET MVC application for code optimization. And at the same time as a part of code rearrangement, I required to access base controller instance from view. So here in this post we will see how we can access base controller instance from within view. Before looking at actual implementation, let me describe how all controller were arranged.</p>
<div style="clear:both;"></div>
<a name='more'></a>
<h4>Controller structure</h4>
<p>In MVC application, we had one controller named <b>BaseController</b> derived from <b>System.Web.Mvc.Controller</b> and all other application controller were derived from this <b>BaseController</b> so we can have <a target="_blank" href="http://en.wikipedia.org/wiki/Hooking">hook</a> in case if we require to plug some logic or extend all controller at later time. Following is pseudo code for the same.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> BaseController : Controller</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">private</span> <span class="kwrd">string</span> _userRole;</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">string</span> UserRole</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> get { <span class="kwrd">return</span> _userRole; }</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--><pre class="alteven"> </pre><!--CRLF--><pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> HomeController : BaseController</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> ActionResult Index()</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> <span class="kwrd">return</span> View();</pre><!--CRLF--><pre class="alteven"> }</pre><!--CRLF--><pre class="alt">}</pre><!--CRLF--></div></div>
<p>In above pseudo code, for illustrative purpose we have put one property which expose role of logged in user. From within controller, we can access it with <b>this.UserRole</b> but we cannot access it directly from view. </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-GprB8Q4Ldd0/UNXc6uL_ImI/AAAAAAAABNM/b0I-B2V2giM/s1600/aspnet-mvc-ViewContext.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-GprB8Q4Ldd0/UNXc6uL_ImI/AAAAAAAABNM/b0I-B2V2giM/s1600/aspnet-mvc-ViewContext.png" /></a></div>
<p>As we can see in above image that we can access <b>ControllerBase</b> with <b>@ViewContext.Controller</b> but we can’t access our base controller directly. However we can cast <b>@ViewContext.Controller</b> in <b>BaseController</b> because our <b>BaseController</b> is inherited from <b>System.Web.Mvc.Controller</b> which is again inherited from <b>ControllerBase</b> class. But each time casting <b>@ViewContext.Controller</b> is not good way better we create extension method which cast it and return <b>BaseController</b> instance. So below is the code which adds extension method to <b>ViewContext</b> class.</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper"><div id="codeSnippet" class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> ViewContextExtension</pre><!--CRLF--><pre class="alteven">{</pre><!--CRLF--><pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">static</span> BaseController BaseController(<span class="kwrd">this</span> ViewContext view)</pre><!--CRLF--><pre class="alteven"> {</pre><!--CRLF--><pre class="alt"> BaseController baseController = (BaseController)view.Controller;</pre><!--CRLF--><pre class="alteven"> <span class="kwrd">return</span> baseController;</pre><!--CRLF--><pre class="alt"> }</pre><!--CRLF--><pre class="alteven">}</pre><!--CRLF--></div></div>
<p>Once we add above code we can access base controller with <b>@ViewContext.BaseController()</b> and hence we can also access <b>@ViewContext.BaseController().UserRole</b> and all other member of base controller from view. Hope this would be hopeful!</p>
<p><i>You can follow me on <a href="https://twitter.com/NandipMakwana" target="_blank">twitter</a> for latest link and update on <a href="http://www.dotnetexpertguide.com/search/label/ASP.NET">ASP.NET</a> & <a href="http://www.dotnetexpertguide.com/search/label/MVC">MVC</a>.</i></p>Nandip Makwanahttp://www.blogger.com/profile/07942831860038209121noreply@blogger.com