Integrating ApplicationServices.AuthenticationService through Javascript only

If you are using a standard Microsoft Auth setup then you have probably used ApplicationServices.AuthenticationService before.  It is pretty simple and not the topic of discussion here, but integrating it into MVC is a pain and not documented anywhere; at least that I can find.

 

Here is how to enable the WCS Auth service: http://msdn.microsoft.com/en-us/library/bb398990.aspx

In Webforms you can enable Ajax services by using Script Manager: http://www.asp.net/web-forms/tutorials/aspnet-ajax/understanding-asp-net-ajax-authentication-and-profile-application-services

 

In MVC, you don’t have access to script manager.

The following code shows you how to enable and use AuthenticationService from pure javascript

 

<script src=”http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js”></script>
<script>
$(document).ready(function () {

Sys.Services.AuthenticationService.set_path(‘http://[url]/AuthenticationService.svc’);

$(“#login”).click(function (event) {
Sys.Services.AuthenticationService.login(username,password, false, null, ”, CompleteCallBack, null, username);
});
});
function CompleteCallBack(validUser, context, methodName) {
if (validUser == true) {
alert(‘yes’);
}
else {
alert(‘no’);
}
}

</script>

 

Onyxtek sites will go black on Weds in protest against SOPA

All Onyxtek sites are set to go dark on Weds: Rate My Neighborhood, Ideal Wait, Onyxtek, and all related blogs. It was 3 lines of code for all the .Net sites and one plugin for all the wordpress sites.

For .Net

<%
if(DateTime.Now < new DateTime(2012,01,19) && DateTime.Now > new DateTime(2012,01,18))
{
%>
<script type=”text/javascript” src=”//js.sopablackout.org/sopablackout.js”></script>
<%
}
%>

For WordPress follow these instructions

https://github.com/chrisguitarguy/WP-SOPA-Blackout

I had problems with the updated 1.2, so you may just want to install the 1.0 version.

Thanks to Scott Edwards and Interwest.

I wanted to thank Scott Edwards from Interwest for helping Onyxtek get the insurance we needed for a big contract. http://www.iwins.com

We have moved away from GoDaddy.

Onyxtek has finished moving all our domains away from GoDaddy.  Does anyone know a good place to buy a Multiple Domain (UCC) SSL cert?  Our new domain host, NameCheap, doesn’t seem to offer them.

Microsoft MVC and the MVVM pattern

At Onyxtek we believe in the strict separation of layers.  We have typically used the MVVM pattern when designing our projects.  Over the next few posts I am going to learn Microsoft MVC and compare it to my experiences with MVVM.

A brief lesson on MVVM.  MVVM stands for Model-View-ViewModel

What this means is the UI presentation, the View, is completely seperate from the data and business layers, the Model, and they are tied together through the ViewModel.

The View and the Model only communicate through the ViewModel.

Our typical projects are laid out like this:

I was recently asked why we typically make our business layer a web service.  The short answer is to make it easier to reuse it outside of ASP.Net.  The business layer can be used in a WinForm app, a phone app, or in other related websites.  It allows us to give access to our API to whatever and whomever we choose.

The View

Our views are pretty simple.  They are standard ASPX files with very little in the code behind, though more than what would be in MVC or other implementations of MVVM.

Our login page looks like this

protected void Page_Load(object sender, EventArgs e)
{
   if (Request.Url.AbsoluteUri.ToLower().Contains("logout"))
   {
       Response.Cookies["login"]["username"] = "";
       Response.Cookies["login"]["sessionGuid"] = "";
       Response.Redirect("/Member/Login");
   }

   string email = (Request.Cookies["login"] ==null) ? "" : Request.Cookies["login"]["username"];
   string sessionGuid = (Request.Cookies["login"] == null) ? "" : Request.Cookies["login"]["sessionGuid"];

   Business.Entities.Member member = new Business.Entities.Member
   {
      Email = email
   };

   member = Helpers.AuthenticationServiceHelper.LoginMember(member, sessionGuid);

   if (member != null)
   {
      this.MasterPage.Member = member;

      Response.Redirect(this.Redirect);
   }
}

There is just some basic code to check if it is a logout and checks the cookies to see if the user has saved their login.  In a typical MVVM pattern, there would be a ViewModel called Login and this code would be moved into there.  The reason we don’t do this is because there is extra code to make this wire up correctly in ASP.Net.  In Silverlight the extra code is not needed, so for Silverlight projects we use actual ViewModels.

