ITmeze - IT world server like cyprus meze

jQuery style Ui dialog over flash banners

Itmeze

I was doing some extra job for one of the clients, some changes on the web site full of blinking flash banners. Idea was to get users' attention even more by displaying some floating windows... lovely ... Obvious choice would be jQuery modal dialog... So I made it ... Unfortunately it has shown up that some of the flash banners remain 'over' the dialog, and some of them don't. After digging into that I figured out that the reason behind that is one of flash parameters: "wmode" (thanks God this is not another inner flash issue). From Adome Knowledge base:
wmode - Possible values: window, opaque, transparent. Sets the Window Mode property of the Flash movie for transparency, layering, and positioning in the browser.
  • window - movie plays in its own rectangular window on a web page.
  • opaque - the movie hides everything on the page behind it.
  • transparent - the background of the HTML page shows through all transparent portions of the movie. This option can slow animation performance.
So, to fix that You need to set this parameter to 'transparent'. Fortunately all flash objects were placed with swfobject scripts. Sample code to fix that issue may look like may look like (video from YouTube):
    $(document).ready(function () {
        // The video to load.
        var videoID = "xxx";
        // Lets Flash from another domain call JavaScript
        var params = { allowScriptAccess: "always", wmode: "transparent" };
        // The element id of the Flash embed
        var atts = { id: "ytPlayer" };
        // All of the magic handled by SWFObject 
        swfobject.embedSWF("http://www.youtube.com/v/" + videoID + "&enablejsapi=1&playerapiid=player1",
                       "videoDiv", "420", "258", "8", null, null, params, atts);
    });

Hope this saves some of Your precious time...

Tags: [dialog] [flash] [jquery] [web development]

Checkbox has to be 'checked' - with unobtrusive jQuery validation and ASP.NET MVC 3

Itmeze

Is it a pretty common scenario to have a checkbox on a form, that is required to be checked during POST-ing of a form. This usually happens when we have a typical 'Agree to Terms and Conditions' element. When I started to play with unobtrusive JavaScript validation in new ASP.NET MVC i was pretty sure that decorating boolean property with [Required] attribute will solve that issue. Surprisingly it doesn't. The key to this problem lies in interpretation of jQuery validation 'required' rule. I digged a little and find a specific code inside a jquery.validate.unobtrusive.js file:
adapters.add("required", function (options) {
  // jQuery Validate equates "required" with "mandatory" for checkbox elements
  if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
    setValidationValues(options, "required", true);
  }
});
As You can see rule does not applies to checkboxes. Simple solution to that would be to either change this code (which we really do not want to do) or create a new specific adapter. I do not know why it is like that - i can guess that it might be for a backward compatibility. Anyway, to make that work we will start by creating a custom attribute.
public class BooleanRequired : RequiredAttribute, IClientValidatable {        

        public BooleanRequired() {
            
        }

        public override bool IsValid(object value) {
            return value != null && (bool)value == true;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
            return new ModelClientValidationRule[] { new ModelClientValidationRule() { ValidationType = "brequired", ErrorMessage = this.ErrorMessage } };
        }
    }
As You can see it inherits from common RequiredAttribute. Moreover it implements IClientValidateable. This is to make assure that rule will be propagated to client side (jQuery validation) as well. The key part here is GetClientValidationRules method (adapter) where we define new, custom ValidationType called for the purpose of this post, as a 'brequired'. To make that work, a specific JavaScript code has to be prepare that adds our custom adapter:

jQuery.validator.unobtrusive.adapters.add("brequired", function (options) {
    //b-required for checkboxes
    if (options.element.tagName.toUpperCase() == "INPUT" && options.element.type.toUpperCase() == "CHECKBOX") {
        //setValidationValues(options, "required", true);
        options.rules["required"] = true;
        if (options.message) {
            options.messages["required"] = options.message;
        }
    }
});

All that is left is to mark properties with newly created BooleanRequired attribute.

