Matrix Code Tunnel

Refactored: Creating dynamic/configurable parameterized queries in Entity Framework

A little while back I posted about a technique I was using to setup parameterized queries using Entity Framework. I had posted to the .Net group on Google+ and received some amazing feed back from Dan Nemec and Chris McCall and refactored the code. It’s cleaner, easier to work with, and hopefully a bit more optimized too. Here’s what’s different. Continue reading

Computer Code

Creating dynamic/configurable parameterized queries in Entity Framework

EDIT: A better, refactored version of this can be found here.

Entity Framework is an amazing tool. It allows you to quickly and easily get your basic queries and updates running with little hassle. In addition, you have business objects to interact with, which makes your middle tier (or your controller) that much easier to work with. However, when you need to start setting up more dynamic queries from user input, things start to get tricky. Here’s a solution I created to help with that. Continue reading

How to run PHP applications in Visual Studio 2012

A PHP app launched from Visual Studio 2012

A PHP app launched from Visual Studio 2012

Note: This post comes as a HT to this StackOverflow question, I’m just tweaking a few things to accomodate for VSMMXII…

I’m working on a project to convert a PHP application to a .Net MVC application. The initial prototype has some nice bootstrap/highcharts functionality, so I want to preview the site locally as I’m migrating the code over. Instead of starting up or installing a new editor, I wanted to take advantage of IIS Express that comes with Visual Studio 2012 to run the app. It’s really easy to setup and here’s how to do it. Continue reading

2012 in review

2012 Year in Review

So here we are, the end of another year and while I don’t blog for a living, I try to be serious enough about it that stats matter. Plus it’s fascinating to see how the year pans out in my blog. Here’s some interesting info for a year in review. Continue reading

Log4Net: A Quick Start Tutorial and Guide with MVC and SQLite

Note: A lot of this is duplicated from my original post, but I felt it helpful to add a new post with new technology!

Synopsis

Log4Net, a port of the well known Log4J being used in Java environments, provides a feature rich, highly configurable, and simple to configure logging mechanism that you can have up and running in no time. This article will give you a basic overview of the library and how you can integrate it into your projects quickly and easily. Continue reading

Quick Tip: Aborting builds in Visual Studio based on file contents

Quick TipRemember a little while back when I had that problem with Entity Framework and SQL Server 2005/2008 databases? Well, it raised it’s ugly head again, and I was looking for a way to detect our error. Fortunately, we can setup a pre-build event to detect the bug and stop the process from going further. Continue reading

Quick Tip: How to Download a File from Amazon S3 and Prompt the User Using .Net

Quick Tip

Amazon S3 is a wonderfully simple and powerful way to have mass storage at your disposal in the cloud. Amazon provides a wonderful SDK with great examples on how to do the common tasks. However, I ran into one issue I didn’t see an example for, and spend the better part of a day piecing my way though. How do download a file from S3 using a web application and prompt the user on what to do with the file. Continue reading

Computer Code

Automatic User and Time Stamping in Entity Framework 4

Computer Code

Lately I’ve had the opportunity to really dig deep with Entity Framework 4. While I’m not utilizing the “Code First” approach, I’m still quite happy with now nice the Entity Model can take my existing database and build practically everything I need for my application’s data layer, and most of my business layer. The one tricky thing to resolve still is automating the user/time stamping that we use to track changes in the application. Continue reading

Changing Log4Net Configurations Dynamically

One  issue I’ve run up against over my time using log4net is being able to change the logging levels dynamically. When I build an application, I put in both top level Error/Fatal log messages, but I also put Debug/Info level messages when issues arise that I need to handle (check out my Quick-Start Guide if you’re curious on how to set this all up). By default I have the logging level set to WARN, but I want to be able to quickly see DEBUG level messages when things aren’t working properly.

Changing the configuration on the fly works fine in a development environment, but in a production environment, I don’t have access to the configuration file to make the proper modification due to the security restrictions we have in our environment. In addition, if I’m working on an application through a web host, it would be nice to change the configuration without having to FTP into the server.

Thanks to the LINQ to XML features announced in the .Net 3.5, being able to change the configuration on the fly became really easy. To note, I’m sure there were ways of dynamically updating the configuration pre-3.5, but parsing XML documents and searching/updating them can be tricky and time intensive at times. Not so anymore.

Without going into too much detail, the solution comes through using the XDocument object and the . For instance, if I wanted to get the logging level being used, and I know the proper XML path to the node, I can use the following code:

ContentDoc = XDocument.Parse(File.ReadAllText(LogPath));
Results = ContentDoc.Descendants("log4net").Descendants("root").
             Descendants("level").Attributes().First().Value;

