Webcognoscere

Hi, welcome to Webcognoscere, the digital home of Eliana and Miguel Ribeiro.

LINQ Basic Projection

Author: Miguel Posted 5. May 2013

Here is a basic example of LINQ Projection.

I'm using it to build up a SelectList used in a dropdown for my ASP.NET MVC View.

In this particular case, I want to display all the administrators in my system in a dropdown for the user to select. I have a class that holds a particular users' information as well as a stored procedure that retrieves all the users in the database.
I then load these users into a List of my [User] class and convert it to a SelectList using LINQ.
The LINQ that I use makes easy work of creating and joining the [FirstName] and [LastName] fields to create a composite field to display in my dropdown.

My User class looks like this:

public class User
        {
            public int UserId { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string RoleName { get; set; }
        }
 

And I want my dropdown to look like this:

Here's the LINQ to project (read transform) my List<User> to a new list of a custom type where the FirstName and LastName properties are merged into a single Username property.

var userList =
                from u in users
                where u.RoleName == "Administrator"
                select new { Id = u.UserId, Username = string.Format("{0} {1}", u.FirstName, u.LastName) };

Next, I create a new SelectList passing in the my List, set the Value field (within the list) and the Display field and pass it to my view. Voila! :)

SelectList list = new SelectList(userList, "Id", "Username");

In LINQ, the process of transforming the results of a query is called projection. It is achieved using LINQ's select operator and can be applied in two 'styles', LINQ query syntax or LINQ method syntax. If I had've done this using method syntax it would've looked like this:

var userList = users.Where(u => u.RoleName == "Administrator")
                                .Select(u => new { Id = u.UserId, Username = string.Format("{0} {1}", u.FirstName, u.LastName) });

It all depends on your personal preference and the complexity of what you're trying to do. But in essence it's doing the same thing. I threw in the where operator so you could see how you could filter your items as well.

Hope this helps.

Tags:

In this post I'll show you how to send a JSON object to your MVC Action Method and have your Action Method return you a JSON result.

The code for this article can be downloaded from here.

Why do you want this?

Firstly I'd like to give you some examples as to why you would want to do this and how it can enhance your web applications/sites:-

  1. You want a web page to save some data to a database without having to redirect the user to another page or have the user leave the current page they are on.
  2. You want to perform some or other function on the server side without having the user leave the current page.
  3. You want to keep the UI responsive
  4. You want to minimize the amount of postbacks on your website.

 

Understanding the scenario

My scenario is a simple one:-
We have a website that sells various items online. Our store currently has only three items. To keep this page responsive I want to keep items that the user opts to add to his cart in a client side object, until such time that they want to actually check out and pay for these items.
I want to code it this way as the alternative is to save these items each time the user clicks the 'Add to Cart' button. This would then post back each and every time the user clicks the 'Add to Cart' button and could prove slow and frustrating for the user. So to keep our users engaged with our site we must provide them with a responsive and efficient UI and storing his/her cart items in a client-side JSON object is the perfect mechanism for doing this. Adding and removing items from his/her cart will be quick and when they are ready to purchase they can click the 'checkout' option.

 

First things first, defining the Shopping Cart Objects

For this article I specifically wanted a semi-complex object as the mapping of JSON objects to C# objects in previous versions of MVC worked only for what I call 1 tier objects. Objects without child objects inside them. Things like arrays were a hassle to get working and you had to write your own custom binding helpers to get them to map properly. With the advent of MVC 3, this is much easier, but I still wanted to show you what a real life object may look like and how it would map into your C# objects.

So here below you can see what my Shopping Cart objects look like:

C# Objects

public class ShoppingCartModel
{
	public int UserId { get; set; }
	public string DeliveryInstructions { get; set; }
	public List<CartItemModel> CartItems { get; set; }
}

public class CartItemModel
{
	public int Id { get; set; }
	public string ItemName { get; set; }
	public decimal Price { get; set; }
	public int Quantity { get; set; }
}

