advanced web statistics

Set Silverlight Startup Page

In sandboxing Windows Phone 7 recently I came across the need to change my startup page.  The reasoning for this is simple: I have a core of the work completed and I want to sandbox a data call before I implement in the actual application.  With conventional web projects this is as easy as right-clicking the file you want to and click 'Set As Start Page'. With the Windows Phone 7 SDK this luxury does not exist.

There is however a way to accomplish this with a little bit of code.  Simply open up your projects App.xaml.cs and implement an Application_Startup method.

private void Application_Startup(object sender, StartupEventArgs e)
{
    RootVisual = new SandboxPage();
}

SandboxPage is the name of my XAML page in this example. Here we simply set the RootVisual to an instance of our new page.

The second piece to this is registering this startup method in the App constructor a la:

public App()
{
    Startup += Application_Startup;
}

This doesn't necessarily apply to Windows Phone 7.  General Silverlight.

Easy.

Tags: C#, Silverlight, Windows Phone

Microsoft Office Interop Outlook & C# For Outlook Searches

I had a need yesterday to query a bunch of Outlook e-mails: 44,743 to be exact.  This was the result of a clients mailing list account being setup incorrectly and we just found out about it!  An e-mail account was setup strictly for the mailing list and it was never properly setup as an Outlook account locally.  No big deal.  When the hosting provider contacted us to clean it up I noticed that there were a BUNCH of bad e-mail addresses (Return to sender, bad account, etc...).  At first I started to click on individual e-mails, copy the bad e-mail address to a .txt file, then search that folder for the same e-mail address and delete the results.  That takes FOOOOORRREEEEVVVVEEEEERRRRRRR.  Then I realized I could dork around with Outlook via a C# console application and harvest the e-mails and output them in a sorted Excel spreadsheet.

Enter Microsoft.Office.Core and Microsoft.Office.Interop.Outlook namespaces. I decided it would be best to create a little C# console application utilizing these namespaces to search the e-mail, write a little regular expression pattern (by write I mean copy & paste one from the interwebs) to parse out e-mail addresses, and add e-mail addresses that didn't have the host name or the reply e-mail account in it to a List<string> (if it didn't already contain it!).  It was pretty easy.

First:

using Outlook = Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Interop.Outlook;

I'm not going to bore you with the entire application unless you really want it.  I'll just get you to the point where you can start to do stuff with your e-mails.

Now you need to instantiate your Outlook object.

Outlook.Application application = new Application();
Outlook.NameSpace nameSpace = application.GetNamespace("MAPI");
Outlook.MAPIFolder mapiFolder = nameSpace.GetDefaultFolder(OlDefaultFolders.olFolderJunk);

It might be worth mentioning the olFolderJunk business you see there.  In the interest of time I didn't want to mess around with trying to navigate to the folder that I actually stored these e-mails in since I have a bunch of subfolders in Outlook due to using multiple accounts and a handful of rules and what-not.  So in the interest of time I moved all the e-mails to the junk folder since I could easily access it.  I think the correct syntax would be something like:

nameSpace.Folders["FOLDER"].Folders["SUB"].Folders["YOU_GET_IT"];

Moving on.  Once you finally get access to your designated folder you need to start being able to do stuff with the items in that folder.  It's as easy as enumerating the, you guessed it; MailItem objects a la:

foreach (MailItem mailItem in mapiFolder.Items)
{
   // do stuff
}

Easy.  The properties are fairly braindead as well.  MailItem Object Members

Have fun.  I'll probably use this in the future as well.

Tags: C#, Code

Silverlight ObservableCollection Bug Will Be the Death of Me

BUG: Items are sorted correctly sometimes, other times not so much.

FREQUENCY: Intermittent, never when debugging and stepping through everything, always seems to happen when I'm not.

RATING: Probably the most painful bug I've worked on in some time.

