Archive for the ‘.NET Development’ Category

 

Triggering a Specific GridView Row Command When Page Loads

I have an asp.net page with a gridview and each row uses a TemplateField to make a LinkButton to select the row. In my case, the action of clicking the text link triggers a FormView to appear in order to edit the data.

 

I needed a way to open the editing form automatically for the first item in the gridview when the page loads. After using combinations of different .NET page events (Page_Render(), Page_Unload(), etc.), I found myself going around and around because I was never at the right point in the execution order for getting the data bound , knowing the correct CommandArgument and having access to all the data in the row at the same time. I was setting session variables and checking IsPostBack and it was becoming more complicated than it seemed like it needed to be.

 

It was time to rethink the whole issue. I ended up writing 1 line of javascript with a little prep C# code which finds the correct LinkButton, transforms its .NET generated ID into something useful, and then stores it for the javascript to use. The javascript executes a postback after the page loads so it mimics a user clicking on the “Edit” link, just like I wanted.

 

The code for the edit link as a column in my gridview:

 

<asp:TemplateField ShowHeader=”False”>

<ItemTemplate>

<asp:LinkButton ID=”LinkButtonSelect” runat=”server” CausesValidation=”False”

                CommandName=”Select” Text=”EDIT”

    CommandArgument=’<%# Bind(”ID”)%>‘>

</asp:LinkButton>

</ItemTemplate>

</asp:TemplateField>

 

In my C# code I check if there are any rows in my grid before I attempt to postback on anything and I’m choosing row 0 because I want the first row. The parameter for __doPostBack needs to have dollar signs instead of underscores like the ID has, so I replace them accordingly.

 

At the bottom of my.aspx page I have this javascript code (which could also be added into the onload event):

 

<script type=”text/javascript”>

 

<%

    // Get and format the the ID of the Edit link in the first row

    if (GridView1.Rows.Count > 0)

    {

        LinkButton lnkEdit = (LinkButton)GridView1.Rows[0].FindControl(“LinkButtonSelect”);

        string strEditID = lnkEdit.ClientID.ToString().Replace(“_”,“$”);

%>

         // trigger a postback like someone clicked “Edit”

         __doPostBack(‘<%= strEditID %>’, );

 

<%

    }

%>

 

</script>

 

So in the end, the javascript line has the same value as the href attribute that is generated for the LinkButton. View the source code of your page and check it out!

Posted by Kevin under .NET Development, C# Tags: , , ,  •  No Comments

Display a Nested List Inside Another Repeater

A simple way to display a list of data is to use an asp:Repeater. If the data also needs to show a nested list of related data for each main item, one can place another Repeater inside the first. In the code behind, the queries used for each Repeater can be linked in a dataset as a parent-child relationship via a Data Relation.

In the example below we make the multiple queries in only one SQL command statement, then link the result tables together by making a new DataRelation. The link uses key and foreign key ID columns from each result set.

This C# example shows how you can have a list of phone numbers as an area inside a larger list of contacts.

             In the Page_Load function…
             …

        // Create and fill a DataSet
SqlDataAdapter myCommand = new SqlDataAdapter(

            "SELECT DISTINCT MemberID, Address, FirstName, LastName " +
            " FROM MemberNames M; " +

            "SELECT MemID, phonetype, Number " +
            " FROM MemberNames M " +
            " INNER JOIN Phone P ON M.MemberID = P.MemID;" +
             , myConnection);

         DataSet ds = new DataSet();
        myCommand.Fill(ds);

         // Relate the two tables from the query together
        ds.Relations.Add(new DataRelation("MemberID_Phone", ds.Tables[0].Columns["MemberID"], ds.Tables[1].Columns["MemID"]));

        // Bind the outer Repeater to the DataSet.
        rptMember.DataSource = ds.Tables[0];
        rptMember.DataBind();

 When we bind the data for each item in the outer Repeater, we will create a child view using the relation we linked previously.

     protected void rptMember_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        DataRowView drv = e.Item.DataItem as DataRowView;
         Repeater rptPhone = e.Item.FindControl("rptPhone") as Repeater;

        rptPhone.DataSource = drv.CreateChildView("MemberID_Phone");
        rptPhone.DataBind();
    }

 This snippet from the .aspx files shows the nested repeaters.

<asp:Repeater id="rptMember" OnItemDataBound="rptMember_ItemDataBound" runat="server">

         <ItemTemplate>

          <!– Tags to display the bound data (name, address, etc.) –>  

          <!– Make a repeater for all phone numbers for each person –>

            <asp:Repeater id="rptPhone" runat="server">
              <ItemTemplate>
                <%# DataBinder.Eval(Container.DataItem, "PhoneType")%>:
                <%# DataBinder.Eval(Container.DataItem, "Number")%>

              </ItemTemplate>
            </asp:Repeater>

            …

 To sum it all up, we implemented several technical elements here. 

  • Nested Repeaters
  • Using a multi-result query
  • Using DataSet Relations

 Our example displays a list of Contacts with a sub-list for multiple phone numbers.

