Finally, a SelectedItems Option (yaaay)

If you're like me you've often pondered why controls like CheckBoxList don't provide a way to get a collection of selected items.  You've always had the option to iterate the Items collection and evaluate the Selected property, but why should that have to be done over and over again?  I want a quick way to get the selected items from a CheckBoxList, ListBox, DropDownList, and RadioButtonList; all items which inherit from ListControl.

The excellent creation of extension methods makes it simple to get the selected items from a ListControl.

using System.Collections.Generic;

using System.Web.UI.WebControls;

 

namespace ListControlExtensions

{

    public static class ListExtensions

    {

        public static List<ListItem> SelectedItems(this ListControl list)

        {

            List<ListItem> items = new List<ListItem>();

            foreach (ListItem item in list.Items)

            {

                if (item.Selected)

                {

                    items.Add(item);

                }

            }

            return items;

        }

    }

}

 

Have you found an alternative to getting the selected items from a ListControl without looping through the Items collection?

kick it on DotNetKicks.com

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

A Generic JSON Serialization Extension Method Starring DataContractJsonSerializer

Download the sample code for this post. 

In October of 2007 The Gu wrote a ToJSON extension method using the JavaScriptSerializer class.  Since that time the JavaScriptSerializer class has been marked obsolete in favor of DataContractJsonSerializer.  In this post we’ll write an updated ToJSON method to satisfy every JSON extension method fantasy you have.  Quick agenda… the goal is to take a .Net object and convert it in to JSON text which would likely be consumed be a remote client.  Let’s start with the object to convert… an Address class.

using System.Runtime.Serialization;
 
...
 
[DataContract(Name = "Address", Namespace = "")]
public class PersonAddress
{
    [DataMember(Name = "City", Order = 1)]
    public string City { get; set; }
    [DataMember(Name = "Country", Order = 2)]
    public string Country { get; set; }
    [DataMember(Name = "PostalCode", Order = 3)]
    public string PostalCode { get; set; }
    [DataMember(Name = "State", Order = 4)]
    public string State { get; set; }
    [DataMember(Name = "Street", Order = 5)]
    public string Street { get; set; }
}


DataContract
and DataMember attributes provide information to the serialization process of how to structure the data.  It is possible to use the more familiar System.Serializable attribute however the output isn’t nearly as friendly.  More on that later.

The constructor for DataContractJsonSerializer we’re using requires knowledge of the Type of object being serialized to JSON.  For the purposes of this method we’re likely to not know which Type is to be serialized.  Quite often it will be a custom type.  We need our extension method to be more generic… I love .Net…  Here’s the method suitable for such a task:

using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

...

public static string ToJSON<T>(this T obj)
{
    MemoryStream stream = new MemoryStream();
 
    try
    {
        //serialize data to a stream, then to a JSON string
        DataContractJsonSerializer jsSerializer = new DataContractJsonSerializer(typeof(T));
        jsSerializer.WriteObject(stream, obj);
 
        return Encoding.UTF8.GetString(stream.ToArray());
    }
    finally
    {
        stream.Close();
        stream.Dispose();
    }
}

 

Be sure to reference System.Runtime.Serialization and System.ServiceModel.Web.

Let’s dissect a bit.  DataContractJsonSerializer needs to know the object type.  In our case it’s generic, so we’ll let typeof(T) figure it out for us.  The serializer WriteObject method wants a stream to write the serialization output to for which we’re using a MemoryStream; an easy object for retrieving text from.  And that’s what we do… convert the stream’s byte array into a string; our JSON string.

Let’s run this pup using the following code:

PersonAddress address = new PersonAddress();
address.City = "Newport Beach";
address.Country = "US";
address.PostalCode = "92626";
address.State = "CA";
address.Street = "123 Candyland Way";
 
string json = address.ToJSON();
 
Response.Write(json);


And the results:

{"City":"Newport Beach","Country":"US","PostalCode":"92626","State":"CA","Street":"123 Candyland Way"}

Earlier I mentioned if you used the [Serializable] attribute instead of the [DataContract] attribute your solution would compile and function however your results would come out a bit different.  Here’s the output when using Serializable:

<{"<City>k__BackingField":"Newport Beach","<Country>k__BackingField":"US","<PostalCode>k__BackingField":"92626","<State>k__BackingField":"CA","<Street>k__BackingField":"123 Candyland Way"}>

As you can see this is far less friendly to work with from a JSON consumer perspective… Make it easier on yourself and stick with DataContract in this case.

I hope this helps in your JSON endeavors.  Let me know if you have any questions of problems!

Download the sample code for this post.

kick it on DotNetKicks.com
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

LINQ to SQL: Selecting a Single Row

Tonight I'm playing around with LINQ to SQL using the AdventureWorks database.  I'm going to load a product from the Product table given the ProductID, therefore loading a single product.  Simple right?  There are a couple of was to construct a LINQ statement to retrieve a record:

LINQ Query 

public Product GetProduct(int productID)
{
    AdventureWorksDBDataContext db = new AdventureWorksDBDataContext();
    Product product = (from p in db.Products
                       where p.ProductID == productID
                       select p).Single();
    return product;
}

Using a Lambda expression 

public Product GetProduct(int productID)
{
    AdventureWorksDBDataContext db = new AdventureWorksDBDataContext();
    Product product = db.Products.Single(p => p.ProductID == productID);
    return product;
}

If you notice I'm using the Single() extension method, which will absolutely do the job... when the record exists.  The gotcha is if the record doesn't exist an exception is thrown.  Instead of using the Single() method, use SingleOrDefault().  This is one you'll learn the hard way... I did.  Here's a sample using the Lambda expression without worrying about an exception when the record is missing.

Using a Lambda expression with SingleOrDefault 

public Product GetProduct(int productID)
{
    AdventureWorksDBDataContext db = new AdventureWorksDBDataContext();
    Product product = db.Products.SingleOrDefault(p => p.ProductID == productID);
    return product;
}

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

.Net and C# Versioning Clarifications

Many people have a misconception regarding versions of the latest release of Beta 2 of the .Net Framework.  With .Net 1.0, 1.1, and 2.0, the framework and the language versions were released in parallel i.e. .Net Framework 2.0 released with C# 2.0, etc.  Then when .Net 3.0 came out the link was broken.  .Net 3.0 did not increment the version of the languages themselves; it was purely additions to the framework library which included Windows Communication Foundation (WCF), Windows Workflow Foundation (WF - I think WWF was taken), and Windows Presentation Foundation (WPF).  The languages themselves remained 2.0  As for Ajax.Net, it's logic is embedded in the framework therefore its version is also Ajax.Net 3.5.