So I've got an ItemsControl in a custom XAML user control.  All this does is display an IEnumerable<T> of video items.  Simple.  To provide a better user experience we implemented an ObservableCollection<T> as the source of the ItemsControl with a Collection_Changed event so we can add one item at a time to the collection so as to not wait for the entire collection to populate before displaying to the user.  Now we're able to display the first 2 items and the scrollbar height shrinks as items are being added.  It's a nice user-experience.

Anyway, so for the implementation.  When the VideoRetrieveComplete event fires (after making a web service request for the data) we call the UpdateVideoCollection method.

UIThread.Run(delegate
{
   videoListControl.UpdateVideos(args.VideoItems);
   videoListControl.itemsControlVideoListing.DataContext = new VideoItem();
}

Notice that we're doing this in the UI Thread.  The code above is located in our Controller class.  The args.VideoItems is an IEnumerable<VideoItem> and they are sorted in the order they need to be in.  I have verified this time and time again with painful debugging.

Now time for VideoList controls properties, objects, and methods:

public int CurrentPageIndex { get; set; }
public ObservableCollection<VideoItem> ObservableCollection { get; set; }
private List<VideoItem> VideoItems = new List<VideoItem>();

Constructor where everything is initialized.  Probably important to include this.

public VideoList()
{
   CurrentPageIndex = 0;
   InitializeComponent();
   ObservableCollection = new ObservableCollection<VideoItem>();
   itemsControlVideoListing.ItemsSource = ObservableCollection;
   ObservableCollection.CollectionChanged += CollectionChanged;
}

public void UpdateVideos(List<VideoItem> videoItems)
{
   UIThread.Run(delegate
         
   {
               VideoItems.AddRange(videoItems);
               ObservableCollection.Clear();

               if (VideoItems != null && VideoItems.Count > 0)
               {
                  VideoItem videoItem = VideoItems[0];
                  VideoItems.RemoveAt(0);
                  ObservableCollection.Add(videoItem);
               }
            });
}

void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
   if (VideoItems.Count > 0)
      UIThread.Run(delegate
               
{
                  VideoItem videoItem = VideoItems[0];
                  VideoItems.RemoveAt(0);
                  ObservableCollection.Add(videoItem);
               });
}

The reason for removing an item, and then re-adding it is that this is the only way we can get our Converters to fire off, otherwise the collection hasn't changed and UI elements don't update.  For example, switching between tabs the user can add videos to their playlist.  Each time the tabs are selected and the VideoListing populates the VideoItems within that listing needs to show either an ADD / DELETE FROM PLAYLIST button depending on whether or not the item is in the playlist.  If there's another way to get those Converters to fire off I'm all ears.

So the problem is that more often than not the videos, which come in sorted correctly, are not always displayed that way.  For example, if I have 5 videos with dates 10/1/2008, 10/1/2008, 9/30/2008, 9/29/2008, 9/28/2008 sometimes the sort will be:

10/1/2008
9/30/2008
9/29/2008
9/28/2008
10/1/2008

or:

9/30/2008
9/29/2008
10/1/2008
9/28/2008
10/1/2008

You get the idea.  Could it be that we are not implementing this correctly?  Do we need to rebind the ItemsControl or is this correct?

I've been working on this bug for a day and a half now and have nothing.  I'm sure it's probably something stupid.

I'm all ears if you have anything. ANYTHING!

Oh, should probably add that if I page to the next listing of videos and then back it'll remedy itself!

Tags: C#, Silverlight

No Generic List FindAll Method in Silverlight 2 Beta 2

Came across a need this morning to use the FindAll method. To my dismay it wasn't there.  I know that Silverlight uses a subset of the .NET Framework but the System.Collections.Generic namespace is definitely there.

System.Collections.Generic namespace in Silverlight 2 Beta 2

You can clearly see that I'm using the namespace in the above image.

ReSharper List.FindAll Error Silverlight 2 Beta 2

Here you can see that ReSharper's background compiling caught it right away. For a second there I thought: "You know, maybe ReSharper is full of shit. This can't be right." I tried to compile to make sure (which was the case with the version 4 nightly builds).