Posted by Kevin under .NET Development, C#  •  No Comments

Article Series and Planned Topics

by Allan Sieker

When it comes time to write an interesting article about a technical topic my mind goes into a deadlock in trying to find the balance between space/time constraints and keeping the content interesting.  Too short of an article and it seems trivial because the technical stuff doesn’t get covered enough.  Too technical, and the article becomes long and boring.  All the while, wanting to keep things original, informative, and light.  So did I end up with?  How about a series of related articles that covers something that is near and dear to all of us?   

 I bought my first computer in 1978 (yes, I still have it) and as my home network expanded to what it is now – several servers, workstations, and laptops, the need for keeping a file inventory goes with the territory.  Sure, over the years I created my own file databases written in several languages (BASIC, Pascal, dBASE, Clipper, VB, C#) and they all served their purpose, but technology keeps improving and I always want more.   

 What if data warehousing concepts were applied to capture the “slowly changing dimension” of file updates?  What if file collections were recognized and managed as applications and other entities?  What if all of the computer file inventories were gathered locally then stored centrally for searches via a web interface?   What if backup history were also available?

 This article series will cover a broad range of technical topics with the end goal being a respectable system for home or business usage.  Concepts will be discussed and code will be available for download.  References to other articles and postings will also be made.

 Here is a brief list of planned topics: 

  • Using recursive methods to collect file information from all of the folders on a drive.
  • Creating console and Windows “file agent” applications to collect file data and write to an XML file.
  • Creating a SQL Server file inventory database.
  • Balancing cost and architecture to avoid over-costing and over-engineering.
  • Importing “file agent” XML into the database.
  • Creating an ASP.NET web application for searching and retrieving application & file information.
  • Making “file agent” applications downloadable from the web site using ClickOnce.
  • Using the Visual Studio Report Designer and the ReportViewer control to create web reports.
  • Creating a “wrapper” application for Microsoft’s Backup to manage and track backups.
  • Detecting media and image file duplicates based on file content instead of file name.

 Feedback is always welcome.

Using A Data Container Column as an Inline IF Condition

I find myself using .net data containers in many web applications.  Binding controls such as asp:Repeater and asp:DataList to data sources can make displaying your data more manageable.  In a few of those instances I need to have some of the data display in a little different manner depending on that particular info.

For example, a “sold” image could be shown if the status of a data item warrants it.  If the status is anything else no extra HTML is rendered.

<%# (DataBinder.Eval(Container.DataItem, "Status").ToString() == "Sold") ?
<img src='/images/sold.gif' />" : "" %>

Instead of making a server-side control in my .aspx page then having my code behind find it in some sort of databound function, I find it cleaner to use an inline C# IF statement for simple display changes such as these.

In the sample code below, we are making an anchor link. The data in the “Type” column from the database describes if the data is a URL or an email address.  Our inline IF statement has this structure:

If the Type equals “Website” then add nothing to the data.  Otherwise, the data is an email address, so make a “mailto:” link out if it.

<asp:Repeater id="rptAddress" runat="server">
<ItemTemplate>

<a href="<%# (DataBinder.Eval(Container.DataItem, "Type").ToString() == "Website") ?
 "" : "mailto:" %>   <%# DataBinder.Eval(Container.DataItem, "Address")%>" >
<%# DataBinder.Eval(Container.DataItem, "Address")%>
</a>
</ItemTemplate>
</asp:Repeater>
Just remember, the C# syntax for an inline If uses the question mark and a colon:
<% (condition) ? "true" : "false" %>

Posted by Kevin under .NET Development, C#  •  No Comments

Before You Start Increasing the CommandTimeout Value…

by Allan Sieker

Just recently I had the opportunity to investigate a timeout error happening on an ASP.NET web application of a new client.   This web application is a very intense and complex business solution involving tiered hierarchies of entities for companies, resources, processes, and projects.  Definitely not your typical web site.

The source of the timeout was an embedded SQL query consisting of a SQL view joined to another table.  A SqlDataAdapter was being used to fill a DataSet from a SQL Server database.   Very straight forward on the surface, but then I noticed that the a CommandTimeout setting of 60 was being used.  Why would such a simple query be taking more than 60 seconds to execute?

My first was to set a breakpoint just before the execution of the query so I could see what the actual parameter values were.   My second step was to copy/paste the query into an open query tab on SQL Server Management Studio and alter the query to use literal values from the first step.   To my surprise, the query did take a bit of time to execute.  Time to drill down.

I scripted out the SQL view and found that it consisted of a 13 table join where 3 of the joins were to views with joins of their own.  And one of the returning columns was a function having several querys of its own – and a 3 table join.  Time to get another Diet Mt. Dew…

I now understood why the previous developer slapped in a 60 second timeout.  Sure, I could have increased the timeout to 120 seconds and it would probably have solved the problem.  But would it be the professional way of solving the problem?  I thought not.  Besides, I didn’t want to put the client through a compile/rebuild/release cycle for just changing one line of code.  Another important thing to consider is that the users will have to endure this long query several times a day.  I couldn’t take that road.

This query and all of its branches was way too complicated to digest quickly, so I started breaking each branch down and checking to see if the queries were taking advantage of indexes. 

As it turned out, in about an hour I found four places where an index could be added and the yield of that effort took the 60+ second query down to 3 seconds.  The users were  ecstatic.

So the moral of my story is this:  Please do not blindly increase the timeout values without an honest attempt to tweak the query.    The time you take this one time will benefit your users every day.

Posted by Allan under .NET Development, SQL Server  •  No Comments

Process XML in C#.net

By George Zheng

XML has been used in a lot of places for transferring data because of its platform independence and its simple, text-based, self-describing format. It is a common requirement for preparing and consuming XML data. Microsoft provides several convenience tools to help developers deal with XML under .NET platform.

  1. System.Xml.XmlTextReader/System.Xml.XmlTextWriter
  2. System.Xml.Serialization.XMLSerializer
  3. System.Xml.Linq

XmlTextReader/XmlTextWriter
XmlDocument objects are easy to use for navigating the DOM copying, modifying, or inserting nodes. However, they can also use a large amount of memory to store the entire DOM of a large XML string in memory. Because of this, the XmlTextReader and XmlTextWriter classes can be used for stream based manipulation of an XML string.
Let’s say you have an XML as:
<?xml version=1.0 encoding=utf-8 ?>
<user id=1>
<firstname>George</firstname>
<lastname>Zheng</lastname>
</user>

Following code will read it into a user object.

User user = new User();
XmlTextReader reader = new XmlTextReader(“user.xml”);

while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == “user”)
{
user.Id = Convert.ToInt32(reader.GetAttribute(“id”));
}
if (reader.Name == “firstname”)
{
user.Firstname = reader.ReadElementContentAsString();
}
if (reader.Name == “lastname”)
{
user.Lastname = reader.ReadElementContentAsString();
}
}
}
With XmlTextWriter, following code will generate XML string:

StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlTextWriter writer = new XmlTextWriter(sw);

writer.WriteStartElement(“user”);
writer.WriteAttributeString(“id”, user.Id.ToString());
writer.WriteElementString(“firstname”, user.Firstname);
writer.WriteElementString(“lastname”, user.Lastname);
writer.WriteEndElement();

return sb.ToString();

XMLSerializer

If you don’t want to deal with the XML element by element, .NET provides an alternative approach to convert object instance to XML and read the data back – XML Serialization. This is more convenience for a complex object.

TextReader tr = new StringReader(xml);
XmlSerializer s = new XmlSerializer(typeof(User));
User user = (User)s.Deserialize(tr);

Following code can be used to serialize the object:

XmlSerializer s = new XmlSerializer(typeof(User));
TextWriter writer = new StringWriter();
s.Serialize(writer, user);
writer.Flush();
string xml = writer.ToString();
writer.Close();

The object can be a complex object like:

public class User
{
[XmlAttribute("id")]
public int Id { get; set; }

[XmlElement("firstname")]
public string Firstname { get; set; }
[XmlElement("lastname")]
public string Lastname { get; set; }

[XmlArray("projects")]
[XmlArrayItem("project", typeof(Project))]
public List<Project> Projects { get; set; }
}

public class Project
{
[XmlAttribute("id")]
public int Id { get; set; }
[XmlElement("name")]
public string Name { get; set; }
}

As you can see, serializer attributes can be used to specify how the object’s properties map to XML entities. I’m not going to discuss these attributes here. Details can be found from Useful Links below.

LINQ

In some case, convert the whole XML may not be a good idea. Linq provides a convenience approach to query a complex XML.

Here is the example account feed response from Google Analytics API