Similarly, each the entire document can be exposed as an enumerable XElement object, so you can iterate through a collection of appenders, looking through the proper filename value through the following code:

XDocument ContentDoc;
IEnumerable<XElement> DocPoints;

ContentDoc = XDocument.Parse(File.ReadAllText(LogPath));
DocPoints = ContentDoc.Descendants("log4net").Descendants("appender");
foreach (XElement Item in DocPoints)
{
   if (Item.Attribute("name").Value == "XmlSchemaFileAppender")
   {
      Results = Item.Ancestors().Descendants("file").Attributes().First().Value;
   }
}

From here you can see that accessing and modifying values becomes quick and easy to do. The XDocument object also allows you to easily add new nodes to an existing document. You could easily add an ASP.Net appender, or any other appender to the system on the fly, or enable/disable appenders on the fly as well.

But for today, we’re going to keep things simple and only worry about updating the logging level. This way you can easily make your application dump out diagnostic data in the production environment and then revert back to its simple error logging after you have the necessary data.

Most of the code is given to you above. The final step in the process is to update the log level value and then write it back out to an XML file. The XDocument object provides for this as well:

ContentDoc = XDocument.Parse(File.ReadAllText(LogPath));
ContentDoc.Descendants("log4net").Descendants("root").
                 Descendants("level").Attributes().First().Value = "DEBUG";
ContentDoc.Save(LogPath);

It really is that simple. The trickiest part of the whole process is learning how to navigate through the XML document with the proper use of the Descendants(), Ascendants(), and Elements() structure used within the object.

In an effort to share the love, I’ve written a really simple ASP.Net application that will show demonstrate all of this, and give you the complete code blocks to make this happen for you. There are two items to note when setting up your own configuration:

  1. The configuration file needs to be in a separate [Assembly].dll.log4net file. Modifying the web.config file on the fly will cause the application to restart its worker process, and eliminate the goals in mind. See my Quick-Start Guide if you need details on setting it up.
  2. You will need to make sure your ASP.Net application has proper write privileges to your configuration file, otherwise the process will file when it attempts to write to the file.
  3. The log entries generated are using the built in lo4net XML format, so you’ll either need to read the XML or maybe take a peek at an old and ugly (but still usable) log4net viewer app I wrote 8^D.

The apps have been tested and compiled to use the Visual Studio Development Server, so you should be able to unzip, fire up the solution, and run the project.

If you run into some additional clever uses with XDocument and log4net configuration, by all means share them here. Hopefully I can get a really robust configuration tool developed to extend things even further.

Enjoy!

DynamicLog4NetVB_2008 (240 KB)
DynamicLog4NetCS_2008 (211 KB)
DynamicLog4NetVB_2010 (389KB)
DynamicLog4NetCS_2010 (350 KB)

How to Sort/Find Custom Objects in a List with VB.Net

Oddly enough there is nothing really new here. However, most of the documentation I’ve been sifting through has all been C# related. Since I had to code this up using vb.net at work, I thought it would be helpful to have a reference available for others out there in vb.net land.

Lately I’ve really fallen in love with the power that generics, List(Of T) and the like, provide for my day to day operations. [Yes, I know this came out in .Net 2.0 but things run a little slow over here...] What I especially like to do is create my own custom objects and maintain them in a List collection for easy iteration and retrieval. Recently I created user information object that I use for somebody logged in as part of the data model. I created a List(Of UserInfo) and could add/remove/list these users without hassle. However, I also needed to sort this list from time to time. In addition, I would need to find an individual user to display particular data about them on a page. Doing this took a small amount more work, but is quick and easy once you know what to do.

UserInfo Object

For starters, here is the object I’ve created to store user information (property/method information has been removed for brevity):