'System.Collections.Generic.List' does not contain a definition for 'FindAll' and no extension method 'FindAll' accepting a first argument of type 'System.Collections.Generic.List' could be found (are you missing a using directive or an assembly reference?)

Weird.

Tags: C#, Silverlight

JSON Serialization with Silverlight Isolated Storage For the Win

I'm going to post this to help others who are killing themselves trying to figure out IsolatedStorage in Silverlight 2 Beta 2.  Ordinarily I'd post stuff like this for my own reference but I have had it beaten into my head for the past 12 straight hours.

The IsolatedStorageFile class abstracts the virtual file system for isolated storage.  It can be used to store stuff such as application settings or user login information.  The application settings being persisted on a user's machine were exactly what we needed to accomplish so that led me down this road.  I read numerous blogs, watched countless videos, and did endless searching and finally crafted my solution as a hodge-podge of all of them!

First, what didn't work.

Channel 9 had a video on "how easy it is to persist user application settings" using IsolatedStorage.  Their solution consisted of the following:

public class LocalStorageHelper
{
    private const string KEY = "FOO";

    public static object RetrieveObjectFromLocalStorage()
    {
        if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY))
            return IsolatedStorageSettings.ApplicationSettings[KEY];

        return null;
    }

    public static void UpdateLocalStorageObject(object value)
    {
        if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY))
            IsolatedStorageSettings.ApplicationSettings[KEY] = value;
        else
           
IsolatedStorageSettings.ApplicationSettings.Add(KEY, value);
    }
}

Simple enough.  The video presenter did all sorts of cool things like shut down the browser, open it back up, press F5 repeatedly and the storage still contained the user data.  I'm guessing this solution worked flawlessly in Beta 1.  I also had to add the checks for whether or not the ApplicationSettings contained the specified key.  Needless to say this implementation isn't very reliable.

It was then that I started looking into JSON and other storage options.  I remember in .NET 2.0 I was used to serializing objects into XML and thought I would take this route.  This was easier said than done because Silverlight is using a subset of the .NET Framework and the XML Serialization namespace didn't make it.  (NOTE: I could've used Linq XML but it was an after thought!).

Enter the DataContractJsonSerializer class.  Since we are only given a default storage of 1MB (more can be requested but the end-user has the option of shutting you down) JSON is a likely candidate since it isn't as verbose as XML.  A simple string written in a text file within the file store is more than sufficient enough to give us an instance of the object which holds the properties we want to persist.

Some code for converting an object to JSON string and vice-versa.

public static string ConvertObjectToJsonString(object input)
{
   try
   
{
      using (MemoryStream memoryStream = new MemoryStream())
      {
         DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(input.GetType());
         dataContractJsonSerializer.WriteObject(memoryStream, input);
         memoryStream.Position = 0;

         using (StreamReader streamReader = new StreamReader(memoryStream))
            return streamReader.ReadToEnd();
      }
   }
   catch (InvalidDataContractException)
   {
      return string.Empty;
   }
}

public static T ConvertJsonStringToObject<T>(string json)
{
   try
   
{
      using (MemoryStream memoryStream = new MemoryStream())
      {
         byte[] bytes = Encoding.Unicode.GetBytes(json);
         memoryStream.Write(bytes, 0, bytes.Length);
         memoryStream.Position = 0;

         DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(T));

         return (T)dataContractJsonSerializer.ReadObject(memoryStream);
      }
   }
   catch (SerializationException)
   {
      return default(T);
   }
}

You might notice the InvalidDataContractException I am catching above.  Like with XML Serialization you want to mark a class & properties as Serializable.  If you don't you won't be able to serialize it.  Hence the catch block.  Here's an example of a serializable class:

using System.Runtime.Serialization;

namespace LocalStorage.Objects
{
   [DataContract]
   public class UserAccount
   
{
      [DataMember] public string EmailAddress { get; set; }
      [DataMember] public string Password { get; set; }
   }
}

