How to load Javascript for the whole application except few folders or area?

When you want to load a specific resource like a Javascript file or a CSS file depending of a view, you can use a RenderSection.

On the other hand, if you always want to load this Javascript file (or CSS) but not in some folder, how can you do it? This can be resolved by using _ViewStart.cshtml file. Every folders can have a defined _ViewStart.cshtml which allow you to choose which Layout to use.

@{
    Layout = "~/Views/Shared/_MasterPage.cshtml";   
}

This is an example of a _ViewStart.cshtml page that define the Layout. If you are using Area within your application, you can have an Area which doesn’t use the same Layout. This can be defined by adding this file to the folder of your views and you change the Layout. It can be at the root of the Area’s view folder or directly into the folder of a specific view. Asp.Net MVC will execute ALL _ViewStart.cshtml from the root to the view. That mean that if you define something at the root, this will remain if not overwritten. It work’s fine with the Layout property which can be redefined in a folder which will override the default _ViewStart.cshtml value.

So, if you want to load a Javascript file for all view except one Area, you cannot do :

//_ViewStart.cshtml : At the root for every views
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    <script src="@Url.Content("~/Scripts/myFile.js")" type="text/javascript" > </script>
}
//_ViewStart.cshtml : Inside the View directory of the Area
@{
    Layout = "~/Views/Shared/_Layout.cshtml";    
}

This won’t work because the _ViewStart.cshtml will be executed first and add the script.

To solve this issue you can use TempData.

//_ViewStart.cshtml : At the root for every views
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewContext.TempData.Add("MyFileKey", @Url.Content("~/Scripts/MyFile.js"));
}
//_ViewStart.cshtml : Inside the View directory of the Area
@{
    Layout = "~/Views/Shared/_Layout.cshtml";   
	ViewContext.TempData.Remove("MyFileKey");
}

This require you to modify the Layout also :

<head>
...
    
	@if(ViewContext.TempData.ContainsKey("MyFileKey"))
	{
	  <script src="@ViewContext.TempData["MyFileKey"]" type="text/javascript" > </script>
	}
...
</head>

That’s it. You have now the Javascript file loaded for the whole application except those areas where it removes it from the TempData. Of course, a even better solution would be to use an object that can have multiple resources which are then handled in the Layout. The goal here is just to show you a way to handle Javascript and CSS file with the perspective of Area where this one remove additionnal resource.

How to have a JQuery function using call back with parameter

Let say that you want to use a JQuery function and do something when this one end. This is possible with callback that most of JQuery function does have. Unfortunatly, you might want to pass data to the call back function when this one may not let you. How to handle this situation? This is what we will see in this short article concerning JQuery and call back function.

First of all, why would we want to pass information to callback? Couldn’t we simply use anonymous function and access data from the outer scope? True, but this may lead to big chunk of code and also cause to repeat code. Let take the following example where an Ajax call is done. We want to hide a division, set the value from the ajax call and then display the division again. But, we may not the division already visible, in this case we just want to set the data and display the division.

 $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: /*...*/,
        dataType: 'json',
        url: /*...*/,
        success: function (result) {
            var resultJson = $.parseJSON(result);
            if ($("#myDivisionWhereTheDataBelong").is(":visible")) {
                $("#myDivisionWhereTheDataBelong").slideUp(150, /*Set data from Ajax call here + Show Division Again*/);
            } else {
                /*Set data from Ajax call here + Show Division Again*/
            }
        }
    });

This illustrate the goal of this article. How can you “set the data from Ajax and show the division” without having twice the same code. The first reflex may be to create a function but let’s write first the code repeated in both place to illustrate a functionnal code that is simply just not optimized.

 $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: /*...*/,
        dataType: 'json',
        url: /*...*/,
        success: function (result) {
            var resultJson = $.parseJSON(result);
            if ($("#myDivisionWhereTheDataBelong").is(":visible")) {
                $("#myDivisionWhereTheDataBelong").slideUp(150, function(){
            $('#FormInput1').val(resultJson.Val1);
            $('#FormInput2').val(resultJson.Val2);
            $("myDivisionWhereTheDataBelong").slideDown(150);
				});
            } else {
                $('#FormInput1').val(resultJson.Val1);
                $('#FormInput2').val(resultJson.Val2);
                $("myDivisionWhereTheDataBelong").slideDown(150);
            }
        }
    });