The release of Visual Studio 2008, the IDE formerly known as Orcas, is bundled with .Net Framework version 3.5 and the languages (well, VB and C# at least) have been promoted to 3.0 versions.  Expect to see this trend continue, breaking the mold of the previous versioning coincidence.

kick it on DotNetKicks.com
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Extension Methods in C# 3.0

.Net 3.5 Extension methods are a great new way of adding functionality to an existing type – even a type you don’t have the source code to such as is the case with a .Net framework library type i.e. String.   Suppose you had a string and wanted to see if that string existed in another array of strings.  You can write your own loop to search, or you could write an extension method which would do it for you.  A method with the signature of bool IsInArray(string textToFind , string[] textArray) would appear to accomplish such a goal.  We can add such a method to the string type with C# 3.0 and the .Net Framework 3.5.

It isn’t completely obvious how this works so I’ll provide some clarification.  First of all, your extensions must be defined in a separate class and the namespace must be referenced in your code.  In this case we’d include a “using ExtensionMethodSample” statement to get access to StringExtensions.  Secondly, examine the signature of the IsInArray method.  The first parameter is “this string myString” which tells the compiler the method is an extension of string.  An argument isn’t explicitly passed to the method for myString, but the parameter can be used within the method as if it were.  Parameters 2…n are all explicitly supplied with arguments as you’ll see with Intellisense.


If we were to execute this call to IsInArray(this string myString, string[] stringArray), passing in the myStrings string array, we’d receive the Boolean value of True back because “hello” was in the myStrings array.

Gotchas

This appears to be a very promising way to add functionality to existing types however there are some “gotchas”: 

Signature Ambiguity (or lack thereof)

If you provide an extension method with the same signature as a method already available on the type you’re extending, the extension method is ignored.  Instead, you should create your own type derived from the type you’d like to extend and override the method or add an overload.  An example of this if you create an extension method of signature “string ToString()” for type String.  String already has a “string ToString()” method which would be the method called.

I did find I can create an additional overload of an existing type as an extension method.  Let’s take this same ToString() example.  If I added an overload which doesn’t yet exist for ToString() such as “public static string ToString(this string myString, int repeatCount)” then I’d have the base ToString() methods plus my new overloaded ToString method.


Type Modification

If the type you are writing an extension method for changes, your extension method may require modification to maintain compatibility.  This sort of goes without saying and is just as likely to be the case if you’ve derived a class from that type and added methods to your new class. 

Conclusion

As stated, Microsoft’s recommendation is to derive a class if possible and avoid extension methods.  I personally feel extension methods have their place with primitives and potentially asp.net built-in user controls.   These are types I just don’t want to derive from and modify – I prefer the built-in ease of use.  I’ve longed for a method on a checkbox list which returns a collection of items which were checked.  Instead we must loop through the checkbox list and build our own collection.  An extension method can resolve this issue for us without creating a completely new asp.net user control.

I’m sure we’ll see extension method libraries entering the community which provide often desired functionality not yet built into the .net framework and C#.

For more information, check out Scott Guthrie's blog article on .Net Framework 3.5 extension methods.

kick it on DotNetKicks.com
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

JsonQueryStringConverter Class

The JsonQueryStringConverter class comes equipped with the .Net Framework 3.5.  The basic premise here is you can serialize an object into a JSON-like string which can be passed via query string.  Typically this class is to interact via Windows Communication Foundation although it’s interesting to see how it works with a simple application.  I can see using this as a means to serialize and transport object data without going through web services and using SOAP.  You may find a practical application for this today.

Let’s start with a very basic type with some properties to show how this works.  We’ll have one of our properties be another type with properties to show a bit of hierarchy.  Note – your classes must be serializable.  I’ve marked both of my objects with the [Serializable] attribute.  The ToString methods I’ve added are for demonstration purposes to show the data in the objects.  We’ll use them below, but these are not requirements by any means.

[Serializable]
public class MyName
{
      public string First { get; set; }
      public string Last { get; set; }
      public override string ToString()
      {
            return string.Format("First: {0}, Last: {1}", First, Last);
      }
}

[Serializable]
public class MyClass
{
      public MyName MyName { get; set; }
      public string MyAddress { get; set; }
      public int MyAge { get; set; }
      public bool IsOld { get; set; } 

      public override string ToString()
      {
            return string.Format("MyName: {0}, MyAddress: {1}, MeAge: {2}, IsOld: {3}", MyName.ToString(), MyAddress, MyAge, IsOld);
      }
}

 

As you can see we’ve create two types; MyClass and MyName, with MyName being a type used within MyClass.  We’re also using auto-implemented properties.  If you’d like a bit more info on those, check out this short explanation.  Next, we’re going to instantiate an object of MyClass, and convert it to a JSON string for ease of passing over the web.  We’ll do this using the System.ServiceModel.Dispatcher.JsonQueryStringConverter class (you must reference the System.ServiceModel.Web assembly first).

void JsonQuerystringConversion()
{
      //setup object to test with
      var me = new MyClass();
      me.IsOld = false;
      me.MyAddress = "123 My Way";
      me.MyAge = 29;
      me.MyName = new MyName { First = "ian", Last = "suttle" }; 

      //convert object to JSON value
      JsonQueryStringConverter jsonQ = new JsonQueryStringConverter();
      string value = jsonQ.ConvertValueToString(me, typeof(MyClass));
      Response.Write(value);
}

If you compile and run it you’ll see this method create a string as follows:

{"_x003C_IsOld_x003E_k__BackingField":false,"_x003C_MyAddress_x003E_k__BackingField":"123 My Way","_x003C_MyAge_x003E_k__BackingField":29,"_x003C_MyName_x003E_k__BackingField":{"_x003C_First_x003E_k__BackingField":
"ian","_x003C_Last_x003E_k__BackingField":"suttle"}}

That’s great, but we must also be able to revert this data to an object to get the best bang for the buck.  That’s just as easy, if not easier, than what we just did.

void JsonQuerystringToObject()
{
      //convert querystring value to object
      JsonQueryStringConverter jsonQ = new JsonQueryStringConverter();
       //naturally this would come from the querystring and never as a hard-coded string here
      string value = "{\"_x003C_IsOld_x003E_k__BackingField\":false,\"_x003C_MyAddress_x003E_k__BackingField\":\"123 My Way\",\"_x003C_MyAge_x003E_k__BackingField\":29,\"_x003C_MyName_x003E_k__BackingField\":{\"_x003C_First_x003E_k__BackingField\":
\"ian\",\"_x003C_Last_x003E_k__BackingField\":\"suttle\"}}";

      var fromString = jsonQ.ConvertStringToValue(value, typeof(MyClass));
      Response.Write(fromString.ToString());  //This is why we added the ToString method
}

A couple of items to point out as the inline documentation already does:a) we’d never have value in hard-coding the JSON string into the code like this and would likely grab it from the Request object 
b) the last line of this method uses the ToString method we added to display the values in the MyClass object.
And the result: 