ShoppingCartModel is the 'parent' object that holds a list of the Items that the user wants to purchase.

Now in our scenario we need a JSON representation of our C# objects so we can use them on the UI when the user is adding/removing items from his/her cart.

JSON Object

var m_ShoppingCart = {
	UserId: 10,
	DeliveryInstructions: "Leave at front desk",
	CartItems: []
};

I've just put random values inside this object to show you what data would typically be there.

Next we need to create a simple UI so that we can add items to our JSON object (m_ShoppingCart) to pass through to our Controller Action Method. I'll just show you the output of what the UI looks like below and you can just grab the code here.

So the idea here is to click on the 'Add to Cart' button, have this add the item to the JSON object called m_ShoppingCart, then have that get added to the Shopping Cart UI List (which calculates the total) and finally have the user click the Checkout.
When the user clicks the 'Proceed to Checkout' link, we post this JSON object to the Controller Action Method, which converts our JSON object into our C# object where we can then save it to the database and return a success status indicator. 

The JavaScript

Adding to the Cart

Calling the AddToCart function

<input type="button" value="Add to Cart" onclick="javascript:AddToCart(1, 'Book A', 14.95, 1);$(this).attr('disabled',true);" />

You'll notice that I call two Javascript functions in the 'onclick' event of the button. The first is the function that actually adds the item to the shopping cart, the second merely disables the button so that the user cannot click it again.
Next, the function itself

function AddToCart(id, itemName, price, quantity) {

	//  Add the item to the shopping cart object
	m_ShoppingCart.CartItems.push({
		"Id": id,
		"ItemName": itemName,
		"Price": price.toFixed(2), //   Issue here if you don't specify the decimal place
		"Quantity": quantity
	});

	//  Render the shopping cart object
	RenderShoppingCart();
}

On the face of it, AddToCart() is a pretty straight forward method, however, there's two items of interest inside it.
Firstly, there's the JavaScript 'push' method, which is a native JavaScript method for adding items to an array. This method is especially useful when adding complex objects to an array.
Secondly, you may have noticed that I specifically call the 'toFixed()' method when assigning the price to the m_ShoppingCart.Price property. This is because the toFixed() method preserves the number of decimals in the price that I'm passing through. Without it, my JSON object would store the number 11 as opposed to 11.00 and, when it got passed through to my controller action method, the mapping into the C# discarded the actual number and merely retained the trailing zeros, resulting in a price of $0, not $11.00. (if anyone can explain this to me, that'd be great)

Rendering the Cart

Rendering the cart is straight forward, however, I'll list it here for those of you that would like to see how I built up the html using javascript and jQuery:

function RenderShoppingCart() {

	$("#CartItemList").html("");

	var totalAmount = 0;

	$.each(m_ShoppingCart.CartItems, function (index, cartItem) {

	    var itemTotal = Number(cartItem.Price) * Number(cartItem.Quantity);
	    totalAmount += itemTotal;

	    $("#CartItemList").append("<li>" + cartItem.ItemName + " - $" + itemTotal.toFixed(2) + "</li>");
	});

	$("#TotalAmount").html("$" + totalAmount.toFixed(2));
}


The Meat and Potatoes

Next we have what I like to call the 'Meat and Potatoes' of the post :) the actual Posting of the JSON object to our MVC Controller Action Method:

The JavaScript

function PostData() {
		$.ajax({
			url: '@Url.Content("~/Store/Checkout")',
			async: false,
			type: "POST",
			data: JSON.stringify(m_ShoppingCart), 
			dataType: "json", 
			contentType: "application/json; charset=utf-8",
			error: function (jqXHR, textStatus, errorThrown) {
				alert(jqXHR + "-" + textStatus + "-" + errorThrown);
			},
			success: function (data, textStatus, jqXHR) {
				$("#Results").show();
				$("#ResultMessage").html(data.Message);
			}
		});
}

Ok, so this is the crux of this post and certainly took me some time to figure out the right combination of the parameters.