[BooleanRequired]
public bool AcceptTermsAndCond { get; set' }

Happy coding!

Tags: [web development]

Silverlight, Flash and HTML5 on job market

Itmeze

There have been a lot of buzz after unfortunate interview where by Bob Muglia admitted that: our (Microsoft) strategy with Silverlight has shifted. That somehow disappointed me, as I was planning to take a closer look at Silverlight. Well, according to guys from Redmond, future belongs to HTML5 - whatever that means. I have decided to check how does the market look like in industry of so called RIA - Rich Internet Applications. The most proper check is to compare demands for appropriate skills. I have used indeed.com to perform my research. job-market-absolute No surprise so far. Knowledge of Flash is the most demanded nowadays. Although it is clearly visible that it is not growing as fast as it used to. Please, note that measures were taken using absolute  scale. Much more interesting thing happen when we tke a look at this graph in relative scale. And that is something that makes You think. Comparing to Silverlight and Flash, demand for HTML5 skills has recently exploded. I know that it far too soon to talk about HTML5. I know that it will not substitute Flash nowadays, and will definably not replace Silverlight for  companies that run 'back office' tools on it. I know ... But still, one picture is worth a thousand words

Tags: [flash] [html5] [silverlight] [web development]

Weird exception (with the simplest solution) after playing with Entity Framework

Itmeze

I have been playing with Entity framework Code-First approach (this is definitely the way I am going to use for my next project, i love it). Anyway, doesn't matter if it is Code-First or Database-First approach, from time to time I keep on getting an exception:
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. The statement has been terminated.
It always takes few minutes to remember - what was that. Ah... It happens when You do not initialize DateTime properties when adding objects to database. Of course, that don't have to be Your problem dear reader but as it happened to me for the third time I assume It should be pretty common one. Seriously, if for the third time You dig for solution of a known to You problem - that means You are getting old buddy.

Tags: [datetime] [entity framework] [web development]

Manually forcing ELMAH to log exception

Itmeze

ELMAH is one of those projects that I use for literally ALL my own projects. It is an easy to implement error-logging component - for ASP.NET (MVC as well). The best thing about it is that it comes with web page that allows you to view all logged errors (even those of 'yellow screen of death'), plus email notification or rss feed. wow ?! Okay, so ELMAH logs all of our unhanded exceptions... What about the case when you 'catch' exception but would still like to log it in ELAM defined medium. To do that, use code sample below:

try {
    throw new ApplicationException("This error has to be logged");
} catch (Exception e) {
    Elmah.ErrorSignal.FromCurrentContext().Raise(e);
}

Such a call is the most proper one and is much safer than calling Elmah.ErrorLog.Default.Log(e). Happy coding!

Tags: [.net] [elmah] [log] [web development]

How to implementing log in to site with Facebook account in ASP.NET MVC

Itmeze

I have decided to enable users that already have a Facebook account (who hasn't ?!) to log on my site with their Facebook credentials. Process has shown to be pretty easy but It took me some time to figure out few things. I have decided to implement so called 'Single Sign-On' and I pretty much followed guildlines from http://developers.facebook.com/docs/guides/web. So, not to loose your precious time, let us start from the beginning.

1. Register Your application/web site

First You need to have a Facebook account. Then You visit http://developers.facebook.com/setup/ to register Your web site. After filling out the form: and pressing 'Create application' button You will receive Application ID and Secret numbers. As You can see from filled form Your web site can stay on localhost - it would work great anyway. You will get Your info in similar form as here:

2. Place login button

Now, You are ready to place Facebook login button on Your web site. I have placed it next to standard login button in LoginUserControl.ascx (Partial View):
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%
    if (Request.IsAuthenticated) {
%>
        Welcome <b><%: Page.User.Identity.Name %></b>!
        [ <%: Html.ActionLink("Log Off", "LogOff", "Account") %> ]
<%
    }
    else {
%>
        <div class="login-with-facebook">
            <fb:login-button ></fb:login-button>
        </div>
        [ <%: Html.ActionLink("Log On", "LogOn", "Account") %> ]
<%
    }

%>

3. Add Facebook namespace

As You can see Facebook uses it's own html namespace. Due to that I have actually lost some time - as I couldn't figure out why my log in button does not show up in IE.... You need to add fb namespace to Your site (preferably in Site.master):
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
This solves the issue.

4. Add JavaScript code

Now some js code is needed, place it at the bottom of the web site:
<div id='fb-root'></div>
<script>
window.fbAsyncInit = function () {
            FB.init({ appId: '<%= Settings.FacebookApplicationId %>', status: true, cookie: true,
                xfbml: true
            });
            FB.Event.subscribe('auth.sessionChange', function (response) {
                if (response.session) {
                    window.location = '<%= Url.Action("LoginWithFacebook", "account", new { returnUrl = Request.Url }) %>';
                } else {
                    window.location = '<%= Url.Action("logout", "account", new { returnUrl = Request.Url }) %>';
                }
            });
        };
        (function () {
            var e = document.createElement('script');
            e.type = 'text/javascript';
            e.src = document.location.protocol +
          '//connect.facebook.net/en_US/all.js';
            e.async = true;
            document.getElementById('fb-root').appendChild(e);
        } ());
</script>
Make sure You have placed 'fb-root' element or You manually added script reference to 'connect.facebook.net/en_US/all.js' script. Replace settings.facebookapplicationid with the one You received after registering app in facebook (Previous step) Previusly placed button () is initialized thanks to FB.init function. Event 'auth.SessionChange' is handled in such a manner that when user registers it redirects to /account/loginwithfacebook and when user log out it goes to /account/logout. As simple as that.

5.  Server side code

Now we need to handle those actions. I will just describe log in, as log out is self explanatory.
[AcceptVerbs(HttpVerbs.Get)]
        public ActionResult LoginWithFacebook(string returnUrl)
        {
            var cookie = FacebookCookie.GetCookie(Settings.FacebookApplicationId, Settings.FacebookSecretKey);

            if (cookie != null) {

                WebClient client = new WebClient();

                var result = client.DownloadString("https://graph.facebook.com/me?access_token=" + cookie.AccessToken);

                JavaScriptSerializer js = new JavaScriptSerializer();

                var user = js.Deserialize<FacebookUserHelper>(result);

                var contextUser = UserService.CreateUserFromFacebook(user);

                FormsAuth.SetAuthCookie(contextUser.Name, false);

            }

            if (string.IsNullOrWhiteSpace(returnUrl))
                return RedirectToHomePage();
            else
                return Redirect(returnUrl);
        }

After a call to LoginWithFacebook is made code checks if there is a specific Facebook cookie and validates it ('Settings.FacebookApplicationId' and 'Settings.FacebookSecretKey' are the one obtained during registration period). If everything is okay we call 'https://graph.facebook.com/me' passing authentication token received within a cookie to obtain user's data, like name or email. Service returns Json data so we use JavaScriptSerializer to deserialize it. Next we just set authentication cookie. Validation of a cookie may look like:

         public bool ValidateFacebookCookie(string orgCookieValue, string facebookAppSecret) {
            var args = HttpUtility.ParseQueryString(orgCookieValue.Replace("\"", string.Empty));
            var cookieCheck = new StringBuilder();
            foreach (var key in args.AllKeys.Where(k => k != "sig")) {
                cookieCheck.AppendFormat("{0}={1}", key, args[key]);
            }
            cookieCheck.Append(facebookAppSecret);
            var md5Hash = cookieCheck.ToMD5Hash(Encoding.ASCII);
            StringBuilder signature = new StringBuilder();
            for (int i = 0; i < md5Hash.Length; i++) {
                signature.Append(md5Hash[i].ToString("X2"));
            }
            return string.Equals(args["sig"], signature.ToString(), StringComparison.InvariantCultureIgnoreCase);
        }

You can obtain facebok cookie value with:

       public static string GetFacebookCookieValue(string facebookAppId, string facebookAppSecret) {
            string name = string.Format("fbs_{0}", facebookAppId);
            if (!HttpContext.Current.Request.Cookies.AllKeys.Contains(name)) {
                return null;
            }
            return HttpContext.Current.Request.Cookies[name].Value;
        }

In case You need a complete code for Facebook cookie validation, You may find it using Googling or write me an email and I will send to anyone. You may check how it works by visiting CyprusQA web site. That is it, happy coding!

Tags: [facebook] [openid] [web development]

LINQ Enumerable.Agregate with Path.Combine

Itmeze

Path.Combine accepts two parameters. Just two... So when we combine multiple path we have to deal with with nesting of Path.Combine:

string rootDir = "/root/app";
string folder1 = "users";
string folder2 = "mike/upload";
string filename = "text.xml";

var path = Path.Combine(rootDir, Path.Combine(folder1, Path.Combine(folder2, filename)));

There are 2 ways to handle this: 1. Use Enumerable.Agregate:

string rootDir = "/root/app";
string folder1 = "users";
string folder2 = "mike/upload";
string filename = "text.xml";

var path2 = new string[] { rootDir, folder1, folder2, filename }.Aggregate(Path.Combine);

2. Or upgrade to .NET 4.0 where there is an overload with Path.Combine(params string[] paths) :) Have fun!

Tags: [.net] [linq] [programming] [web development]

Debugging silverlight in Firefox and Chrome

Itmeze

Well, it seams that war between Firefox and Chrome in my life is not over yet, despite brave decision I have made.... I was forced to write small widget in Silverlight, and to be honest I was having hard time debugging it in visual studio - somehow, I couldn't hit any breakpoints. Well shit happens. After an hours spend on that i've decided to change browser to IE thinking - Microsoft products goes well with Microsoft products. I wasn't sure about that but surprisingly, it worked. After some time of googling I managed to find a solution for firefox: 1. In Firefox address bar type "about:config" and accept warning 2. Change value of the entry "dom.ipc.plugins.enabled.npctrl.dll" to "true" 3. Restart Firefox It worked just great. I still haven't managed to find a proper solution for Chrome browser. I guess until I am ready with this widget Firefox has to be my temporary browser... eh ... Anyone with Chrome fix/workaround?

Tags: [chrome] [debugging] [firefox] [silverlight] [web development]

<-- Prev Next -->

Copyright 2013 © ITmeze