Category Archives: Web Development

Entity Framework and DateTime2

I’ve decided that anything that takes me more than a day to figure out is worth a blog post. It’s been awhile since I’ve posted anything development related, but I’ve just recently started kicking the tires on the Entity Framework. I started with a simple example, and started with a very simple relational database containing 2 tables.

I then moved over into Visual Studio, and used the Entity Framework toolset to reverse engineer the database. The generated model was extremely simple, so I was all set to create a simple form to add a record into my database. I started out with the form below:

The code behind contained the following in the page_load method on postback:

                    try
                    {

                        ScheduleRequest sr = new ScheduleRequest {Name = tbName.Text, Comments = tbComments.Text, ModifiedDate = DateTime.Now };
                        db.ScheduleRequests.Add(sr);
                        db.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        divMessage.Visible = true;
                        divMessage.Attributes.Add("class", "message-error");
                        divMessage.InnerText = "There was an error processing your request." + ex.ToString();
                    }

After submitting the form, I hurried into the database to see how much time the Entity Framework was going to save me. The record was there, however my code was failing. A quick breakpoint gave me access to the exception, and I was given the following error:

Store update, insert, or delete statement affected an unexpected number of rows (0).

I did my normal googling, and quickly found a resolution that suggested that someone else had modified the context, something about concurrency, and many other odds and ends. Since I was about 5 minutes into a very simple example, I assumed it was none of those, although I tried several different modifications. Again, I’m a little out of touch with development, so I assumed I was just rusty.

I finally decided to put it to rest for the evening, and picked it up again tonight. This time, I got a little smarter and ran a trace in SQL Profiler to see what was actually being sent to the database. At first glance, nothing seemed out of the ordinary

exec sp_executesql N'insert [dbo].[ScheduleRequest]([ModifiedDate], [Name], [Comments])
values (@0, @1, @2)
select [Id]
from [dbo].[ScheduleRequest]
where @@ROWCOUNT > 0 and [Id] = scope_identity() and [ModifiedDate] = @0',N'@0 datetime2(7),@1 nvarchar(50),@2 nvarchar(50)',@0='2013-05-23 20:42:00.8549512',@1=N'Testom',@2=N'g'

Running the query from management studio returned 0 results, which seemed consistent with the exception. I went through each parameter, tweaked a few things, and then finally narrowed it down to the ModifiedDate column that was causing the query to return 0 results, even though the record was actually being written to the database. A closer look revealed that the ModifiedDate that I was passing in was more precise than what was being stored in the database. Urgh

A little further research indicated that the Entity Framework handles all dates as datetime2 in SQL Server. A quick change of the datatype on the ModifiedDate column from datetime to datetime2, and I was all set!

Adding a textarea to a gridview

Today I had the need add a multi-line textbox field inside of an ASP .NET Gridview, and also have the ability to edit this field. This is usually pretty simple with your standard asp:BoundField control, but making the field allow for multiple lines of input was not as easy.

I ended up using an asp:TemplateField to achieve the look I was going for. I added an ItemTemplate as well as an edit template, where I added a textbox with the textmode set to MultiLine.

        
            
                
                
                    
                        
                    
                    
                        <%# Eval("longDescriptionField")%>
                    
                
            
        
        
            
                
                
            
        

The itemTemplate just contains the string that I want to display, and the editItemTemplate contains the text box that has the textbox set to multiLine mode. This creates a textarea for the string that needs to be displayed, and I can modify the height and width of the control.

In order for me to update this field, I need to add a parameter in the code behind that represents this text area. I added the OnRowUpdating event handler so that I can modify the data source just before it performs the update. In the code behind, I have something like this:

    protected void SetUpdateParameters(object sender, GridViewUpdateEventArgs e)
    {
        myDataSource.UpdateParameters.Add("longDescription", ((TextBox)myGrid.Rows[e.RowIndex].FindControl("longDescriptionTextBox")).Text);
    }

Obviously the last step in the process is to write my update statement to update the information in the database, using my newly created parameter.

HTTP Error 401.3 – Unauthorized

Tonight I received the following error while trying to implement the Super Fish jquery menu plugin:


HTTP Error 401.3 – Unauthorized
You do not have permission to view this directory or page because of the access control list (ACL) configuration or encryption settings for this resource on the Web server.

At first it threw me for a loop, because my website could access all other files just fine. The only files that were being blocked, were the .js files that I was trying to use. The other .css files were coming through fine, and they had the same permissions setup as the .js files.

It turns the that the files were “blocked” by Windows because they “came from another computer”…

After unblocking the file, I was still getting the same error, and then I noticed that the file name font color was green, which seemed kind of odd. I opened up the advanced attributes on the file, and there was one more checkbox that I needed to clear. The file was encrypted, and therefore the web server could not read it. Clearing that box resolved the issue.

Creating dynamic meta tags using ASP .NET

SEO (search engine optimization) is all the rage these days. There are many great sites on the web that nobody’s ever seen or heard of. Part of the reason might be that the sites haven’t been optimized for search engines. I’ll do another post all about SEO some day, but for right now I want to highlight a couple of ways that you can enhance the pages on your site.

All good ASP .NET sites have a sitemap that organizes the site. If you don’t have a CMS (content management system), this is also a great place to store meta information about each page, such as the description and key words. These can be added as attributes on the sitemap, along with any other possible meta tags. I created a user control that I like to use that handles meta tags, and I just drop this into the master pages on the sites that I create. As long as I have a solid sitemap, the control takes care of the rest. I also like to take care of the page title for each page in this control, it’s handled in the code behind.

As you can see in the following sitemap file, I’ve used the description attribute, and also added my own keyWords attribute. Although key words aren’t as popular as they used to be for SEO, I like to go ahead and add them if I have a few handy. If you don’t list any key words, the control just ignores that attribute.




  
    
      
      
      
    
  

