Shaun Xu

The Sheep-Pen of the Shaun


News

logo

Shaun, the author of this blog is a semi-geek, clumsy developer, passionate speaker and incapable architect with about 10 years experience in .NET. He hopes to prove that software development is art rather than manufacturing. He's into cloud computing platform and technologies (Windows Azure, Aliyun) as well as WCF and ASP.NET MVC. Recently he's falling in love with JavaScript and Node.js.

Currently Shaun is working at IGT Technology Development (Beijing) Co., Ltd. as the architect responsible for product framework design and development.

MVP

My Stats

  • Posts - 97
  • Comments - 346
  • Trackbacks - 0

Tag Cloud


Recent Comments


Recent Posts


Archives


Post Categories


 

Microsoft just released an example named Microsoft Townhall which was built and deployed on Azure. It uses ASP.NET MVC as its webiste framework and the SQL Azure plus LinqToSQL as its the database and the ORM framework. You can download the source code at the MSDN Code Gallery.

image

Basides the Azure it might be more useful to us to learn how they utilized ASP.NET MVC. Just a very quickly review I found it utilized the Enterprise Library Unity as the main IoC container for controllers, services and repositories and customized a lot of ModelBinders, Filters, etc.

 

Hope this helps,

Shaun

 

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.

 

Just knew from Wang Tao that Microsoft will launch the Web Camp event in many cities to share their technologies and experience on web application building. The topics of this Web Camps would focus on ASP.NET, jQuery and Entity Frameworks and how to build a cool web application based on them which I’m very interesting. And another reason is that, it’s FREE.

 

Please have the detail information and register at http://www.webcamps.ms/, which is built on Windows Azure. And the speaker in Beijing would be Scott Hanselam and James Senior – WOW!

 

Hope this helps,

Shaun

 

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.


 

One of my colleague and friend, Robin is playing and struggling with the ASP.NET MVC 2 on a project these days while I’m struggling with a annoying client. Since it’s his first time to use ASP.NET MVC he was meetings with a lot of problem and I was very happy to share my experience to him. Yesterday he asked me when he attempted to insert a <br /> element into his page he found that the page was rendered like this which is bad.

image

He found his <br /> was shown as a part of the string rather than creating a new line. After checked a bit in his code I found that it’s because he utilized a new ASP.NET markup supported in .NET 4.0 – “<%: %>”.

image

If you have been using ASP.NET MVC 1 or in .NET 3.5 world it would be very common that using <%= %> to show something on the page from the backend code. But when you do it you must ensure that the string that are going to be displayed should be Html-safe, which means all the Html markups must be encoded. Otherwise this might cause an XSS (cross-site scripting) problem. So that you’d better use the code like this below to display anything on the page.

image In .NET 4.0 Microsoft introduced a new markup to solve this problem which is <%: %>. It will encode the content automatically so that you will no need to check and verify your code manually for the XSS issue mentioned below. But this also means that it will encode all things, include the Html element you want to be rendered. So I changed his code like this and it worked well.

image

After helped him solved this problem and finished a spreadsheet for my boring project I considered a bit more on the <%: %>. Since it will encode all thing why it renders correctly when we use “<%: Html.TextBox(“name”) %>” to show a text box? As you know the Html.TextBox will render a “<input name="name" id="name" type="text"/>” element on the page. If <%: %> will encode everything it should not display a text box. So I dig into the source code of the MVC and found some comments in the class MvcHtmlString.

   1: // In ASP.NET 4, a new syntax <%: %> is being introduced in WebForms pages, where <%: expression %> is equivalent to
   2: // <%= HttpUtility.HtmlEncode(expression) %>. The intent of this is to reduce common causes of XSS vulnerabilities
   3: // in WebForms pages (WebForms views in the case of MVC). This involves the addition of an interface
   4: // System.Web.IHtmlString and a static method overload System.Web.HttpUtility::HtmlEncode(object).  The interface
   5: // definition is roughly:
   6: //   public interface IHtmlString {
   7: //     string ToHtmlString();
   8: //   }
   9: // And the HtmlEncode(object) logic is roughly:
  10: //   - If the input argument is an IHtmlString, return argument.ToHtmlString(),
  11: //   - Otherwise, return HtmlEncode(Convert.ToString(argument)).
  12: //
  13: // Unfortunately this has the effect that calling <%: Html.SomeHelper() %> in an MVC application running on .NET 4
  14: // will end up encoding output that is already HTML-safe. As a result, we're changing out HTML helpers to return
  15: // MvcHtmlString where appropriate. <%= Html.SomeHelper() %> will continue to work in both .NET 3.5 and .NET 4, but
  16: // changing the return types to MvcHtmlString has the added benefit that <%: Html.SomeHelper() %> will also work
  17: // properly in .NET 4 rather than resulting in a double-encoded output. MVC developers in .NET 4 will then be able
  18: // to use the <%: %> syntax almost everywhere instead of having to remember where to use <%= %> and where to use
  19: // <%: %>. This should help developers craft more secure web applications by default.
  20: //
  21: // To create an MvcHtmlString, use the static Create() method instead of calling the protected constructor.