As you can see, it’s not pretty because we duplicate code but it works.

The second step is to create a function but the main problem is that slideUp takes only a call back function that doesn’t have any parameter.

var showResult = function(resultJson) {
      $('#FormInput1').val(resultJson.Val1);
      $('#FormInput2').val(resultJson.Val2);
      $("myDivisionWhereTheDataBelong").slideDown(150);
}
 $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: /*...*/,
        dataType: 'json',
        url: /*...*/,
        success: function (result) {
            var resultJson = $.parseJSON(result);
            if ($("#myDivisionWhereTheDataBelong").is(":visible")) {
              $("#myDivisionWhereTheDataBelong").slideUp(150,showResult);
            } else {
               showResult(resultJson);
            }
        }
    });

This won’t work because we do not pass to showResult method any parameter, and even by writing ‘showResult(resultJson)’ it won’t do much more. In fact, we need to pass a pointer to a function without parameter.

var showResult = function(resultJson) {
    return function() {
       $('#FormInput1').val(resultJson.Val1);
       $('#FormInput2').val(resultJson.Val2);
       $("myDivisionWhereTheDataBelong").slideDown(150);
    };
};
$.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: /*...*/,
        dataType: 'json',
        url: /*...*/,
        success: function (result) {
            var resultJson = $.parseJSON(result);
            if ($("#myDivisionWhereTheDataBelong").is(":visible")) {
                $("#myDivisionWhereTheDataBelong").slideUp(150,showResult(resultJson));
            } else {
                showResult(resultJson)();
            }
        }
    });

Here you can see multiple modification. First, the function return an other function. This is because we need a parameterless function for the callback. The first method lets you send additionnal information and return a pointer to a method that have access (because of the closure principle of Javascript) to the parameter of the outer function. The second modifification is in the else. You now call the method which take a single parameter but it requires you to call again the return anonymous function. This is why you have ‘showResult(resultJson)()’;

How to create a fall back to html5 placeholder for Internet Explorer with Modernizr library

Modernizr is a small javascript library that work in parallel of your main library (like JQuery) and make work more advanced features like some CSS3 features or Html5 features on browser that doesn’t support it nativly.

One feature that even Internet Explorer 10 doesn’t handle is the attribute placeholder. Modernizr let you check if the current browser support it, if not create your own custom fall back.

Once you added the Modernizr library to your webpage, you can now create a new javascript file with a function that will test the placeholder feature, if it’s not available will execute some custom code.

<script src="/Scripts/Libs/jquery-1.8.2.js" type="text/javascript"> </script>
<script src="/Scripts/Libs/modernizr-1.7.min.js" type="text/javascript"> </script>


Here is the custom code that will put a placeholder when an input does have the placeholder attribute.

jQuery(function () {
    // check placeholder browser support 
    if (!Modernizr.input.placeholder) 
    {
        // set placeholder values 
        jQuery(this).find('[placeholder]').each(function () 
        {
            if (jQuery(this).val() == '')  // if field is empty 
            {
                jQuery(this).val(jQuery(this).attr('placeholder'));
                jQuery(this).addClass('placeholder');
            }
        }); 
        
        // focus and blur of placeholders 
        jQuery('[placeholder]').focus(function () 
        {
            if (jQuery(this).val() == jQuery(this).attr('placeholder')) {
                jQuery(this).val('');
                jQuery(this).removeClass('placeholder');
            }
        }
		).blur(function () 
        {
            if (jQuery(this).val() == '' || jQuery(this).val() == jQuery(this).attr('placeholder')) 
            {
		        jQuery(this).val(jQuery(this).attr('placeholder'));
		        jQuery(this).addClass('placeholder');
		    }
		}
		);

        // remove placeholders on submit 
		jQuery('[placeholder]').closest('form').submit(function () 
        {
            jQuery(this).find('[placeholder]').each(function ()
            {
                if (jQuery(this).val() == jQuery(this).attr('placeholder')) 
                {
                    jQuery(this).val('');
                }
            });
        });
    }
});