<?xml version=1.0 encoding=UTF-8?>
<feed xmlns=http://www.w3.org/2005/Atom xmlns:openSearch=http://a9.com/-/spec/opensearchrss/1.0/ xmlns:dxp=http://schemas.google.com/analytics/2009>
<id>http://www.google.com/analytics/feeds/accounts/abc@test.com</id>
<updated>2009-06-25T03:55:22.000-07:00</updated>
<title type=text>Profile list for abc@test.com</title>
<link rel=self type=application/atom+xml href=http://www.google.com/analytics/feeds/accounts/default/>
<author>
<name>Google Analytics</name>
</author>
<generator version=1.0>Google Analytics</generator>
<openSearch:totalResults>12</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>12</openSearch:itemsPerPage>
<entry>
<id>http://www.google.com/analytics/feeds/accounts/ga:1174</id>
<updated>2009-06-25T03:55:22.000-07:00</updated>
<title type=text>www.googlestore.com</title>
<link rel=alternate type=text/html href=http://www.google.com/analytics/>
<dxp:tableId>ga:1174</dxp:tableId>
<dxp:property name=ga:accountId value=30481/>
<dxp:property name=ga:accountName value=Google Store/>
<dxp:property name=ga:profileId value=1174/>
<dxp:property name=ga:webPropertyId value=UA-30481-1/>
<dxp:property name=ga:currency value=USD/>
<dxp:property name=ga:timezone value=America/Los_Angeles/>
</entry>
<entry>
<id>http://www.google.com/analytics/feeds/accounts/ga:6284812</id>
<updated>2009-01-06T17:39:33.000-08:00</updated>
<title type=text>www.googlestore.com (Test Team)</title>
<link rel=alternate type=text/html href=http://www.google.com/analytics/>
<dxp:tableId>ga:6284812</dxp:tableId>
<dxp:property name=ga:accountId value=30481/>
<dxp:property name=ga:accountName value=Google Store/>
<dxp:property name=ga:profileId value=6284812/>
<dxp:property name=ga:webPropertyId value=UA-30481-1/>
<dxp:property name=ga:currency value=USD/>
<dxp:property name=ga:timezone value=America/Los_Angeles/>
</entry>
</feed>

With following code, you will get ID, Title and AccountName for each entry.

XDocument doc = XDocument.Parse(xml);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix(“dxp”);
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();

IEnumerable<Account> entries =
from en in doc.Root.Descendants(defaultSpace + “entry”)
select new Account
{
ID = en.Element(defaultSpace + “id”).Value,
Title = en.Element(defaultSpace + “title”).Value,
AccountName =
en.Elements(dxpSpace + “property”).Where(
xe => xe.Attribute(“name”).Value == “ga:accountName”).First().
Attribute(“value”).Value
};

Useful Links

Insert XML Nodes Using XmlTextReader and XmlTextWriter
Using the XmlSerializer Attributes
Added Google Analytics Reader for .NET


download Download source code

Posted by George under .NET Development, C# Tags: ,  •  1 Comment

Coding Standards and SQL Mistakes

 By Allan Sieker

If you want to learn something from one of the best, please check out Clint Edmonson’s web site where you can download free coding standards for both VB and C#.  I worked with Clint at AB and I must say that he is one sharp guy.  I am sure he raised Microsoft’s collective talent a few notches when he joined them.  Be sure to look him up at the St. Louis “Day of .NET” Conference in August.

Shifting gears from .NET to SQL….

I ran across “Ten Common Database Design Mistakes” and found it to be most interesting.  I’m sure you will too.

Saving Web Contact Info to a Downloadable Spreadsheet

Usually a website owner has the data from their contact forms emailed to them.  But sometimes it can be useful for the site to automatically add that info to an ongoing list of contacts.  One way that most people like to be able to see and sort such data is in a spreadsheet.  It is quite easy to make a “fake” spreadsheet using an html table that Excel will open like any other .xls file.

 

Here are the basic steps:

  • Create and save a “spreadsheet” which defines the header row
  • Upon each contact form submittal, write an html row to that file 

Read the rest of this entry »

Posted by Kevin under .NET Development, C#  •  No Comments

Maintaining the Active Tab in TabContainer Control

by George Zheng

Problem

AJAX Control Toolkit has a neat control – TabContainer, to allow you create tabs on your web page easily. However, one problem with it is that when user refreshes the page, it defaults back to the first tab. This will cause user confusion if you have pagination in third tab let’s say. Every time, when user click a page number on third tab. Page get refreshed and it should show third tab, not the first tab.

Solution

The reason refreshed page always show the first tab is, in fact, one of the benefits of the tab control – switching between tabs doesn’t cause a post back. This is a pure client activity. When server prepares the page, it has no idea which tab is the active tab on client side. So server will set first tab as active tab by default.
Read the rest of this entry »

Posted by George under .NET Development, C# Tags: ,  •  4 Comments

Dispose – Dispose – Dispose – even if it doesn’t do anything

I am always astounded how often I inherit code from smart developers who know what they are doing, but still do not take the time to close and destroy objects. As much fuss is made about memory management and such, this is still an area of coding where laziness abounds.

.Net memory management and garbage collection is intended to free up our need to manage memory at a micro level, but at the same time it is criticized for not freeing up memory fast enough and then blamed for application issues and server slowness. For best practices, never rely on inherent memory management. Where you can, close and DISPOSE!
Read the rest of this entry »

Posted by Derek under .NET Development Tags:  •  No Comments