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:

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