LabelFor html helper with htmlAttributes, MVC 3

The default LabelFor() html helper only comes with two overloads.

Html.LabelFor(Expression expression)

Html.LabelFor(Expression expression, string labelText)

Here is the extension came handy when you want to apply style sheet classes to the label.

public static class LabelForExtensions
    {
        
        public static MvcHtmlString LabelFor(this HtmlHelper html, Expression<Func> expression, object htmlAttributes)
        {
            return LabelFor(html, expression, new RouteValueDictionary(htmlAttributes));
        }
        public static MvcHtmlString LabelFor(this HtmlHelper html, Expression<Func> expression, IDictionary htmlAttributes)
        {
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
            if (String.IsNullOrEmpty(labelText))
            {
                return MvcHtmlString.Empty;
            }

            TagBuilder tag = new TagBuilder("label");
            tag.MergeAttributes(htmlAttributes);
            tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
            tag.SetInnerText(labelText);
            return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
        }

    }

Call it in the view by using the following line of code.

@Html.LabelFor(a => a.Name, new { @class="field-label",title="Enter Username"})

The output is,

Username

Integrate openID, oAuth to your site using JanRain

Integrate openID to your site using JanRain. It is definitely a time saver. My site is built in mvc3 and here are the steps how to do it.

1. You need to setup the widget and copy the generated js code to your site and update the “tokenUrl”.

<script type="text/javascript">(function() {    if (typeof window.janrain !== 'object') window.janrain = {};    window.janrain.settings = {};

    janrain.settings.tokenUrl = '__REPLACE_WITH_YOUR_TOKEN_URL__';

    function isReady() { janrain.ready = true; };    if (document.addEventListener) {      document.addEventListener("DOMContentLoaded", isReady, false);    } else {      window.attachEvent('onload', isReady);    }

    var e = document.createElement('script');    e.type = 'text/javascript';    e.id = 'janrainAuthWidget';

    if (document.location.protocol === 'https:') {      e.src = 'https://rpxnow.com/js/lib/itsharp/engage.js';    } else {      e.src = 'http://widget-cdn.rpxnow.com/js/lib/itsharp/engage.js';    }

    var s = document.getElementsByTagName('script')[0];    s.parentNode.insertBefore(e, s);})();</script>

2. Add your site url to the whitelist, here I put “itsharp.com.au”

itsharp.com.au JanRain Integration
itsharp.com.au JanRain Integration

3. I created a JanRainHelper to make the “auth_info” API call, and a class “JanRainData” for the de-serialization of the response data. (please forgive the naming conversions, I just copied all the return data fields from JanRain)

Don’t forget to copy your own “apiKey” and paste in the code below.

public class JanRainHelper{public static string AuthInfo(string token){string apiKey = "***************************";

WebRequest req = WebRequest.Create("https://rpxnow.com/api/v2/auth_info");

((HttpWebRequest)req).UserAgent = "JanRainProServ/1.0(Automated)";req.Method = "POST";

string postData = "token=";postData += token;postData += "&apiKey=";postData += apiKey;

byte[] byteArray = Encoding.UTF8.GetBytes(postData);// Set the ContentType property of the WebRequest.req.ContentType = "application/x-www-form-urlencoded";// Set the ContentLength property of the WebRequest.req.ContentLength = byteArray.Length;// Get the request stream.Stream dataStream = req.GetRequestStream();// Write the data to the request stream.dataStream.Write(byteArray, 0, byteArray.Length);// Close the Stream object.dataStream.Close();

// Send the data to the webserverHttpWebResponse rsp = (HttpWebResponse)req.GetResponse();string content = "";using (StreamReader sr = new StreamReader(rsp.GetResponseStream())){content = sr.ReadToEnd();}return content;}}

 

[Serializable]public class JanRainData{public Profile profile { get; set; }public string stat { get; set; }}

[Serializable]public class Profile{public string identifier { get; set; }

public string providerName { get; set; }

public string displayName { get; set; }

public Name name { get; set; }

public string gender { get; set; }

public bool? genderBool{get{if (string.IsNullOrEmpty(gender))return null;else{if (gender.Equals("male")){return true;}else if (gender.Equals("female")){return false;}else{return null;}}}}

public string birthday { get; set; }

public DateTime? birthdayDateTime{get{DateTime dt;if (!string.IsNullOrEmpty(birthday) && DateTime.TryParse(birthday, out dt)){return dt;}else{return null;}}}

public string email { get; set; }

public string verifiedEmail { get; set; }

public string phoneNumber { get; set; }

public string photo { get; set; }

public Address address { get; set; }}

[Serializable]public class Name{public string givenName { get; set; }public string familyName { get; set; }public string formatted { get; set; }}

[Serializable]public class Address{public string formatted { get; set; }public string streetAddress { get; set; }public string locality { get; set; }public string region { get; set; }public string postalCode { get; set; }public string country { get; set; }}

4. Create an Action method for the “tokenUrl”, JanRain post back with a token, and you will need to use that token to call the auth_info API to retrieve the user info.

I am using the JavascriptSerializer to deserialize the response to a JanRainData object. Then you can do whatever you need to do, such as create a user in your database and authentication cookie, etc.


public ActionResult JanRainPostBack(string token){if (!string.IsNullOrEmpty(token)){string content = JanRainHelper.AuthInfo(token);JavaScriptSerializer s = new JavaScriptSerializer();

var data = s.Deserialize<JanRainData>(content);if (data.stat.Equals("ok") && !string.IsNullOrEmpty(data.profile.providerName) &&       !string.IsNullOrEmpty(data.profile.identifier)){var user = new User(){Email = data.profile.email};_repository.Save(user);return View();}elsethrow new Exception("response failed");}elsethrow new Exception("token is invalid");}

5. It is all done now. Please be aware you might only retrieve limited user information from different openID providers. Eg, twitter will not return an email address which I think it’s pretty lame. If email is required in your dbo.User table, you will need to enforce users to complete the registration.