I'll show an example of how to store the user account in a second.  First how to open / create this in isolated storage.

public static void SaveDataToLocalStorage(string data, string filename)
{
   try
   
{
      using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
      {
         if (!isolatedStorageFile.FileExists(filename))
         {
            using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream(filename, FileMode.Create, isolatedStorageFile))
            using (StreamWriter streamWriter = new StreamWriter(isolatedStorageFileStream))
               streamWriter.Write(data);
         }
         else
         
{
            using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream(filename, FileMode.Open, isolatedStorageFile))
            using (StreamWriter streamWriter = new StreamWriter(isolatedStorageFileStream))
               streamWriter.Write(data);
         }
      }
   }
   catch (IsolatedStorageException)
   {      
   }
}

public static string RetrieveDataFromLocalStorage(string filename)
{
   try
   
{
      using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
      {
         if (!isolatedStorageFile.FileExists(filename))|
            return string.Empty;

         using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream(filename, FileMode.Open, isolatedStorageFile))
         using (StreamReader streamReader = new StreamReader(isolatedStorageFileStream))
            return streamReader.ReadToEnd();
      }
   }
   catch (IsolatedStorageException)
   {
      return string.Empty;
   }
}

I apologize for the mess but those are some pretty lengthy class names and descriptive variable names 8^)

So now how to use:

// instantiate our user
UserAccount user = new UserAccount
                              
{
                                 EmailAddress = "asdf@asdf.asdf"
                                 Password = "stupid"
                              
};

// convert to JSON string
string json = ConvertObjectToJsonString(user);
SaveDataToLocalStorage(json, "UserAccount.txt");

// convert back to UserAccount
string json = RetrieveDataFromLocalStorage("UserAccount.txt");

if (!string.IsNullOrEmpty(json))
{
   UserAccount account = ConvertJsonStringToObject<UserAccount>(json);
   // do stuff with userAccount here...
}

Now the user can be persisted on each site visit.  If you wanted to store the email address and password you could log your user in when they visit the application.  Think "remember me" checkbox or something similar.  Another good use would be to serialize the RSS categories and only display those articles from within your silverlight application.

The possibilities are endless.  Remember that this information is stored with the client in their AppData folder so don't put anything too private in there ;)

Easy.

UPDATE
If this is a little too cluttered for you to read might I suggest viewing the RSS feed.

Tags: C#, Silverlight

Silverlight Databinding and Interaction with Controls

Busy, busy with Silverlight lately.  I'm starting to really enjoy it and am learning a ton.  It's still so new to me that I don't know if I'm doing everything correctly but I am getting stuff to work ;)

The biggest issue I've had with Silverlight lately is databinding and interacting with the bound data.  For example, with ASP.NET you can bind a List<Foo> to a Repeater and implement a method for ItemDataBound event that wires up each of the hyperlinks, buttons, etc... to perform certain actions when each Repeater item is databound.  In Silverlight you do not have this luxury.  The more I work with Silverlight the more I realize that you don't need this.

The way I have been working with Silverlight is the same as working with ASP.NET in that I am a big fan of encapsulation of functionality.  This means modularizing a XAML control with a C# code-behind much like an ASCX in ASP.NET.  Let's say you have 2 controls: Article, and ArticleList.  ArticleList is simply an ItemsControl of Article's. Simple.  Here is the XAML:

ArticleListing.xaml

<StackPanel x:Name="stackPanelArticleListing">
   <ItemsControl x:Name="itemsControlArticleListing">
      <ItemsControl.ItemTemplate>
         <DataTemplate>
            <Controls:Article x:Name="article" />
         </DataTemplate>
      </ItemsControl.ItemTemplate>
   </ItemsControl>
</StackPanel> 

Simple enough. All the binding syntax is in the Article.xaml.  In the Article.xaml I have a TextBox called "textArticle" that displays the entire article.