So, what are the parameters and what values should I give them:

  • async
    • set this to 'true' (without the apostrophes) to prevent the page for 'waiting' for this method to return. I've set it to false as I wanted my page to wait till the post completed.
  • data (with JSON.stringify)
    • this is where you specify the data that is going to be sent to our Action Method
    • WHAT IS JSON.stringify
      • If you leave the JSON.stringify method out, your object (m_ShoppingCart) will be sent to your Action Method as a Key/Value pair object, i.e. a series of objects that have a string representing the name of your property and the value thereof, e.g.:
        • UserId=10
        • DeliveryInstructions=Leave+at+front+desk
        • CartItems[0][Id]=1&CartItems[0][ItemName]=Book A&CartItems[0][Price]=14.95&CartItems[0][Quantity]=1&CartItems[1][Id]=2 ........etc...
      • Using the JSON.stringify method ensures that your object is sent as a JSON object to your Action Method (a string representation thereof)
      • It is a native Javascript method (as of JavaScript 1.7 afaik) that converts a value (object) to the JSON string representation of that object
      • Must work in conjunction with the contentType parameter below
  • dataType
    • This specifies the type of data you are expecting from the server. (i.e. not the datatype that you are sending to the server :) )
    • Our example sees us receiving a JSON object, so you specify "json" as the dataType
  • contentType
    • This gave me pains in my side as you must set this to 'application/json' to inform the server what data type you are sending to the server. If you don't set this, the default is 'application/x-www.form-urlencoded' and the server will interpret the data you are sending it as key/value pairs.
    • Why did I set "charset=utf-8". By default it should be UTF-8 (at least as per jQuery.ajax documentation), but just in case ;)

The C#

My controller doesn't do much, it accepts the ShoppingCart object that you send through from the JavaScript, compiles a nice 'success message' and returns this to the caller.

[HttpPost]
public JsonResult Checkout(ShoppingCartModel model)
{
	string message = string.Format("Successfully processed {0} item(s).", model.CartItems.Count.ToString());
	return Json(new { Success = true, Message = message });
}

So what you may notice here is there is no visible code converting our JSON object to our ShoppingCartModel object.
This is because, in ASP.NET MVC 3, there's a 'value provider' factory that is doing this for us automatically. This factory attaches to our Controllers' Action Method and converts our JSON object into our ShoppingCartModel. It uses our Action Methods Signature to determine what Type we are expecting and it attempts to convert the input it received (from our POST) into that Type. This all happens inside MVC's binding logic. In MVC 2, you had to write your own 'Value Provider Factory' and enable it so it could run when the data posted to an Action was about to be bound to the type specified on the Actions input parameter(s).

The next thing you'll notice is how I send a JSON object back to the caller. Here I use what's known as an anonymous type, basically defining an object on the fly, and pass this back through the Json method. This method takes in your object and serializes it into JSON format and returns this to the caller.

Now on the UI I can simply access this object as follows inside the success method of my ajax post:

function PostData() {
		$.ajax({
			url: '@Url.Content("~/Store/Checkout")',
			async: false,
			type: "POST",
			data: JSON.stringify(m_ShoppingCart),
			dataType: "json",
			contentType: "application/json; charset=utf-8",
			error: function (jqXHR, textStatus, errorThrown) {
				alert(jqXHR + "-" + textStatus + "-" + errorThrown);
			},
			success: function (data, textStatus, jqXHR) { $("#Results").show(); $("#ResultMessage").html(data.Message); }
		});
}

The returned JSON object comes back as the object named [data] as seen in the success callback above. [data] then maps directly to my anonymous object which has the properties, [Success] and [Message]. So if I wanted to access the message property, I would simply type data.Message;

Conclusion

So there you have it, oh and before I go, just remember the gotchas:

  1. Make sure your parameters on the jQuery Ajax post are set correctly
  2. The automatic JSON binding only works from ASP.NET MVC 3 and up, for MVC 2 you'd have to write your own.
  3. Don't forget that the decimal numbers you send through must be formatted with the correct decimal places before you send it to the Controllers Action Method (the toFixed() method)
  4. And most importantly, YOUR JSON OBJECT PROPERTY NAMES MUST BE EXACTLY THE SAME AS YOUR C# OBJECT NAMES, if they are not, it will not be able to map properly and from what I've seen it is case sensitive.