You can also set a class to style the text when it’s in a placeholder mode.

/*Modernizr fall back style for placeholder*/
.placeholder
{
    color:lightgray;
    font-style: italic;
}

Here is how to use it.

<input type="text" placeholder="This is a placeholder text"/>

That’s it, you have now the placeholder feature available for all browser. You only need to use it as you would if the user would have used a more recent browser.

How to execute a huge SQL file with Microsoft Sql Server

Here is a small article that could be more a note than something else. If you have a lot of SQL statement to execute, let say few gigs of statement, this won’t load into SQL Server Manager. What you can do is to use the sqlcmd command. Open a DOS console and go where you have installed Sql Server Mananger. Mine is:

c:\Program Files (x86)\Microsoft SQL Server\90\Tools\Binn

In the console, you need to specify the server and instance you want to execute the file to. Optionnaly, you can write the output to a file.

sqlcmd -S myServer\instanceName -i C:\myScript.sql -o C:\log.txt

That’s it. Nothing more complicated.

Entity Framework 6 (EF6) is in Alpha 1 stage

Microsoft has released few weeks ago the list of features that Entity Framework 6, EF6 will contains.

Here is a summary of the changes that can already used if you use NuGet to download this alpha version.

Framework 4.0 and Entity Framework

It’s now possible to use .Net 4.0 framework with Entity Framework 6 and have enumeration support, performance increase and spatial support. With EF5.0, we had to upgrade to .Net 4.5. They have moved from .Net into EF6.0 the code required to benefit from these 3 subjects. This is a good news because it will increase the migration from EF4 to EF6 without having to upgrade the framework. For small project it wasn’t an issue, but for bigger project, the cost (and the fear) to upgrade was seen as a show blocker for some people.

EF 6.0 is more open

Entity Framework 6.0 has changed is open source agreement and to be fully compatible they had to open few things. Now, it doesn’t use the provider of Ado.Net. This mean that you have to change the configuration file to provide the provider of your choice. Of course, most if not all scenario will (should) use Ado.Net as provider. Nonetheless, it’s not configurable.

Not only it’s more open for the provider but a lot of interface can be injected. DbSpatialServices, IDbModelCacheKeyFactory, IDbProviderFactoryService, IManifestTokenService, IDbConnectionFactory, MigrationSqlGenerator,IDatabaseInitializer and as said, DbProviderServices can be injected. This is a good new to provide you own implementation of these services.

Migration Update

Some new feature for the migration update mechanism are also available. The first one let you customized the history table and the second let Entity Framework’s context to be multi-tenant. This give you the possibility to have a single DbContext that can communicate to multiple physical database.

Global Entity Configuration

EF6.0 bring custom configuration of entity to an other level. It’s now possible to configure a property globally for all context object. So if for all your entity you have the property ID that is a primary key with the same configuration, instead of defining this one in each entities configuration, you just have to specify it in the convention as part of a rule of your system.

That’s it for the moment, a lot of great improvement is done on EF6.0 and we keep looking forward for new improvement in a more stable release soon.

Entity Framework Schema specified is not valid error

{“Schema specified is not valid. Errors: \r\nThe mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type ‘MyClassName’. Previously found CLR type ‘MyNameSpaceContext.Context.MyClassName’, newly found CLR type ‘MyNameSpaceModel.Domain.MyClassName’.”}

This error occur only if you have 2 classes with the same name in different namespace. It can be quite easy to reproduce without having the goal to do it also. How it’s done? It’s done because the Linq to Entity use model classes instead of context classes. Entity Framework can only manipulate classes that are registered to it, context classes, and not other classes even if those one are very similar.

For example, if you want to return a list of MyClassName (context) class which are inside a collection of MyClassName (domain model), you can have this problem.

var fromDatabase = _dataContext.Set<MyClassName>().Where(p => listMyClass.Select(d => d.ID).Contains(p.ID));

This won’t work because listMyClass contain a list of MyClassName, but from the domain model not the context. It’s easy to get wrong because usually the service layer and the repository layer receive as parameter domain object and not directly the context. To solve this issue, you need to proceed into two steps. The select to get the list of id must be done outside Linq To Entity. This way, the code will be executed as Linq to Object and won’t affect Entity Framework.

