• TortoiseSVN and issue tracking integration

    Would you like to associate each of your subversion check-ins with a particular issue, bug or change request? TortoiseSVN provides an easy way to link revisions to issues in any bug tracking system.

     

    To accomplish this, TortoiseSVN needs to know some information about your bug tracking system. Since TortoiseSVN resides on the client, this information needs to be stored somewhere locally. This is accomplished by adding properties to your SVN controlled folders. Once these properties are added, Tortoise knows to expose an additional textbox to allow you to enter the associated issue identifiers. With this information, Tortoise will add a well defined line to your comment that is both human readable, and that it can easily parse. (Full technical details available here.)

     

    You can add these properties, by right clicking the root folder for your project and selecting TortoiseSVN->Properties. As you add each property, be sure to check the “Apply Property Recursively” checkbox.



    Here is a screen shot of the properties and example of their typical values:



    bugtraq:label is the label that appears next to the textbox for entering issue identifiers. This label also appears as a header for a new column when viewing the log. Note: you can specify multiple identifiers separated by a comma.



    bugtraq:warnifnoissue can be set to true to warn a user that they have not entered anything in the textbox.




    bugtraq:number can be set to do validation on the new textbox. Setting to true will only allow the entry of numeric values. (Note that the checkin shown in the screen shot above would not be permitted with this value set to true. This will be dependent on your bug tracking system.)

     

    bugtraq:message is the format of the message that is appended to your comments. This example uses “Issue ID: %BUGID%”. %BUGID% will be replaced with the actual value you enter in the text box.





    bugtraq:url is the url of your bug tracking system.

    You might have noticed that the issue number in the comment is a hyperlink; this is where that link is specified. Again, you can use the value %BUGID% , which will be replaced by the value you entered. As an example, I have used: http://MyBugTrackingURL/Default.aspx?BugID = %BUGID%.

     

    If you correctly set all of the necessary properties recursively, then every folder in your project should be marked as modified. Check in the entire project, and the next time your team does a check out, they will have the ability to associate issues with check-ins.


    Full story

    Comments (0)

  • Handling Session Timeouts
    With new technology making the web a viable option for more and more applications, we are now seeing the web browser take over for the traditional desktop. Developers making this transition, quickly learn about some of the key differences between the two paradigms.  One of the issues they are often forced to deal with is Session expiration.  Out of the box, ASP.NET and IIS typically allow only 20 minutes of idle time before the session expires. This can be configured, but knowing that the session expired, or redirecting to a particular page often comes in handy.  One way to do this is to add a cookie during the Session_Start method of the global.ascx.cs file, and then check for that same cookie the next time a session is created.  If the cookie is there, the session either timed out, or was reset.

    Here is an example:

    protected void Session_Start(Object sender, EventArgs e)
    {
    //Check if there is a cookie from when the session started.
    //If not, the session has not been started yet,
    //so add the cookie.
    HttpContext context = HttpContext.Current;
    HttpCookieCollection cookies = context.Request.Cookies;
    HttpCookie SessionCookie = cookies["SessionStarted"];
    if (SessionCookie == null)
    {
    HttpCookie cookie = new HttpCookie("SessionStarted", DateTime.Now.ToString());
    cookie.Path = "/";
    context.Response.Cookies.Add(cookie);
    }
    else
    {
    //If there was a cookie, but we are in this method starting a session
    //Then the session must have expired or been reset.

    //TODO: Do something useful with this info, log it, etc.
    //update the cookie with the new session start time
    cookies.Remove("SessionStarted");
    SessionCookie.Value = DateTime.Now.ToString();
    context.Response.Cookies.Add(
    SessionCookie);

    //Redirect to the whatever page you want to handle this situation. //An error page, login page, etc. context.Response.Redirect("~/Login.aspx", true);
    }
    }

         

    Full story

    Comments (0)

  • Working for Falafel is Hard...Part 2

    I got up at 5 in the morning and jumped on a plane to meet the rest of the Falafels at headquarters. It was a long day. The airline had lost my luggage and I had been up for 8 hours before even getting to the office. We worked all day and headed out for dinner after that. I was exhausted. That all changed when I realized how I was going to get back to my hotel. I was going to take the company car:

    Full story

    Comments (0)

  • Dynamically add rows to a GridView

    Ever need to show something in a databound gridview that isn't in your datasource? Don't worry, relax, forget about that datasource. Just create that extra row dynamically.

    Lets assume I have a GridView with 2 columns. The first column shows the items on an order,  the second column shows the price of that item and the footer shows the order total.  How would I inject a row that shows the tax?

    Something like this in the RowDataBound EventHandler would do the trick:

    decimal orderTotal = 0.0m;
    decimal tax = 0.0m;
    protected void gvOrderDetail_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        //TODO: Calculate the orderTotal and the tax when RowType = DataRow
        if (e.Row.RowType == DataControlRowType.Footer)
        {
            //Create the Row
            GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal);
            //Add the two Columns
            row.Cells.AddRange(CreateCells());
            //get a reference to the table that holds this row
            Table tbl = (e.Row.Parent as Table);
            //Add the row at the end of the list, but before the footer.
            tbl.Rows.AddAt(gvOrderDetail.Rows.Count + 1, row);

            //Don't forget to account for any changes in the footer. Since we added a row to show the tax,
            //that tax must also be accounted for in our footer. Calculating the orderTotal and the tax
            //is an exercise for the reader.
            Label lbl;
            lbl = (Label)e.Row.FindControl("lblTotal");
            lbl.Text = String.Format("{0:C}", (orderTotal + tax));
        }
    }

    private TableCell[] CreateCells()
    {

        TableCell[] cells = new TableCell[2];
        TableCell cell;
        Label lbl;

        //The order item column
        cell = new TableCell();
        lbl = new Label();
        lbl.Text = "Sales Tax";
        cell.Controls.Add(lbl);
        cells[0] = cell;

        //The price column
        cell = new TableCell();
        lbl = new Label();
        lbl.Font.Bold = true;
        lbl.Text = tax.ToString("C");
        cell.HorizontalAlign = HorizontalAlign.Right;
        cell.Controls.Add(lbl);
        cells[1] = cell;

        return cells;
    }

    Full story

    Comments (1)

  • So you want to build a framework?

    Many companies are moving away from constantly building applications from scratch, and instead focusing their development on  building a reusable and testable framework to encapsulate their business rules.  Their frameworks are then used to quickly produce custom apps, webservices, components, etc. It is sort of like building a house. First they build a solid foundation, and then build on top of that foundation whatever structure they may need. If you are part of a team about to head down this path, I would strongly recommend a few of my favorite resources, to make sure you get the foundation right the first time.

    Early in 2005, Brad Abrams had a 15 part webcast on "Designing .NET Class Libraries". Its now archived on MSDN, but I dug up the link so you don't have to: https://msdn.microsoft.com/netframework/programming/classlibraries/

    Soon after the series was complete, he and Krzysztof Cwalina released a book called "Framework Design Guidelines". The book sums up what you might see in the webcast, and if you decide to take a stab at building your own framework, I would consider it required to have on hand.

    Full story

    Comments (0)

  • Date formatting a BoundField

    If you have a BoundField in a GridView that displays a datetime, but you only want to display the date, how would you go about doing that?

    Set the DataFormatString to "{0:d}" ?

    That is what I thought too. Turns out, this doesn't always work.
    That is because by default the value is extracted from the data store, HtmlEncoded, and then the format string is applied. After HtmlEncoding,  the format string won't do anything. The fix in most cases, is usually pretty simple. Just turn off HtmlEncoding for that field by setting HtmlEncode="false".
    If you can't turn off HtmlEncoding, it looks like there is some custom formating in your future.

    Full story

    Comments (0)

  • Effective caching in ASP.NET

    If you add an item using the indexer, like this:

    Cache["TestItem"] = value;

    The item is added to the cache with no expiration policy and a normal priority. As a result, the item will stick around indefinitely.
    We can help the cache decide which items to toss out of memory by specifying an expiration policy and/or a priority:

    Cache.Insert("TestItem", value, null, Cache.NoAbsoluteExpiration,
      TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null)

    Above, I gave the item a 20 minute sliding expiration. This means each time the item is accessed, its 20 minute lease on life is renewed.
    I could have told it to expire after exactly 20 mins, no matter how many times it is accessed by setting an absolute expiration instead:

    Cache.Insert("TestItem", value, null, DateTime.Now.AddMinutes(20),
      Cache.NoSlidingExpiration, CacheItemPriority.Normal, null)

    And to really take control of the scavenging mechanism, you can change the priority of items added to the cache. Lower priority, means it is removed first when system resources are running low. The values range from "Low" to "NotRemovable". See the CacheItemPriority type's documentation for all of the values.

    You will also notice that the Cache has an "Add" method. If you choose to use the Add method, adding a key that already exists in the cache will result in an exception, while doing the same with the Insert method will overwrite it. Setting a value using the indexer is equivalent to this call:

    Cache.Insert("TestItem", value, null, Cache.NoAbsoluteExpiration,
      Cache.NoSlidingExpiration, CacheItemPriority.Normal, null)

    Full story

    Comments (0)

  • Web Resources in ASP.NET 2.0

    There is a cool new feature in ASP.NET 2.0 that allows you to embed resources into your server side assemblies and have your web controls request these resources automatically. This is especially handy when you want to deploy a new control. No longer do you have to find just the right spot to place the JavaScript and image files that your control depends on. 

    Microsoft already uses this technique with its validators. The JavaScript needed for client side validation is embedded in one of the .NET assemblies on the server. If you were to view the source of any web page that uses a validator in ASP.NET 2.0, you might see something like this:

    <script src="/MyWebSite/WebResource.axd?d=68d8KT0ikvX6J4c8Z8zwvfZXzPdyyYYY8TuccizWlCePFWz&t=632847500868593750" type="text/javascript"></script>

    This is a request to a new HttpHandler, WebResources.axd, for the necessary JavaScript. The first parameter, ‘d’ is an encrypted identifier telling the handler which resource it needs. The ‘t’ parameter is an encrypted timestamp, used to determine if the resource has changed.

    Looks pretty simple right?

    Well, lets see how easy it is for you to use this technique. Lets try to create a control that has its JavaScript embedded as a resource. For this example, I am going to use a useful script that buffers key presses and matches an entire word in a dropdownlist instead of just the first character. (Thanks to Jonathan Cogley at ASP Alliance for the original script: http://authors.aspalliance.com/thycotic/articles/view.aspx?id=3)

    First, lets open up or create a new web site in Visual Studio 2005 and then add a new Web Control Library project to it. After adding the project, remember to add a reference to it from our web site.  This new assembly will contain all of the elements of our control and our web site has to know about it to use it.

    Next, lets add a new class that inherits from DropDownList:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Web.UI.WebControls;
    using System.Web.UI;


     

    namespace WebControlLibrary1
    {
        public class KeyedDropDownList : DropDownList
    {
            private bool _caseSensitive = false;

            public KeyedDropDownList(){}

        
         public bool CaseSensitive
         {
         get
         {
         return _caseSensitive;
         }
         set
         {
         _caseSensitive = value;
         }
         }
        }
    }

    I have also added a property “CaseSensitive” which will be passed to the script to allow us to turn on and off case sensitivity when matching strings in our list.

    Now add a new a JScript file and examine the properties. To embed this file as a resource the Build Action must be set to 'Embedded Resource'.  After setting the build action,  feel free to copy this code into the file or substitute JavaScript of your own:

    function KeyedDropDownList_onkeypress(dropdownlist,caseSensitive) 
    {
    // check the keypressBuffer attribute is defined on the dropdownlist
    var undefined;
    if (dropdownlist.keypressBuffer == undefined)
       {
    dropdownlist.keypressBuffer = '';
    }
       // get the key that was pressed
    var key = String.fromCharCode(window.event.keyCode);
    dropdownlist.keypressBuffer += key;
      if (!caseSensitive)
       {
    // convert buffer to lowercase
    dropdownlist.keypressBuffer = dropdownlist.keypressBuffer.toLowerCase();
    }
      // find if it is the start of any of the options
    var optionsLength = dropdownlist.options.length;
    for (var n=0; n < optionsLength; n++)
    {
    var optionText = dropdownlist.options[n].text;
    if (!caseSensitive)
         {
    optionText = optionText.toLowerCase();
      }
    if (optionText.indexOf(dropdownlist.keypressBuffer,0) == 0)
         {
    dropdownlist.selectedIndex = n;
    return false; // cancel the default behavior since
    // we have selected our own value
         }
    }
    // reset initial key to be inline with default behavior
    dropdownlist.keypressBuffer = key;
    return true; // give default behavior
    }

    Next,  you must add an attribute to the assemblyinfo.cs file to reference the embedded resource:

    [assembly: System.Web.UI.WebResource("WebControlLibrary1.JScript1.js", 
    "text/javascript")]

    You will notice that the reference to the JScript file is fully qualified. You must do this using the project's default namespace, not just any old namespace in the assembly. You can see this  by right clicking on the project and viewing the properties. I should also mention that we intentionally left out an optional boolean parameter named 'PerformSubstitution'. By default 'PerformSubstitution' is off, and you should turn it on if the referenced resource accesses other embedded resources. An embedded style sheet that defines some style using an embedded image is a good example of when to set PerformSubstitution to true.

    Now, instead of registering the script block with the necessary JavaScript ourselves, we will register a request to get the script block from our  assembly.  Thanks to the new ClientScriptManager in ASP.NET 2.0, this is  very easy.  We will first override the OnInit method of our KeyedDropDownList class and then  get a reference to this manager to do most of our work.

    protected override void OnInit(EventArgs e)    
    {
    base.OnInit(e);
    ClientScriptManager cs = Page.ClientScript;
    Type rsType = this.GetType();
    cs.RegisterClientScriptInclude("MyScript",
    cs.GetWebResourceUrl(rsType,"WebControlLibrary1.JScript1.js"));
    }

    The last piece of coding is very simple.  Just attach  the onkeypress event of our control to our custom JavaScript function.  Although in this example we have not used the ViewState to track our lone property,  we might want to do that or add more properties that can be passed to the JavaScript function.  So here I overrode the OnLoad method to add the attribute to our webcontrol. By the time the OnLoad event is fired, the ViewState will have been  loaded.

    protected override void OnLoad(EventArgs e)
    {
    base.OnLoad(e);
    this.Attributes.Add("onkeypress",
    "return KeyedDropDownList_onkeypress(this," +
    _caseSensitive.ToString().ToLower() + ")");
    }

    If all goes well, we should be able to now use this control on any form in our web app and the necessary JavaScript will automatically accompany it wherever it goes. I should also point out that when debugging, the JavaScript is not cached, it is downloaded each time. When debugging is off, the JavaScript is cached on the client automatically. 

    I have  included the markup for the test page that registers and uses this new control below.

    <%@ Page Language="VB" AutoEventWireup="false"
    CodeFile="Default.aspx.vb" Inherits="_Default" %>
    <%@ Register Assembly="WebControlLibrary1"
    Namespace="WebControlLibrary1" TagPrefix="wcl" %>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
    <title>Test Page</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <wcl:KeyedDropDownList id="ddlTest" runat="server">
    <asp:ListItem Value="1">Calendar</asp:ListItem>
    <asp:ListItem Value="2">Can</asp:ListItem>
    <asp:ListItem Value="3">Candle</asp:ListItem>
    <asp:ListItem Value="4">Canary</asp:ListItem>
    <asp:ListItem Value="5">Card</asp:ListItem>
    <asp:ListItem Value="6">Cat</asp:ListItem>
    <asp:ListItem Value="7">Cow</asp:ListItem>
    </wcl:KeyedDropDownList>
    </form>
    </body>
    </html>

    Full story

    Comments (0)

  • Add scrollbars to anything in ASP.NET

    When paging just won't cut it, scrollbars come in handy. Fortunately, it is quite easy to add scrolling support to just about anything. All you need to do is wrap any of your controls in an HTML DIV tag.

    The key to the code below is to set the DIV style to "OVERFLOW: auto;" and specify a size. When overflow is set to auto, scrollbars will automatically appear if  the control size exceeds the DIV's dimensions. The code below binds a datagird to the Order table in the Northwind database. This would normally produces a pretty large datagrid, but thanks to our DIV, we will only see a subsection of the data.

    <DIV style="OVERFLOW: auto; WIDTH: 550px; HEIGHT: 200px">
    <asp:datagrid id=DataGrid1 runat="server" DataSource="<%# dataView1 %>"
    AutoGenerateColumns="False" ShowHeader="False">
    <Columns>
    <asp:BoundColumn DataField="OrderID"></asp:BoundColumn>
    <asp:BoundColumn DataField="ShippedDate"></asp:BoundColumn>
    <asp:BoundColumn DataField="ShipName"></asp:BoundColumn>
    <asp:BoundColumn DataField="ShipCity"></asp:BoundColumn>
    </Columns>
    </asp:datagrid>
    </DIV>

    Full story

    Comments (0)

  • A search engine for code

    Krugle is a search engine for source code that is supposed to make life easier for us developers. You can sign up for the Beta on their website and try it out sometime next month.  http://www.krugle.com/

    Full story

    Comments (0)

  1. 1
  2. 2
  3. Next page