I really hope this post helps you guys create really usable, responsive and efficient sites/applications and please, let me know your thoughts and comments.

I'd really love to hear what you guys think.

 

The code for this article can be downloaded from here.

Tags: , , , , , ,

Microsoft Unity - Configuration and Aliases

Author: Miguel Posted 30. November 2011

Should I Use Aliases in my Configuration File?

It's a good idea to use aliases for the following two reasons:

  1. User Friendly
    1. It allows you to keep all your assembly references at the top and easily viewable, so you don't have to sift through all the registration tags to search for the references you need to add to the project, and
  2. Better Error Display
    1. You will get more useful errors should you reference the incorrect assembly or if you don't reference the assembly you are specifying in the configuration.

If you are using the registration tags to specify the full type names and assemblies, and one of them happens to be misspelt or you haven't referenced that project in your assembly, Unity will throw a very obscure message that will look like this: "FileLoadException was unhandled by user code. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)"

This particular error sent me on a wild goose chase for a good few hours until I decided to use the alias tags. After which it broke immediately and indicated exactly the type that was giving the issues. It was coincidence in fact, since I wanted to clean up my code so that I could easily see all the references that I was using at the top as opposed to sifting through my reference tags. It was after I added in the references that the error it gave me was actually quite descriptive and not obscure like the previous one. In my case, it was a silly misspelling of the reference which would've taking me ages to figure out had I have persisted based on the current error message. In fact, in one post I read the guy actually downloaded the source code for unity and debugged it this way, obviously causing a huge delay in his project.

So it makes sense then to use aliases, as it cleans up your config file quite a bit and due to Unity appearing to resolve the aliases first, will give you a better error message should the type you referenced be unavailable/misspelt etc.

Hope this saves you guys some time. Let me know your thoughts.

Tags:

What is SEO?

Author: Miguel Posted 20. August 2011

Exactly what is SEO and SEM, and why should I worry about them?

Think of your site as a retail store, as more people visit your store, your chance of making a sale increases. It makes sense then that you want as many people entering your store as possible, or does it? If you get people that are not interested in your products, coming into your store, you aren’t likely to make too many sales. However, if you are able to attract people that are interested in your products, your potential for selling to them is huge.

But how do you get that potential customer into your store and not your competitors? Well, that’s the million dollar question. Now if you owned a physical retail store, the factors in attracting the right kind of customer are many, factors such as location, reputation and shop fitting come into play. Do you have a franchise? Are you in a mall? Is your store visually appealing and appropriate to your product offering?

Owning a website isn’t that dissimilar. The primary difference being that you have a virtual presence as opposed to a physical one. Adjusting the parameters and factors to build your online credibility to attract more potential, and targeted, visitors is the arena that SEO (Search Engine Optimization) and SEM (Search Engine Marketing) are focussed on.

In short, SEO and SEM are more than the basic marketing you would do for a physical store to get business. Since you have a physical presence, by default you can be found by people passing by your store. On the net, however, there’s just no ways anyone can find you unless you actively work to get found.

Search Engine Optimization deals with actually making your site 'presentable' to the search engines whilst Search Engine Marketing deals with actively marketing your site using the major search engines marketing programs.

I'll be doing a series of articles on each of these to try and help you gain the most out of your SEO and SEM and avoid the common pitfalls that the average webmaster/business owner makes when trying to do this themselves.

Tags: ,

Communication - The key to successful projects

Author: Miguel Posted 28. October 2010

Imagine this scenario:

You are a project manager. You have a team of 5 developers working on an uber cool web portal and it’s D-Day. You and your team need to demo the software to your client.

You have been busy the whole week with other projects, chasing clients for payment, managing other projects and you are slightly stressed about this particular one as you walk over to the team. You ask them: “So are we all ready to go for the demo this afternoon?”