var arrayId = listMyClass.Select(d => d.ID).ToArray();
var fromDatabase = _dataContext.Set<MyClassName>().Where(p => arrayId.Contains(p.ID));

That’s it! Now it works because listMyClass is transformed into an array of ID which Entity Framework understand.

Enterprise Asp.Net MVC Part 7: Securing action with role authorization

In previous article of the enterprise asp.net mvc series we have choose to allow anonymous not by default and to secure to logged used most of the actions possible. This is great but not enough if we want to have some action available only for specific role. In this article, I’ll show you how to authorize specific role to be mapped to action and to keep the security for anonymous. Also, we will see how to have custom error page for unauthorized action instead of the login screen that Asp.Net MVC redirect when the authorization is unsuccessful.

First of all, we will need to create a new Authorize attribute. This is not because Asp.Net MVC 4 doesn’t provide the attribute but because Asp.Net MVC 4 act the same way for authorized access (401) and a forbidden access (403). We want when it’s an authorized access (not logged) to redirect to the login screen and when it’s the forbidden access (not being in the role) to be redirected to a view saying something and not the login form.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public sealed class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
	public AuthorizeAttribute()
	{
		ErrorArea = string.Empty;
		ErrorController = "Error";
		ErrorAction = "Index";
	}

	public string ErrorArea { get; set; }
	public string ErrorController { get; set; }
	public string ErrorAction { get; set; }


public override void OnAuthorization(AuthorizationContext filterContext)
{
          
    base.OnAuthorization(filterContext);
    if (AuthorizeCore(filterContext.HttpContext))
        return;
    if (filterContext.HttpContext.Request.IsAuthenticated)
    {
        if (ErrorController != null)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
                                                                                            {
                                                                                                action =ErrorAction,
                                                                                                controller =ErrorController,
                                                                                                area = ErrorArea
                                                                                            }));
        }
        else
        {
            filterContext.Result = new HttpStatusCodeResult((int)HttpStatusCode.Forbidden);
        }
    }
    else
    {
        filterContext.Result = null;
    }
}
}

This is the attribute class. This class check if the user is authenticated, if not, will redirect to the normal process and return a 401 http status with the login form. If the user is authenticated, the status code is changed to 403 if no controller is specified, otherwise, will redirect to a specific controller/action. By default, I have set a controller and action, this way, it’s more user friendly to have a real page inside the page layout than the default 403 IIS page. Of course, it’s up to you to choose what you prefer. However, I believe that not only it’s more user friendly but this way give you the possibility to log forbidden access and to have custom message.

To use this new AuthorizeAttribute, we need to change the default filter set to every action. In Asp.Net MVC 4, you need to search for FilterConfig.cs

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new Views.AuthorizeAttribute());
    }
}

The line 6 has been replaced by or AuthorizeAttribute. This won’t do such a big change since the access by default isn’t set. But, when an action shall be protected by a specific role, this is where the custom authorize class shine.

[HttpGet]
[Views.Authorize(Roles = Models.Roles.ADMINISTRATOR)]
public ActionResult Create()
{
    var x = ServiceFactory.Exercise.New(Model);
    return View("Create",x);
}

As you can see in the code above, if the use is not an administrator than this one will be redirected to the default error page.

At anytime, you also can specify a specific controller and action if for a special case you need to do something else for a forbidden access.

[Views.Authorize(Roles = Models.Roles.ADMINISTRATOR, ErrorController = "CustomerController", ErrorAction = "LogAndRedirect")]
public ActionResult Create()
{
    var x = ServiceFactory.Exercise.New(Model);
    return View("Create",x);
}

To conclude, it’s possible to have distinct page for authorized access and forbidden access. I strongly believe it’s important to do something different since it’s counter intuitive to display to login form when someone is already logged without the right role. It’s fundamental that the user know what’s going on and this is why a redirection to a custom error’s controller seem the natural solution to this problem.

Series Articles