Here is the markup for the control, looks very straightforward, doesn’t it? Notice that the visibility on all the controls is initially set to false, because not all pages are going to have all of these attributes.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MetaTags.ascx.cs" Inherits="usercontrols_MetaTags" %>






Then in the code behind, I look at the attributes on the current sitemapnode and determine which tags to enable. This control is best used in conjunction with a master page, so that you only need to add this once, and any page using the master page will automatically be taken care of. Also notice that we use the title attribute on the sitemap to set the page title. I store a site name in the configuration that I prepend to each title. Not sure if that’s a best practice these days, just a preference of mine.

    protected void Page_Load(object sender, EventArgs e)
    {
        //First, check to see that we even need to handle this page, pages not in the sitemap will not have meta tags
        if (System.Web.SiteMap.CurrentNode != null)
        {
            this.Page.Title = ConfigurationManager.AppSettings["SiteName"] + " - " + System.Web.SiteMap.CurrentNode.Title;
            if (System.Web.SiteMap.CurrentNode.Description != null && !string.IsNullOrEmpty(System.Web.SiteMap.CurrentNode.Description))
            {
                metaDescription.Visible = true;
                metaDescription.Attributes.Add("content", System.Web.SiteMap.CurrentNode.Description);
            }

            if (System.Web.SiteMap.CurrentNode["keyWords"] != null && !string.IsNullOrEmpty(System.Web.SiteMap.CurrentNode["keyWords"]))
            {
                metaKeywords.Visible = true;
                metaKeywords.Attributes.Add("content", System.Web.SiteMap.CurrentNode["keyWords"]);
            }

            if (System.Web.SiteMap.CurrentNode["robots"] != null && !string.IsNullOrEmpty(System.Web.SiteMap.CurrentNode["robots"]))
            {
                metaRobots.Visible = true;
                metaRobots.Attributes.Add("content", System.Web.SiteMap.CurrentNode["robots"]);
            }

            if (System.Web.SiteMap.CurrentNode["author"] != null && !string.IsNullOrEmpty(System.Web.SiteMap.CurrentNode["author"]))
            {
                metaAuthor.Visible = true;
                metaAuthor.Attributes.Add("content", System.Web.SiteMap.CurrentNode["author"]);
            }

            if (System.Web.SiteMap.CurrentNode["copyright"] != null && !string.IsNullOrEmpty(System.Web.SiteMap.CurrentNode["copyright"]))
            {
                metaCopyright.Visible = true;
                metaCopyright.Attributes.Add("content", System.Web.SiteMap.CurrentNode["copyright"]);
            }
        }
        else
        {
            //At the very least, set a default page title
            this.Page.Title = ConfigurationManager.AppSettings["SiteName"];
        }
    }

Although I rarely use, or never use, a couple of those meta tags, I like to have them there just in case. The result of using this control in conjunction with the sitemap is something that looks like the following in the head section your rendered page source:


    
    

WordPress is suppressing the title tag, but just imagine the following in the code snippet above <title>My Site name – Home Page</title>

Building a dynamic navigation menu in ASP .NET

ASP .NET provides a few out of the box controls for navigation, but for most people, a custom navigation menu is the way to go. A common pattern that I use is creating a series of unordered lists to represent my navigation, and then I’ll use some kind of javascript to make it a little more flashy. Given the sitemap below, we’ll generate the markup needed to create a menu similar to what can be found here: Sample Menu



  
    
      
      
      
    
    
      
      
    
    
      
      
      
    
  

The markup that we’re after looks something like this:

  • Main Navigation 1
    • Sub Navigation 1
    • Sub Navigation 2
    • Sub Navigation 3
  • Main Navigation 2
    • Sub Navigation 4
    • Sub Navigation 5
  • Main Navigation 3
    • Sub Navigation 6
    • Sub Navigation 7
    • Sub Navigation 8

We can use a combination of the Sitemap objects and ASP .NET repeaters to get the desired result. If you haven’t already done so, first you must configure your site to use the sitemap. By default, your site will look for a file called Web.sitemap, or you can manually configure the sitemap in the Web.config file.

I like to put all of the code for generating the navigation inside of a user control. It always seems to make piecing together a page a little easier, and if I need to do multiple master pages, I can reuse the navigation code if needed. In order to get the markup in the right structure, I nest a repeater within another repeater:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="top-navigation.ascx.cs" Inherits="uc_top_navigation" %>

Notice that I added an OnItemDataBound handler to the main repeater. I do this so that during each iteration of the repeater, I can bind the nested repeater to the sitemap.

In the page load event of the user control, I need to bind my sitemap to the first repeater. Because of the way I’ve structured my sitemap, I want the nodes that are just below the root node. I set the source of my repeater to be these nodes, and then bind it. This gets me the top bar of my navigation, but no dropdowns just yet.

    protected void Page_Load(object sender, EventArgs e)
    {
        navBar.DataSource = System.Web.SiteMap.RootNode.ChildNodes;
        navBar.DataBind();
    }

Now that I have my top bar going across the top, it’s time to add the dropdown menus. Using the OnItemDataBound handler on the first repeater, we can get an instance of the current node that we’re working with, and use those child nodes to build out the markup for the menu. The code for this might look like this:


    protected void navBar_OnItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        SiteMapNode currentRepeaterNode = (SiteMapNode)e.Item.DataItem;
        ((Repeater)e.Item.FindControl("subNavDropdown")).DataSource = currentRepeaterNode.ChildNodes;
        ((Repeater)e.Item.FindControl("subNavDropdown")).DataBind();
    }

This gives us the markup that we need. Paired with a proper javascript file and css, this is a simple pattern to follow for creating a dynamic navigation menu.