An eerie silence creeps over all 5 team members. You know what’s next; you’ve experienced this feeling before, your heart sinks, and your mind races as to what you are going to tell the client.

One lonely developer steps up and tells you what you already know: “There is a problem. Some functionality doesn’t work due to ‘x’, ’y’ and ‘z’”.

You know your next steps aren’t going to be easy; the call to the client is going to be an unpleasant one, your reputation is going to take a bruising, the company’s reputation is going to take a knock. This is not good.

You take the next steps; you phone the client, empathize with his frustration, take his slack and re-assure him when he can actually expect the demo. You put down the phone and your blood starts boiling.

  1. Why did this happen?
  2. Why did no-one communicate this to me earlier?
  3. Why didn’t the team test that particular piece of functionality at the beginning of the week?
  4. Who is to blame?

Now these are all reasonable questions to ask. But they all have one thing in common; their answer has nothing to do with you.

Unfortunately, this is the real problem. ‘You’ are the answer to these questions. It’s a harsh reality that you have to deal with, and the sooner you do, the sooner these sort of issues go away.

As a project manager, the ownership should be on you to ensure these sorts of things don’t happen. You need to ensure that at minute 59 things blow up and go pear shaped.

Now before the worlds project managers get defensive and block out the message in this article, let me explain why I think this is a project manager’s failure.

You see this scenario happens so often in the software/web development industry because of some very simple and core issues. The most fundamental of them all is communication. Communication in a team environment is key to the delivery of a successful project. Yet everyone on the team thinks that it is the next person’s responsibility to instantiate the communication. As a project manager, in my opinion, it is up to you to get the communication between the team flowing. You are seen as the project leader and therefore you need to make the environment a suitable and comfortable one to communicate in.

If you find that you never receive any feedback or communication, you need to analyze and address this immediately and not at the end of the project. You need to honestly assess whether the lack of communication is actually your fault or the developers fault. If the developer perceives you to be unapproachable then you cannot reasonably expect the developer to be open with his communication to you.

Developers need to know that their project managers are there to assist them, they need to really believe that the project managers have their best interests at heart. They need their leaders to take an interest in what they are doing as opposed to just the results of what they are doing. If they do not receive this type of support they are less inclined to take the project managers on the ‘journey’ of the project and this is where all communication begins deteriorating.

If the project manager is not willing to take the journey with the developers on the project, they will inevitably fall out of touch with what is actually going on with the project. And the scenario indicated above will happen time and time again.

So in closing, as a project manager, your role is not only the schedule and budget of the project, but the project itself. The person who dictates the timelines is usually the person that drives the project. You cannot drive a project at arm’s length; you cannot lead a project by sitting at your desk and merely tracking everyone’s’ progress. You need to get involved. You need to force communication if it is not happening. This is your role; it’s an important one and key to the success of any project.

Great leaders make greater project managers as they want both the project and everyone in the project to succeed. A project is not just a task they have to get done, it’s a journey that they want to be on, a journey that will allow them to meet new people and build new relationships through hard work and team effort. This is what drives good project managers; a personal interest in every person on the team, and having this interest will motivate and drive your team to success after success.

Project managers need to be leaders. They need compassion and a strong sense of self motivation to effectively drive a team to be successful.

Tags:

Effort vs. Usability

Author: Miguel Posted 19. October 2010

This weekend, my wife and I worked on I'm See You and Bridal Obsessions.
I was busy getting our public event model going while she was busy on the registration process in Bridal Obsessions.

It was at this point, the point after she had gotten the site to send the validation email (after registration), that she started getting frustrated with the amount of usability work she actually had left to do.

You see, when you write down a task that says "Create Registration Process for Bridal Obsessions" and you think about what it involves, you very rarely think that there is much 'usability' work to do around it. I mean, surely you just capture the users details and send them a validation email and that's it right? WRONG!