Article #1: Asp.Net MVC Enterprise Quality Web Application
Article #2: Asp.Net MVC Enterprise Quality Web Application Model
Article #3: Asp.Net MVC Enterprise Quality Web Application Controller
Article #4: Asp.Net MVC Enterprise Quality Web Repository Layer
Article #5: Asp.Net MVC Enterprise Quality Web with Entity Framework
Article #6: Asp.Net MVC Enterprise Quality Layers
Article #7: Asp.Net MVC Enterprise Quality Web Security

Source code on GitHub

Selectivizr example : how to use CSS selector with older browser

Selectivizr is a small javascript library (under 20ko when not compressed and under 5ko when compressed) that has the goal to make work your CSS with older browser like IE8, IE7, IE6. Selectivizr require you to have a javascript library to your html file. This is not a problem usually because most website use JQuery. So, to make it works, first download Selectivizr.

Second, go just under the line where you add JQuery and add the following code.

	<script src="@Url.Content("~/Scripts/Libs/jquery-1.8.2.js")" type="text/javascript"> </script>
	<!--[if (gte IE 6)&(lte IE 8)]>
	  <script type="text/javascript" src=@Url.Content("~/Scripts/Libs/selectivizr.js")></script>
	<![endif]-->

Of course, the code above use Url.Content that come from the Asp.Net framework but you could simply add both Javascript with a relative or absolute path manually. So, it works with any web framework like PHP.

From here, all code that were using more specific selector like :hover, :focus, :first-child, :last-child, :nth-child, :not… will works!

What happen it’s that it will be simulate with Javascript instead of using CSS for IE 6-8 and will remain with CSS for all others browser.

How to add dynamic property to your class with ExpandoObject

In some scenario, you may want to add dynamically information to your object without having to define a specific type or interface. This type of scenario has been developed by Asp.Net MVC with the ViewBag which let you add any type of information dynamically. In a project, you may want to have this kind of behavior and be able to add information of different type and to access it later.

To do, you need to use the ExpandoObject.

public class YourClass
{
	public int Id{ get; set; }
	public dynamic Attributes { get; set; }

	public MatriceRow()
	{
		Attributes = new ExpandoObject();
	}
}

This is a working example. From there you can use the YourClass class and set attributes.

 var myClass = new YourClass();
 myClass.Id = 1;
 myClass.Attributes.IsBoolean = true;
 myClass.Attributes.MyName = "Patrick Desjardins";

You cannot define the Attributes property directly to the type of ExpandoObject. If you do, you will get an exception.

‘IsBoolean’ and no extension method ‘IsBoolean’ accepting a first argument of type ‘System.Dynamic.ExpandoObject’ could be found (are you missing a using directive or an assembly reference?)

This functionality should be used rarely. It’s always better to be strongly typed and not use dynamic because this one is only checked when the code is executed rather than when compiled.

Linq and grouping with custom object

Depending of what you want to do, you may want to group by id or by more values. A common case is to group by a unique idenfier but also want to get some connexe information like let say having the name. For example, if we want to group every jobs that every body had in their life, we would like to group by userid. But we may want to have their full name.

var groupedList = nonGroupedList.GroupBy(g=> new MyCustomGroupingClass(g.UserId, g.UserFullName));

This won’t work because every MyCustomGroupingClass will be different from C# perspective. This is because Linq will compare every object and figure out that every MyCustomGroupingClass has a different object.

var groupedList = nonGroupedList.GroupBy(g=> g.UserId);

This would work, because an integer is comparable but it doesn’t solve the need to have the user name.

The solution is hidden in the problem : comparing classes. We need to provide a way to compare. This can be done by providing an override to the Equals method of your grouping class.

public class MyCustomGroupingClass
{
	public int ID { get; set; }
	public string FullName { get; set; }

	public override bool Equals(object obj)
	{
		if (ReferenceEquals(null, obj)) return false;
		if (ReferenceEquals(this, obj)) return true;
		if (obj.GetType() != this.GetType()) return false;
		return Equals((MyCustomGroupingClass)obj);
	}
	protected bool Equals(MyCustomGroupingClass other)
	{
		return ID.Equals(other.ID) && string.Equals(FullName, other.FullName);
	}
}

From here, you will be able to group without problem with Linq and your custom grouping class.