Public Class UserInfo

      ' Private Members
      Private m_UserId As String
      Private m_FirstName As String
      Private m_LastName As String
      Private m_SecurityLevel As Integer
      Private m_Roles As List(Of String)

      ' Public Properties

      Public Property UserId() As String
         Get
            Return m_UserId
         End Get
         Set(ByVal value As String)
            value = m_UserId
         End Set
      End Property

      Public Property FirstName() As String
         Get
            Return m_FirstName
         End Get
         Set(ByVal value As String)
            m_FirstName = value
         End Set
      End Property

      Public Property LastName() As String
         Get
            Return m_LastName
         End Get
         Set(ByVal value As String)
            m_LastName = value
         End Set
      End Property

      Public Property SecurityLevel() As Integer
         Get
            Return m_SecurityLevel
         End Get
         Set(ByVal value As Integer)
            m_SecurityLevel = value
         End Set
      End Property

      Public Property Roles() As List(Of String)
         Get
            Return m_Roles
         End Get
         Set(ByVal value As List(Of String))
            m_Roles = value
         End Set
      End Property

      ' Constructors

      Public Sub New()

         m_Roles = New List(Of String)

      End Sub

      Public Sub New(ByVal UserId As String, ByVal SecurityLevel As Integer)

         m_UserId = UserId
         m_SecurityLevel = SecurityLevel

      End Sub

      Public Sub New(ByVal UserId As String, ByVal Roles As List(Of String))

         m_UserId = UserId
         m_Roles = Roles

      End Sub

      Public Sub New(ByVal UserId As String, ByVal FirstName As String, _
                     ByVal LastName As String, ByVal SecurityLevel As Integer, _
                     ByVal Roles As List(Of String))

         m_UserId = UserId
         m_FirstName = FirstName
         m_LastName = LastName
         m_SecurityLevel = SecurityLevel
         m_Roles = Roles

      End Sub

      ' Public methods

      Public Sub AddUserRole(ByVal RoleName As String)

         If Not m_Roles.Contains(RoleName) Then

            m_Roles.Add(RoleName)

         End If

      End Sub

      Public Sub RemoveUserRole(ByVal RoleName As String)

         If m_Roles.Contains(RoleName) Then

            m_Roles.Remove(RoleName)

         End If

      End Sub

   End Class

All of this is pretty straightforward. You can easily work with a UserInfo object to modify details and add it into a List collection without a problem.

But what happens if you need to find a given user within the list, or sort the list after adding several users to it? In the past you’ve had to essentially write your own collection type object, but thanks to existing interfaces and generics, we simply have to implement two features to make this possible.

IComparer(Of T)

The IComparer interface provides an interface for comparing one object to another. With the advent of generics, we can take the comparer one step further and specify the type of item we are comparing to, which eliminates the need to additional type casting within the method itself.

With out existing UserInfo object, simply add the following line to the class declaration:

Public Class UserInfo
      Implements IComparer(Of UserInfo)

Then within our method, we need to implement the proper Comparer signature that the interface is looking for:

Public Function Compare(ByVal x As UserInfo, ByVal y As UserInfo) _
       As Integer _
       Implements System.Collections.Generic.IComparer(Of UserInfo).Compare

   Return String.Compare(x.UserId, y.UserId)

End Function

In our case, we are going to use the UserId as the item to sort with since we know the usernames are going o be unique. The String.Compare() method returns the proper integer comparison (-1 for less than, 0 for equal, 1 for greater than) that the compare method uses when sorting a collection. You can easily wire this method up however you’d like based on what you want to compare. You can even write up multiple comparison type operators, and then feed a given comparison into the sort method of a collection to sort according to your needs.

Predicate Methods

In order to find a given user within the collection, we leverage a feature called the Predicate to make this happen. Again, in the old way of doing things you’d have to iterate through your custom object and manually look for the item you wanted. While the predicates are essentially doing the same thing, you can define them in ways that will allow you to return more than a single item. So you can do things like find all items in the collection where the last name is like “son” or something to that effect. I’m no expert on predicates, I’m just learning to use them myself, but there is a nice MSDN article on them here.

In our case, we want two simple predicates. One to find a given UserInfo object, and one to find a given UserInfo object based on the user Id (since that is our “primary key”) without having to create the entire object. Defining these methods looks like this:

Public Shared Function FindPredicate(ByVal User As UserInfo) _
       As Predicate(Of UserInfo)

   Return Function(User2 As UserInfo) User.UserId = User2.UserId

End Function

Public Shared Function FindPredicateByUserId(ByVal User As String) _
       As Predicate(Of UserInfo)

   Return Function(User2 As UserInfo) User = User2.UserId

End Function

That’s all there is to it. When you’re ready to use this object with a collection, you can do simple stuff like this:

Dim UserList As New List(Of UserInfo)
   Dim LoadUser As UserInfo
   Dim LostUser As UserInfo
   Dim FoundUser AS UserInfo

   LoadUser = New UserInfo("Sammy", 25)
   UserList.Add(LoadUser)
   LoadUser = New UserInfo("Hobart", 50)
   UserList.Add(LoadUser)
   LoadUser = New UserInfo("Fester", 10)
   UserList.Add(LoadUser)
   LoadUser = New UserInfo("Kozaky", 25)
   UserList.Add(LoadUser)

   UserList.Sort()

   LostUser = New UserInfo("Hobart", 50)
   FoundUser = UserList.Find(LostUser)

   FoundUser = UserList.Find(UserInfo.FindPredicateByUserId _
                            (User.Identity.Name))

There you have it! Simple and plain and effective. I’m working on redoing the class so you can see it looks like when the interface and predicate functions are added. Stay tuned.