Tuesday, October 15, 2013

Custom View Engine in ASP.NET MVC 4

Custom ViewEngine? Do we really need this? Generally not. But I needed this in a project. In the project I needed to override the ViewEngine.

The override ViewEnging looks like follows:

public class MyViewEngine : RazorViewEngine
    {
        public MyViewEngine()
        {
            ViewLocationFormats = new string[]{
                "/Views/Themes/{0}.cshtml",
                "/Views/{1}/{0}.cshtml"
            };
        }
    }

And then in the Application_Start of Global.asak, add the following

protected void Application_Start()
        {
            // ... other code

            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new MyViewEngine());

            // ... more code
        }

Wednesday, October 09, 2013

Email template background image in Outlook Client

Working with email template is really painful. In the era of HTML5, CSS3 and Javascript, we still need to work in table design because of email clients. Here I am concentrating about the Outlook email client where the background image don't work traditional.

If we want to put a background image in a table row then we need to code as following

<tr class="back" style="height: 38px; background: url(imagepath) no-repeat;">
 
 <td width="70%" style="height: 38px; padding: 0 10px;">
  Cell text
 </td>
 
</tr>

Monday, September 16, 2013

URL routing in ASP.NET MVC

In ASP.NET MVC, the routing is very easy. By examine the URL, its automatically find the controller and then actions.



But, to select a single controller for all kinds of URL, followings can help

           routes.MapRoute(
                "Single",
                "{page}",
                new { controller = "Single", action = "Single" }
            );
            routes.MapRoute(
                "SingleChild",
                "{page}/{child}/{*ignore}",
                new { controller = "Single", action = "Child" }
            );
            routes.MapRoute(
                null,
                "",
                defaults: new { controller = "Single", action = "Home" }
            );

Turning output caching off for authenticated users in ASP.NET MVC

While working on ASP.NET MVC 4, I was badly needed to implement caching to speed up the page loading. Caching is very easy to use and also powerful in ASP.NET MVC. But I needed to turn off the caching for admin. Let me explain why I was needed it.

In our CMS, there is an option for the admin to edit the content inline directly in the main website. The admin don't need to go to dashboard and find the content for editing. When the admin will log-in in the website, they will get this options to edit the content. If I cache the website normally, then either admin will not see the option to edit the content or end user will see the option to edit it.

In ASP.NET MVC, it can be possible to show different cache to the end user and admin using VaryByCustom parameter. But this is not the solution. The admin will not see the immediate update that he just made. Therefore I need to turn off the caching for the authenticated users only. 

In ASP.NET MVC, we used OutputCache attribute to do the caching easily. There are some properties by which you can customize the output cache. But these don't solve my problem.

To solve this I needed to create a new Cache class by extending the OutputCacheAttribute class and only override the OnResultExecuting method. OnResultExecuting method is called before the action result executes. In this methods I have checked that if aa user is authenticated then disable caching. Following is my code:

 public class MyCacheAttribute : OutputCacheAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            var httpContext = filterContext.HttpContext;

            if (httpContext.User.Identity.IsAuthenticated)
            {
                // making cach location none means no cache
                base.Location = OutputCacheLocation.None;
            }
            else
            {
                // you can put your favorite cache location
                base.Location = OutputCacheLocation.Any;
            }

            httpContext.Response.Cache.AddValidationCallback(IgnoreAuthenticated, null);
            base.OnResultExecuting(filterContext);
        }

        private void IgnoreAuthenticated(HttpContext context, object data, ref HttpValidationStatus validationStatus)
        {
            if (context.User.Identity.IsAuthenticated)
                validationStatus = HttpValidationStatus.IgnoreThisRequest;
            else
                validationStatus = HttpValidationStatus.Valid;
        }
    }

Now to use the cache as follows
 public class PagesController 
{
      [MyCache(CacheProfile = "Cache_profile")]
      public ActionResult Index(){
           // the codes
           return View();
}

Thursday, April 18, 2013

FQL: query user table by name

I was trying to find Facebook user by querying by name in the user table. According to the Facebook documentation, the name field of user table is indexable. Therefore, logically it is possible to query by name.

But when I query user table by name field, it gives me the error with code 604.

The error message is "Your statement is not indexable. The WHERE clause must contain an indexable column. Such columns are marked with * in the tables linked from http://developers.facebook.com/docs/reference/fql "

The name field of user table is marked with * in the facebook documentation; https://developers.facebook.com/docs/reference/fql/user/.

----

I have googled about it and found the solution in stackoverflow. It says to run the query on profile table by name and get the id of the user. Then query the user table by the id.

SELECT uid FROM user WHERE uid IN (SELECT id FROM profile WHERE name="kamrul hassan")

Source: http://stackoverflow.com/questions/13793567/fql-filter-user-table-by-name

Wish this will help you.