The comment said the encoding rule of the <%: %> would be:

  • If the type of the content is IHtmlString it will NOT encode since the IHtmlString indicates that it’s Html-safe.
  • Otherwise it will use HtmlEncode to encode the content.

If we check the return type of the Html.TextBox method we will find that it’s MvcHtmlString, which was implemented the IHtmlString interface dynamically.

image That is the reason why the “<input name="name" id="name" type="text"/>” was not encoded by <%: %>. So if we want to tell ASP.NET MVC, or I should say the ASP.NET runtime that the content is Html-safe and no need, or should not be encoded we can convert the content into IHtmlString. So another resolution would be like this.

image Also we can create an extension method as well for better developing experience.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.Mvc;
   6:  
   7: namespace ShaunXu.Blogs.IHtmlStringIssue
   8: {
   9:     public static class Helpers
  10:     {
  11:         public static MvcHtmlString IsHtmlSafe(this string content)
  12:         {
  13:             return MvcHtmlString.Create(content);
  14:         }
  15:     }
  16: }

Then the view would be like this.

image And the page rendered correctly.

image

 

 

 

 

Summary

In this post I explained a bit about the new markup in .NET 4.0 – <%: %> and its usage. I also explained a bit about how to control the page content, whether it should be encoded or not. We can see the ASP.NET MVC gives us more points to control the web pages.

 

Hope this helps,

Shaun

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.
 

 

 


 

To be honest I have not been very interested in the caching before I’m going to a project which would be using the multi-site deployment and high connection and concurrency and very sensitive to the user experience. That means we must cache the output data for better performance.

After looked for the Internet I finally focused on the Memcached. What’s the Memcached? I think the description on its main site gives us a very good and simple explanation.

Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering.

Memcached is simple yet powerful. Its simple design promotes quick deployment, ease of development, and solves many problems facing large data caches. Its API is available for most popular languages.

