Lakkakula's Blog

September 20, 2009

Linksgrid – Enhancements and Conclusion

Filed under: Ajax Client Templates, Asp.Net, Asp.Net MVC, jQuery, MVC — Venkata Uma lakkakula @ 6:17 pm

As with any software product there is always scope for enhancements, linksgrid is no exception. What I tried to do here is to show a different approach for developing Web 2.0 portal with dynamic content loading and user personalization. I also tried to achieve balance between complexity of coding and ease of implementation. Asp.net MVC , Ajax Client Templates and jQuery brings this balance very well by drastically improving productivity of client side programming which is rather complex when written in conventional plain old javascript. Asp.net MVC’s RESTful url based services enhances ease of implementation of AJAX.

If you followed this series from the beginning you might have noticed that, I incrementally added features to the portal. The first enhancement I would do is to clean up javascript framework and improve initial page load behavior. For example the current implementation doesn’t load any JSON on first call to the server, then multiple subsequent calls are made to load widget-list, tab-list, gallery-list etc., All these can be combined into one single JSON object and can be returned on the first call itself. This will improve a little bit of performance as it reduces number of calls to server.

I encourage you to download the latest code and play with it. If you find any problem or have a question, please use http://code.google.com/p/linksgrid/issues/list to post your issues; you are welcome to post a comment in this blog also.

If you find this project helped in one or other way please let me know… I will list your implementation in this blog.

Finally, most important… If any one of you fixed any problem or added a cool new feature to linksgrid, please share code with me.

I wish you enjoyed this series as much as I enjoyed writing and sharing my ideas with you on the project.

Thanks for the support and encouragement I got from you all.

Advertisements

September 9, 2009

Developing Web 2.0 Portal using Asp.Net MVC, Microsoft Ajax Client Templates and jQuery with drag and drop widget personalization – Part 4

Filed under: Ajax Client Templates, Asp.Net, Asp.Net MVC, jQuery, MVC, OpenID — Tags: — Venkata Uma lakkakula @ 7:43 pm

In this series:
1. Introduction
2. Part 1 – Portal Core Functionality
3. Part 2 – Drag and Drop Widget Personalization
4. Part 3 – Building Widget Gallery
5. Part 4 – Introduce Tabs and Users
6. Part 5 – Enhancements and Conclusion

Working portal at: http://aspspider.info/lakkakula/local.aspx

Alright, finally I’ve got some time to write about users and tabs. In previous posts we have seen the core functionality of the portal which is to load widgets through ajax calls and displaying widget gallery. Once we have the core functionality ready, its time to tie it to Users and Tabs. Talking about users, it is typical to implement forms based authentication  for public web sites. When it comes to asp.net or asp.net MVC the natural way is to go through Membership, Role and Profile “Providers“. Let us do it something different here, the latest buzz is “Open ID“, so why not implement it?

Guest User Screenshot

lg-guest

Authenticated user screen-shot

lg-auth

This is what we will do here:lg-flow

To keep things simple, we will not be storing guest user’s activity, such as new widget creation, widget location move etc. For the logged in users we will allow to create new tabs, add widgets, move widgets and delete widgets.

Now for some code: Open ID implementation is straight forward, you can download samples from dotnetopenid project site. What I want to show is, generally after authentication we would be interested to know more about the user such as email, full name etc. DotnetOpenId library has an response extension method which will pull this extra information for us. (note: the extra user information depends on the actual open id provider, in other words its not guaranteed that we will always get response for extra user info.)  Here is the simple implementation of authentication:

