Manually forcing ELMAH to log exception


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!

Share

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


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!

Share

LINQ Enumerable.Agregate with Path.Combine


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!

Share

Debugging silverlight in Firefox and Chrome


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?

Share

Browser and self closed script tag…

I keep on doing that thing for every new project. i simply make script tag self closing, like on the example below:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" />

Browsers may behave in really strange way – just for Your curiosity – try to run it common browsers.

It looks like Chrome is less immune to this than IE and Firefox. And it comes with explanation:

XML self-closing tag syntax used on <script>. The tag will be closed by WebKit, but not all browsers do this. Change to <script></script> instead for best cross-browser compatibility.

So – for Your own safety, do not use self closing on script tag.

Thus anyone of You know why not all major browsers just ignore this? I know that it is ‘my’ bug cause according to html specification i shouldn’t selft close it. But we are all humans, making mistakes is in our nature…

Share

Google Chrome has finally become my first browser!

Chrome…

It has taken some time. I have tried to follow all the changes made since the first version.

I have decided to give it a try from time to time. Each time new major version was released I promised my self to spend at least few days with Chrome as my default browser.

Till version 3.0 or 4.0 Chrome was far far behind Firefox – lack of extensions made web browsing a little bit annoying. After that, when I was finally able to use gmail/wether/translate extensions i was using it more and more often. But still,each time I had to made some web development I was going back to firefox with it’s unbeatable (till recent) add-on: firebug.

Since latest stable Chrome (6.0) i use it even for web development. I have found firebug making my ajax request unstable, and all the embedded developer tools work like charm. There are still few (but just a few) things that i miss from firebug but in overall i am perfectly happy with all Chrome offers and how it saves CPU and memory (comparing to Firefox).

Share