MyName: First: ian, Last: suttle, MyAddress: 123 My Way, MeAge: 29, IsOld: False

Bingo – the JSON string was successfully converted back into a MyClass object, with the MyName property being created properly as well.

 

kick it on DotNetKicks.com

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Implicitly Typed Local Variables

C# 3.0 introduces  implicitly typed local variables by way of the keyword “var”.  The use of var allows one to assign a number of different types to a variable without explicitly stating that variable’s type.  Var is actually not a type at all, but a keyword which instructs the compiler to infer the most appropriate type based on the value or expression to the right of the equals sign. If you’ve developed in the pre-.Net ASP languages you might be inclined to think of var as “Variant” - but don’t J.  Forget everything you’d previously learned about variant types as var is not even a loosely or late-bound type; it no longer applies.

Let’s compare apples to apples here.

In C# 2.0 we would declare variables in a method in this manner:

void MyMethod()
{
    int x = 5;
    string name = “ian”;
}

This type of declaration makes it quite obvious what a variable’s type is, and the value it will contain. 

Using var in C# 3.0:

void MyMethod()
{    
    var x = 5;
    var name = “ian”;
}

As you can see above the use of var is indeed syntactically a bit faster, and offers a variable the ability to receive an unknown (at design time) value type.  You really get what you pay for however.  Even though var has its place with LINQ, it would seem abuse of the keyword for standard variable usage could lead to ambiguity when reading or supporting the code.  One major plus on this note, I found if I assign var x = 5, VS knows it’s an int at design time.  If I then change this to be var x = 5 * 1.2452, VS recognizes it as a double at design time.  Quite impressive!

What are the constraints of using implicitly typed local variables?  Here’s a quick list:

- Must be declared within a method
- Cannot be passed as arguments to other methods
- Can be used in “for” initialization:
     - for (var x = 0; x < myArray.Length; x++) …
- Can be used in “foreach” initialization:
     - foreach (var item in myItems) …
- Can be used in a “using” statement:
     - using (var cmd = db.GetStoredProcCommand("_usp_AccountDelete"))…

Lastly, C# 3.0 also provides for implicitly typed arrays, and is a key player in LINQ utilization.  More on that soon.

kick it on DotNetKicks.com

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Auto-Implemented Properties

.Net Framework's Auto-Implemented Properties, also known as Automatic Properties, are a nifty way of saving a few lines of code without sacrificing performance.  Previous to .Net 3.5 one would typically write a property as follows (C#):

string _name = string.Empty;
public string Name
{
     get { return _name; }
     set { _name = value; }
}

Let's pretend creating the local variables to hold our simple property value is mundane (okay, it is).  Wouldn't it be oh so nice to cut this down to the following code:

public string Name { get; set; }

public string Country { get; private set; } //creates a read-only property

Well you're in luck because that's all there is to it!  When this code is compiled, the compiler will output equivalent logic to the pre-.Net 3.5 property.  Naturally this isn't practicle if you want to modify the private/protected value vs. the public value, but for the basic property such as one you may find in an entity class, Auto-Implemented Properties are quite useful.

kick it on DotNetKicks.com

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

About Me

I'm Ian Suttle and I work for IGN Entertainment, a division of Fox Interactive Media.

Recent posts