You see there's a whole 'workflow' that goes around a simple registration process that may go something like this:

  1. User enters details and clicks 'Register'
  2. Save user details
  3. Generate validation key
  4. Email the validation key to the user
  5. User opens email
  6. User clicks on link in email to validate
  7. Link redirects user to a page that accepts the email address and the validation key
  8. System validates this key against email and approves/declines user
  9. Log user in if validation key and email match

Now besides these 'basic' steps there's a whole bunch of new questions that you must ask yourself to close this 'loop' off.

  • What happens if the email never reaches the user?
  • What happens if the user registers again when the email doesn't arrive
  • What happens if the email goes into the users spam folder? How will you validate them then?
  • What happens if the email address doesn't exist?
  • Do you trace if the user has been to your site before and store their email address in a cookie, then check if they have validated and prompt them etc.

Answering these kinds of questions will force you to think from a user perspective and cover a lot more angles that you would initially have. Just imagine you were the one registering and you didn't get that email. Wouldn't you want an opportunity to have that validation email resent? What happens if you didn't get the validation email and you register again thinking it will resend it? What would you expect the system to do?

Now if you are doing this work for a client, these are the kinds of questions you must ask them to put some perspective in their heads around "Why the registration process will take 4 days and not 1?". It will also 'close the loop' around your 'Registration' task.

Remember: Don't underestimate the time you need on a task. Walk through the entire process you are about to code in detail and in your head, write down these steps as you go, you might just save yourself a lot of pain and prevent project burn in the end.

Tags:

So today I wanted to have an image that redirected the user to one of my actions on a controller upon clicking it. Just like an 'a' tag wrapped around an image.
Up until now I've been merely using links, or more specifically the Html.ActionLink method to generate my links.

After a quick search I found this method which is very straight forward:

The Url.Action() view helper method. This method generates a 'raw' url given the appropriate parameters.

Syntax (for one of its 8 overloaded methods):

Url.Action(string actionName, string controllerName);

Usage:

<a href='<%= Url.Action("Index","Home") %>'> <img src="image source here" /></a>

So using it to generate the raw url, pumping this url into an 'a' tag then wrapping the 'a' tag around an image achieved my goal.

Tags:

To convert a string to lower case in JavaScript we use the following steps:

var sometext=”This is some text.”;
var casechanged=sometext.toLowerCase();

Now the variable casechanged contains “this is some text.”. For upper case in JavaScript:

var sometext=”This is some text.”;
var casechanged=sometext.toUpperCase();

Now the variable casechanged contains “THIS IS SOME TEXT.”.

Tags:

This post is more for me than anything as I keep forgetting this and it is quicker for me to 'Google' it than remember it :)

The method that you want is 'indexOf()', obviously. But it's case sensitive and its result is zero based, meaning that if it finds your letter/word within the string you are searching, 0 indicates that your letter/word was found at the very first position in your search string.

This method returns a -1 if the string you are looking for is not found.

Example:

 

Search String
Text  


NB: The method is case sensitive so it's wise to convert your strings to lower case to ensure you find what you are looking for.

Tags:

Zooming in on a set of Google Markers

Author: Miguel Posted 13. May 2010

function ZoomInOnMarkers(markers) {
    var bounds = new GLatLngBounds;
    for (var i = 0; i < markers.length; i++) {
        bounds.extend(markers[i].point);
    }
    m_GRMap.setZoom(m_GRMap.getBoundsZoomLevel(bounds));
    m_GRMap.setCenter(bounds.getCenter()); 
}

Tags:

Meet the team

Eliana Ribeiro

Designer, Coder and Usability Fundi
View Profile

Miguel Ribeiro

Architect, Coder and Online Fundi
View Profile

Some of our work

Email Newsletters, Email Marketing, Web Design, Web Development Solution Architecture, Software Development, User Experience, Usability, Search Engine Optimization, Search Engine Marketing

Html, Xhtml, Html 5, CSS, jQuery, JavaScript, ASP.NET MVC, C#.NET, Web Services, ASP.NET (1-4), AJAX, ASP.NET AJAX, Transact-SQL

View more