The original Memcached was built on *nix system are is being widely used in the PHP world. Although it’s not a problem to use the Memcached installed on *nix system there are some windows version available fortunately. Since we are WISC (Windows – IIS – SQL Server – C#, which on the opposite of LAMP) it would be much easier for us to use the Memcached on Windows rather than *nix.

I’m using the Memcached Win X64 version provided by NorthScale. There are also the x86 version and other operation system version.

 

Install Memcached

Unpack the Memcached file to a folder on the machine you want it to be installed, we can see that there are only 3 files and the main file should be the “memcached.exe”. Memcached would be run on the server as a service. To install the service just open a command windows and navigate to the folder which contains the “memcached.exe”, let’s say “C:\Memcached\”, and then type “memcached.exe -d install”.

If you are using Windows Vista and Windows 7 system please be execute the command through the administrator role. Right-click the command item in the start menu and use “Run as Administrator”, otherwise the Memcached would not be able to be installed successfully.

Once installed successful we can type “memcached.exe -d start” to launch the service. Now it’s ready to be used. The default port of Memcached is 11211 but you can change it through the command argument. You can find the help by typing “memcached -h”.

image

 

Using Memcached

Memcahed has many good and ready-to-use providers for vary program language. After compared and reviewed I chose the Memcached Providers. It’s built based on another 3rd party Memcached client named enyim.com Memcached Client. The Memcached Providers is very simple to set/get the cached objects through the Memcached servers and easy to be configured through the application configuration file (aka web.config and app.config).

Let’s create a console application for the demonstration and add the 3 DLL files from the package of the Memcached Providers to the project reference.

image

Then we need to add the configuration for the Memcached server. Create an App.config file and firstly add the section on top of it. Here we need three sections: the section for Memcached Providers, for enyim.com Memcached client and the log4net.

   1: <configSections>
   2:   <section name="cacheProvider" 
   3:            type="MemcachedProviders.Cache.CacheProviderSection,  MemcachedProviders" 
   4:            allowDefinition="MachineToApplication" 
   5:            restartOnExternalChanges="true"/>
   6:   <sectionGroup name="enyim.com">
   7:     <section name="memcached" 
   8:              type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching"/>
   9:     </sectionGroup>
  10:   <section name="log4net" 
  11:            type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  12: </configSections>

Then we will add the configuration for 3 of them in the App.config file. The Memcached server information would be defined under the enyim.com section since it will be responsible for connect to the Memcached server. Assuming I installed the Memcached on two servers with the default port, the configuration would be like this.

   1: <enyim.com>
   2:   <memcached>
   3:     <servers>
   4:       <!-- put your own server(s) here-->
   5:       <add address="192.168.0.149" port="11211"/>
   6:       <add address="10.10.20.67" port="11211"/>
   7:     </servers>
   8:     <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00"/>
   9:   </memcached>
  10: </enyim.com>

Memcached supports the multi-deployment which means you can install the Memcached on the servers as many as you need. The protocol of the Memcached responsible for routing the cached objects into the proper server. So it’s very easy to scale-out your system by Memcached.

And then define the Memcached Providers configuration. The defaultExpireTime indicates how long the objected cached in the Memcached would be expired, the default value is 2000 ms.

   1: <cacheProvider defaultProvider="MemcachedCacheProvider">
   2:   <providers>
   3:     <add name="MemcachedCacheProvider" 
   4:          type="MemcachedProviders.Cache.MemcachedCacheProvider, MemcachedProviders" 
   5:          keySuffix="_MySuffix_" 
   6:          defaultExpireTime="2000"/>
   7:   </providers>
   8: </cacheProvider>

The last configuration would be the log4net.

   1: <log4net>
   2:   <!-- Define some output appenders -->
   3:   <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
   4:     <layout type="log4net.Layout.PatternLayout">
   5:       <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
   6:     </layout>
   7:   </appender>
   8:   <!--<threshold value="OFF" />-->
   9:   <!-- Setup the root category, add the appenders and set the default priority -->
  10:   <root>
  11:     <priority value="WARN"/>
  12:     <appender-ref ref="ConsoleAppender">
  13:       <filter type="log4net.Filter.LevelRangeFilter">
  14:         <levelMin value="WARN"/>
  15:         <levelMax value="FATAL"/>
  16:       </filter>
  17:     </appender-ref>
  18:   </root>
  19: </log4net>

 

Get, Set and Remove the Cached Objects

Once we finished the configuration it would be very simple to consume the Memcached servers. The Memcached Providers gives us a static class named DistCache that can be used to operate the Memcached servers.

  • Get<T>: Retrieve the cached object from the Memcached servers. If failed it will return null or the default value.
  • Add: Add an object with a unique key into the Memcached servers.

Assuming that we have an operation that retrieve the email from the name which is time consuming. This is the operation that should be cached. The method would be like this. I utilized Thread.Sleep to simulate the long-time operation.

   1: static string GetEmailByNameSlowly(string name)
   2: {
   3:     Thread.Sleep(2000);
   4:     return name + "@ethos.com.cn";
   5: }

Then in the real retrieving method we will firstly check whether the name, email information had been searched previously and cached. If yes we will just return them from the Memcached, otherwise we will invoke the slowly method to retrieve it and then cached.

   1: static string GetEmailByName(string name)
   2: {
   3:     var email = DistCache.Get<string>(name);
   4:     if (string.IsNullOrEmpty(email))
   5:     {
   6:         Console.WriteLine("==> The name/email not be in memcached so need slow loading. (name = {0})==>", name);
   7:         email = GetEmailByNameSlowly(name);
   8:         DistCache.Add(name, email);
   9:     }
  10:     else
  11:     {
  12:         Console.WriteLine("==> The name/email had been in memcached. (name = {0})==>", name);
  13:     }
  14:     return email;
  15: }

Finally let’s finished the calling method and execute.

   1: static void Main(string[] args)
   2: {
   3:     var name = string.Empty;
   4:     while (name != "q")
   5:     {
   6:         Console.Write("==> Please enter the name to find the email: ");
   7:         name = Console.ReadLine();
   8:  
   9:         var email = GetEmailByName(name);
  10:         Console.WriteLine("==> The email of {0} is {1}.", name, email);
  11:     }
  12: }

The first time I entered “ziyanxu” it takes about 2 seconds to get the email since there’s nothing cached. But the next time I entered “ziyanxu” it returned very quickly from the Memcached.

image

 

Summary

In this post I explained a bit on why we need cache, what’s Memcached and how to use it through the C# application. The example is fairly simple but hopefully demonstrated on how to use it. Memcached is very easy and simple to be used since it gives you the full opportunity to consider what, when and how to cache the objects. And when using Memcached you don’t need to consider the cache servers. The Memcached would be like a huge object pool in front of you.

The next step I’m thinking now are:

  • What kind of data should be cached? And how to determined the key?
  • How to implement the cache as a layer on top of the business layer so that the application will not notice that the cache is there.
  • How to implement the cache by AOP so that the business logic no need to consider the cache.

I will investigate on them in the future and will share my thoughts and results.

 

Hope this helps,

Shaun

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.


 

Just found a good (looks like) tool for jQuery coding and debugging from the appinn.com (Chinese) named jQueryPad by Paul Stovell. With it we don’t need to switch between the visual studio and the browser when coding and debugging.

There’s only one main screen where we can type the HTML and jQuery code and just press F5 to see the result in the bottom frame.

jQueryPad

.NET Frameworks 3.5 is required.

 

Hope this helps.

Shaun

 

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.