[ValidateInput(false)]
public ActionResult Authenticate()
{
var openid = new OpenIdRelyingParty();
var response = openid.GetResponse();
if (response == null)
{
// Stage 2: user submitting Identifier
/*var req = openid.CreateRequest(Request.Form["openid_identifier"]);
var fields = new DotNetOpenAuth.OpenId.Extensions.SimpleRegistration.ClaimsRequest();// .SimpleRegistrationRequestFields();
fields.Email = DotNetOpenAuth.OpenId.Extensions.SimpleRegistration.ClaimsRequest;
fields.Nickname = DotNetOpenId.Extensions.SimpleRegistrationRequest.Request;
fields. .AddToRequest(req);
req.RedirectToProvider(); */
Identifier id;
if (Identifier.TryParse(Request.Form["openid_identifier"], out id))
{
try
{
//return openid.CreateRequest(Request.Form["openid_identifier"]).RedirectingResponse.AsActionResult();
var request = openid.CreateRequest(Request.Form["openid_identifier"]);

request.AddExtension(new ClaimsRequest
{
BirthDate = DemandLevel.Request,
Country = DemandLevel.Request,
Email = DemandLevel.Require,
FullName = DemandLevel.Request,
Gender = DemandLevel.Request,
Language = DemandLevel.Request,
Nickname = DemandLevel.Request,
PostalCode = DemandLevel.Request,
TimeZone = DemandLevel.Request
});

return request.RedirectingResponse.AsActionResult();

}
catch (ProtocolException ex)
{
ViewData[“Message”] = ex.Message;
return RedirectToAction(“Index”, “Home”);
}
}
else
{
ViewData[“Message”] = “Invalid identifier”;
return RedirectToAction(“Index”, “Home”);
}
}
else
{
var res = response.GetUntrustedExtension<ClaimsResponse>();
//var res = response.GetExtension<ClaimsResponse>();
// Stage 3: OpenID Provider sending assertion response
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
var name = response.ClaimedIdentifier.ToString();

if (res != null && res.Nickname != null)
Session[“FriendlyIdentifier”] = res.Nickname;
else if(res!=null && res.Email!=null)
Session[“FriendlyIdentifier”] = res.Email;
else
Session[“FriendlyIdentifier”] = name;

//user setup
using (LinksgridDataContext db = new LinksgridDataContext())
{
var userId = (from u in db.LGUsers
where u.Name == name
select u.Id).SingleOrDefault();
if (userId <= 0)
{
LGUser newUser = new LGUser();
newUser.Name = name;

newUser.BirthDate = res.BirthDate.ToString();
newUser.Country = res.Country;
newUser.Email = res.Email;
newUser.FullName = res.FullName;
newUser.Gender = res.Gender==null?string.Empty:res.Gender.Value.ToString();
newUser.Language = res.Language;
newUser.Nickname = res.Nickname;
newUser.PostalCode = res.PostalCode;
newUser.TimeZone = res.TimeZone;

db.LGUsers.InsertOnSubmit(newUser);

db.SubmitChanges();

repoWidget.NewUserSetup(newUser.Id);

}

}

FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);
return RedirectToAction(“Index”, “Home”);
case AuthenticationStatus.Canceled:
ViewData[“Message”] = “Canceled at provider”;
return RedirectToAction(“Index”, “Home”);
case AuthenticationStatus.Failed:
ViewData[“Message”] = response.Exception.Message;
return RedirectToAction(“Index”, “Home”);
}
}
return new EmptyResult();
}

}

Here is the configuration required for OpenId response extension

<configSections>

<section name=”uri” type=”System.Configuration.UriSection, &#xD;&#xA;            System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″
/>
<section name=”dotNetOpenAuth” type=”DotNetOpenAuth.Configuration.DotNetOpenAuthSection”
requirePermission=”false” allowLocation=”true”/>
</configSections>
<uri>
<idn enabled=”All”/>
<iriParsing enabled=”true”/>
</uri>
<dotNetOpenAuth>
<openid maxAuthenticationTime=”0:05″>
<relyingParty>
<security
requireSsl=”false”
minimumRequiredOpenIdVersion=”V10″
minimumHashBitLength=”160″
maximumHashBitLength=”256″
requireDirectedIdentity=”false”
requireAssociation=”false”
rejectUnsolicitedAssertions=”false”
rejectDelegatingIdentifiers=”false”
ignoreUnsignedExtensions=”false”
privateSecretMaximumAge=”07:00:00″ />
<behaviors>
<add type=”DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth” />
</behaviors>
</relyingParty>
</openid>
<messaging>
<untrustedWebRequest>
<whitelistHosts>
<!– since this is a sample, and will often be used with localhost –>
<add name=”localhost” />
</whitelistHosts>
</untrustedWebRequest>
</messaging>
</dotNetOpenAuth>

Blog at WordPress.com.