The ViewModel

The way we treat ViewModels for ASPX is basically just a helper class.  The helper calls the webservice, and handles any cleanup

public static Business.Entities.Member LoginMember(Business.Entities.Member Member)
{
  return AuthenticationServiceClient.LoginMember(Member);
}

The Model

Our model is spread between the Data and Business Layers.  It is generally a bad idea to use the generated classes from Entity Framework as your entity classes.

[Serializable]
 public class Member : Login
 {
     public AccountType AccountType { get; set; }
     public string Company { get; set; }
     public Address Address { get; set; }
     public string Phone { get; set; }
     public IList<Restaurant> Restaurants { get; set; }
     public CreditCard CreditCard { get; set; }
 }
}

This is our Member Class.  For the most part it is a copy of our EF generated class.  Member inherits from Login which handles all the login functionality.  Items like hashing of the password are all handled from the Login class.

This class is loaded by a “Management” class

public Business.Entities.Member LoginMember(Business.Entities.Member Member)
{
    Business.Entities.Member returnValue = (from m in DBContext.Members
                                            where 
                                            m.Login.Email == Member.Email && m.Login.PasswordHash == Member.PasswordHash 
                                            select new Business.Entities.Member
                                                        {
                                                            ID = m.MemberID,
                                                            AccountType = new Business.Entities.AccountType
                                                            {
                                                                ID = m.AccountType.AccountTypeID,
                                                                CostPerTransaction = m.AccountType.CostPerTransaction,
                                                                HasDomainMapping = m.AccountType.HasDomainMapping,
...

I know to some people this may seem like overkill, but I have found, through failures and successes, that having this separation is the best way, so far.  I say so far because we are constantly learning and growing.

How do you feel about this method?  How would you add or change how we do things?

In my next post, I will start learning Microsoft MVC, and I will see how it compares to how we do things.

Doing Javascript the right way

I have been spending a lot of time recently trying to make myself a better web programmer.  One easy way to do this is to make sure your javascript doesn’t collide with other javascript.

I have been reading this blog:

http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

 

With all new sites I am using the Self-extracting Anonymous Function with Public and Private properties, and use Javascript namespaces to seperate everything into logical areas.

On our new site https://www.socialtable.me I have started this separation of code more so than any previous project.

For example, in the member area there is a page called restaurants.aspx, which as the name sounds allows clients to manage their restaurants

The Javascript for that page is structured like this:

(function (Restaurants, $, undefined) {

    Restaurants.Load = function () {
        $("#tabs").tabs();
        setupUI();
        bindClickHandlers();
    }

    //private functions
    function bindClickHandlers() {
        $("#addRestaurantImg").click(AddRestaurant_Click);
    }

    function setupUI() {
        $("#dialog-form").dialog({
            autoOpen: false,
            height: 300,
            width: 350,
            modal: true,
            buttons: {
                "Create an account": function () {
                   /*validation stuff*/
                    if (bValid) {
                        $("#users tbody").append("<tr>" +
							"<td>" + name.val() + "</td>" +
							"<td>" + email.val() + "</td>" +
							"<td>" + password.val() + "</td>" +
						"</tr>");
                        $(this).dialog("close");
                    }
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            },
            close: function () {
                allFields.val("").removeClass("ui-state-error");
            }
        });
    }

    //event handlers
    function AddRestaurant_Click() {
        console.log('add restaurant clicked');
        $("#dialog-form").dialog("open");
    }

} (window.SocialTable.Members.Restaurants = window.SocialTable.Members.Restaurants || {}, jQuery));

$(document).ready(function () {
    SocialTable.Members.Restaurants.Load();
});

I personally think it make my sites cleaner.  No more Javascript on the pages.  All click events are handled through Javascript classes.

What are some of the ways that you make your web code better?

Google Analytics has become unreliable for us.

It makes me sad how unreliable Google Analytics has become. It says that I had 0 visitors on a day that I have data for in my database. I have fallen back to using awstats, but I need to figure out how to keep it from counting all the async calls my AJAX handler.

Onyxtek just launched Escrow Coordinator Plus.

Onyxtek just launched Escrow Coordinator Plus.
“Simply the Smartest way to do Real Estate”
If you are a real estate agent you completely eliminate your need for a transaction coordinator. Check them out at http://www.escrowcoordinatorpl​us.com/

© Onyxtek
CyberChimps