What if I have a button in my Article control that, when clicked, displays the full article in an ArticleViewer control?  It's actually pretty easy if you set the DataContext of the ItemsControl control.  I've got another Silverlight Class Library as part of my solution and I've got a class called Article.  Article looks like this:

public class Article
{
   public Guid ArticleId { get; set; }
   public string Author { get; set; }
   public string Body { get; set; }
   public string Introduction { get; set; }
   public DateTime PublishDate { get; set; }
   public string PublishDateShort { get; set; }
   public string AuthorUrl { get; set; }
   public string AuthorImageUrl { get; set; }

So when I go to bind my List<Article> to the ItemsControl I would do this:

itemsControlArticleListing.DataContext = new ArticleLibrary.Article();

var results = ArticleLibrary.Article.RetrieveAllArticles();
itemsControlArticleListing.ItemsSource = results; 

So now in my Article control I can get the current DataContext by way of the following:

TextBlock textBlock = sender as TextBlock;

if (textBlock != null)
{
   var article = textBlock.DataContext as ArticleLibrary.Article;

   if (article != null)
   {
      // set another control's text property to article stuff :D
   
}

So I set a breakpoint and you can see that my article object above won't be null:

Article != null

You can also see that I was able to get the exact object that I clicked on.  Well, you really can't see it because of the lack of screen grabs but take my word that this is the one that I clicked on.

Article object local information

Awesome right?

Sorry if this post is all over the place.  It's been a work in progress and I've been adding snippets here and there in between work!

Tags: C#, Silverlight

Elegant Way of Executing a Stored Procedure using LINQ?

I was working in a project today and I was trying to create a generic way of using a DataContext class to execute a stored procedure.  Of course there's the way of dragging a stored procedure onto the designer, etc... but I'm not interested in this at the moment.  TBQH, I haven't even been doing the ORM mapping in this manner lately after using the System.Data.Linq.Mapping namespace to map a POCO (Plain 'Ole CLR Object) to an actual SQL table (as well as using ColumnAttribute's to map the properties to columns.  This is extremely helpful for larger 2.0 projects that were recently converted to 3.5.   Some might argue that this isn't how LINQ was supposed to be used or that it makes it more complicated.   First of all, I don't think that there is any right or wrong way to use LINQ.  Secondly, I find it can be a pain to have to remove the table from the designer, reconnect via Server Explorer, refresh the database, re-drag onto designer over-and-over when making changes to tables, views, procedures, etc...  This is also problematic if you don't have access to a production database from your dev environment.  Most web servers I experience don't have Visual Studio 2008 installed so it's not like I can quickly generate a newer set of LINQ-to-SQL classes.  If a table column name changes, I simply refactor the corresponding property in my library and I'm good to go.

[Table(Name = "dbo.FooTable")]
public class Foo
{
   #region Table Columns / Properties

   [Column]
   public long FooId { get; set; }

   [Column]
   public string FooName { get; set; }

   [Column]
   public string FooDescription { get; set; }

   #endregion Table Columns / Properties

Easy.

public class Database<TDataContext, TEntity>
{
   // ...   
}

Take the previous data access helper class.  Let's say I want to create just a generic function to execute a stored procedure against my database.  Let's call it "ExecuteCommand".

public static void ExecuteCommand(string command, object[] parameters)
{
   if (string.IsNullOrEmpty(command))
      throw new ArgumentNullException("command");

   using (var database = new TDataContext())
      database.ExecuteCommand(command, parameters);

Basic.  The implementation is pretty mindless as well.

Database<MyDataContext, TFoo>.ExecuteCommand("CommandName", null); 

This sucks when you have parameters because I haven't found any documentation on how to execute a procedure elegantly using this approach.  It appears that the DataContext.ExecuteCommand approach is best-suited for on-the-fly dynamic SQL.... gross!  I also read (need to find the link again) that some super-sleuthing uncovered that parameter substitution is silently ignored.  (I'll have to check back on that)

I did find a way to implement using a stored procedure....

string command = string.Format("exec Command '{0}', {1}", "string", 1);
Database<MyDataContext, TFoo>.ExecuteCommand(command, null); 

That is disgusting.  Not a huge fan.  What if you have a procedure that has 5, 10, 20 parameters? Ouch.  What if your input parameters contain ' 's? You would then have to replace all ' with a ''.

Any suggestions?  I'm hoping that there is a much more elegant / succinct way of doing this that I haven't found yet.  I've tried to "RTFM" as they say but a couple thousand pages of LINQ reference books and I've got nothing.

Here's a little 2.0 throwback of what I'm trying to accomplish.  Like I said before, there has to bge a more elegant way of doing this with the 3.5 Framework / LINQ / DataContext that doesn't involve dragging-and-dropping procedures onto the designer.

public static int ExecuteProcedure(List<SqlParameter> parameters, string command)
{
   try
   
{
      using (DBManager manager = ...)
      {
         manager.Open();
         manager.CreateParameters(parameters.Count);

         for (int i = 0; i < parameters.Count; ++i)
            manager.AddParameters(i, parameters[i].ParameterName, parameters[i].Value);

         return (int) manager.ExecuteScalar(CommandType.StoredProcedure, command);
      }
   }
   catch (SqlException)
   {
      return 0;
   }

Help me from the following please!!

StringBuilder query = new StringBuilder("exec Command ");
query.AppendFormat("{0},", foo.FooProperty1);
query.AppendFormat("'{0}',", foo.FooProperty2.Replace("'", "''"));
query.AppendFormat("'{0}',", foo.FooProperty3.Replace("'", "''"));
query.AppendFormat("'{0}',", foo.FooProperty4.Replace("'", "''"));
query.AppendFormat("'{0}',", foo.FooProperty5.Replace("'", "''"));
query.AppendFormat("'{0}',", foo.FooProperty6.Replace("'", "''"));
query.AppendFormat("'{0}'", foo.FooProperty7.Replace("'", "''"));

Database<MyDataContext, Foo>.ExecuteCommand(query.ToString(), null); 

Tags: C#, LINQ

LINQ and Generic GetRecord Method

Lately I've been abstracting some LINQ functionality into a Generic Data Access Class so that it can be reused across multiple projects without having to write out functionality over-and-over (i.e. creating a RetrieveProductsByProductId method, AddNewProduct, DeleteProduct, etc...).

CRUD'ing is a braindead process using LINQ & Generics.  I've found that Update is / can be a huge pain in the ass.  I currently have 2 versions of an update method (working on a 3rd) but just thought I'd kick-off the next couple of posts by posing the following question:

Question:  How well do you think the following would scale?

public T GetRecord<T>(int primaryKey) where T : class
{
   using (var database = new TData())
      return database.ExecuteQuery<T>(string.Format("SELECT * FROM {0} WHERE ID={1}", typeof(T).Name, primaryKey)).Single();

I found this little beauty during my travels to find examples of generic update methods.  This is obviously not an update method but definitely worthy of posting by me.  This seems a little too specific to the database implemented so it begs the question of why one would even try to make it generic.

Here's how I (and Dwight) would implement:

public static T GetRecord<T>(Expression<Func<T, bool>> predicate)
{
   if (predicate == null)
      throw new ArgumentNullException("predicate", "lulz");

   return new TData().GetTable<T>().Where(predicate).SingleOrDefault();
}

Not Shakespeare but it sure is a lot more practical than the previous example IMHO.

var foo = DataAccess<FooDB>.GetRecord<Foo>(f => f.Name == "Stihl 066");

Easy.  I'll be prepping some more entries related to Generic updating of SQL data soon.  I could really use some feedback from some more seasoned LINQ'ers.

Tags: C#, LINQ

LINQ and Reflecting Object Properties

In working on a recent project over the weekend I decided to switch to .NET 3.5.  I haven't implemented OR/M with LINQ yet so I decided to re-write some of the class library functionality (and existing Data Access Layer) using LINQ, lambda's, and other syntactical sugar.  Keep in mind this is a personal project so I can spend some time wasting time!

One of my original methods in the DAL is called Create Parameters. This simply takes an object as a parameter, iterates the properties and creates a SqlParameter and adds it to a List<T>.

public static List<SqlParameter> CreateParameters(object input)
{
   List<SqlParameter> parameters = new List<SqlParameter>();

   foreach (PropertyInfo p in input.GetType().GetProperties())
      parameters.Add(new SqlParameter(p.Name, p.GetValue(input, null)));

   return parameters;

Pretty basic.  With new C# syntax this can be reduced to one line a la:

public static IEnumerable<SqlParameter> CreateParameters(object input)
{
   return input.GetType().GetProperties().Select(p => new SqlParameter(p.Name, p.GetValue(input, null)));

You will noticed that I changed to IEnumerable<SqlParameter>. It can just as easily be converted to List<SqlParameter> by using the ToList extension method.

public static List<SqlParameter> CreateParameters(object input)
{
   return input.GetType().GetProperties().Select(p => new SqlParameter(p.Name, p.GetValue(input, null))).ToList();
}

It should also be worth mentioning that I prefer the above method's syntax over that of the traditional LINQ syntax:

public static List<SqlParameter> CreateParameters(object input)
{
   
return (from p in input.GetType().GetProperties() select new SqlParameter(p.Name, p.GetValue(input, null))).ToList();
}
 

I probably won't have much use for these methods after implementing LINQ-to-SQL as it provides a pretty braindead process to CRUD data. 

Tags: C#, LINQ

Guid Extension Methods

Another "Late Pass" series entry.  I've just recently started using extension methods and seeing how useful they can be.  Extension methods have been pretty fun to write so far.  It's nice to find yourself wanting a piece of functionality and then having the power to now do it.

My first extension method deals with Guids.  I tend to use Guids a lot and there is no real way to convert something to a Guid.  Let's say you have a QueryString value that is a unique identifier (i.e. Guid) and you want to check for it, convert it to a Guid, then do something with it (i.e. retrieve employee information, etc...) I've found that to do this I'd need to some variation of the following:

string s = Request.QueryString["Guid"];
Guid guid == Guid.Empty;

if (!string.IsNullOrEmpty(s))
   try
   {
      guid = new Guid(s);
   }
   catch (FormatException)
   {
      guid = Guid.Empty;
   }

if (guid != Guid.Empty)
{
   
// do stuff with Guid g
}

Enter my first extension method: IsGuid(). This provides a less verbose method of doing business.

if (s.IsGuid())
{
   Guid guid = new Guid(s);
   // do stuff with guid

There is another option:

Guid guid = Request.QueryString["Guid"].ConvertToGuid();

if (guid != Guid.Empty)
{
   // do stuff with Guid

Here is the code for the extension methods. First you will you need a RegularExpression for the format of the Guid.  That's easy enough as Guids have the same format 8-4-4-4-12 (would provide a link to where I found this regular expression but I forgot where I got it 8^( )

private static readonly Regex _guidRegex = new Regex(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", RegexOptions.Compiled); 

Now the actual methods:

public static bool IsGuid(this string value)
{
   return !string.IsNullOrEmpty(value) ? 
            _guidRegex.IsMatch(value) : false;
}

public static Guid ConvertToGuid(this string value)
{
   return string.IsNullOrEmpty(value) ? Guid.Empty : 
      (_guidRegex.IsMatch(value) ? new Guid(value) : Guid.Empty);

Again, I apologize for the line breaks.  I need to implement a new CSS layout.  By implement I mean find a free one that isn't a complete mess.

I'll be posting more extension methods in the future.  Too bad I missed the bus a couple of months ago!

Easy.

Tags: .NET, C#, Code
<< Newer Entries Older Entries >>