Google
 

Wednesday, May 30, 2007

10 Tips for Great .NET Programming

REF: http://www.ftponline.com/wss/2001_12/magazine/columns/desposito/default.aspx

  1. Tip 1: Shape Up Your DataGrid’s Footer
    The DataGrid control might feature a footer—that is, a row that summarizes part of the content shown in the page. The footer is hidden unless you enable it by setting the ShowFooter property to True. Once you do, the footer appears, but it has exactly the same number of columns as other rows. If this is fine with you, it isn’t a problem. Otherwise, you’ll need to add more fields to the footer or remove existing ones.

    OnItemCreated is the key event to hook up. It’s the event handler’s signature:

    void ItemCreated(Object s,
    DataGridItemEventArgs e)

    This code lets you control the creation process for the footer and any other DataGrid item:

    ListItemType itemType = e.Item.ItemType;
    if (itemType == ListItemType.Footer)
    {
    e.Item.Cells.RemoveAt(1);
    e.Item.Cells.RemoveAt(1);
    cellSummary.ColumnSpan = 3;
    e.Item.Cells[0].Text = "...";
    }

    Make sure you intervene when the footer is being created, then grab the control instance representing the footer row. Then you can remove or add as many cells as you need. Don’t forget to set the ColumnSpan property to the original number of columns to avoid rendering problems such as having the footer line look shorter or longer than the rest of the grid.

  2. Tip 2: Use the Cache Object

    Both the Cache and Application objects are collection data containers that make content visible across page and session boundaries. Both don’t fully support Web farm and Web garden scenarios. A Web farm is a Web server architecture in which multiple servers host an application. In a Web garden scenario, multiple processes on the same server host an application.

    Unlike the Application object, the Cache object isn’t instantiated as soon as the first page of the application is loaded. The Cache object gets into the game only when you use it. In addition, the Cache object has features to minimize the amount of memory its data items occupy. You can set a relative or absolute expiration date for cached items as well as associate them with a priority and a decay factor. Then you have greater control over the status of your global data and can implement a special policy to degrade gracefully under low memory conditions. Additionally, the Cache object manages thread-safe objects and doesn’t require Lock and Unlock.

  3. Tip 3: Call a Service With GET or POST
    A Web Service is primarily a URL that you connect to using HTTP. When you create a proxy class for a given Web Service, unless you specify otherwise, the command-line tool wsdl.exe serves you a class that uses the SOAP protocol to make remote calls to the Web Service.

    Although the SOAP protocol is the expected standard for remote procedure calls, nothing prevents you from making calls to a .NET Web Service using plain GET or POST requests. Incidentally, POST commands transport SOAP payloads.

    You can build this feature into the proxy class directly by setting the /protocol switch to httpget or httppost when calling the wsdl.exe utility. The source code for the wrapper class behaves accordingly. You can also call a Web Service using the XmlHttpRequest object (see Resources) and either plain script or compiled code:

    Set http =CreateObject("Microsoft.XMLHTTP")
    http.open "GET",_
    "http://server/service.asmx/MethodName",false
    http.send ""
    MsgBox http.responseText

    By using XmlHttpRequest, you have the chance to connect to Web Services from Win32, script, and, in general, non-. NET code.

  4. Tip 4: Use Cookieless Sessions
    In ASP.NET, the Session object refers to a configurable software entity you can map to an in-process or out-of-process module. The Session object reads a number of runtime settings you can store in the Web server’s framework installation tree or in the application’s BIN directory from the web.config file. This file determines the settings for a number of ASP.NET components. If you put a copy of config.web in your application’s local subtree, the settings end up overriding the default ones set in the framework path.

    One thing you can customize is whether the Session Manager should identify client sessions using cookies (the default) or not. This line in the application local config.web file sets the Session Manager to work without cookies:

  5. Tip 5: Use Custom Grid Pagination
    The Web Form DataGrid control has built-in support for pagination. It displays a pager bar automatically and, with limited help from your code, it shows pages of records of the given size. However, by default, all the necessary records are cached in the DataGrid object’s DataSource property. This means you must fetch the data all at once. Although this isn’t such a big issue with a few dozen records, it becomes a problem with thousands of records. In this case, you might want to fetch records manually and cache them on disk, but off the DBMS.

    You must inform the DataGrid control of this particular behavior. Fortunately, the DataGrid provides for an AllowCustomPagination property that, when set to True, changes the internal behavior of the control quite a bit. When you set this property to True, the grid always reads records found in the DataSource property from first to last. It’s your responsibility to replenish this container with fresh data belonging to the current page. Normally, the grid itself fetches only the records that pertain to the page from the DataSource property.

  6. Tip 6: Load Key Info From Database
    The DataTable object lets you set in-memory primary keys on a given table. This action speeds up the search on both the DataTable and related DataView objects. Another good reason to have in-memory keys is to automatically prevent duplicate insertions that violate table integrity. Then you have plenty of time to fix the table, even properly warn the user, before the data is actually submitted to the database server for a batch update.

    You can set this information manually in your fetching code:

    //ds is an existing dataset
    DataColumn[] keys == new DataColumn[1];
    DataTable dt = ds.Tables["MyTable"];
    keys[0] == dt.Columns["ID"];
    dt.PrimaryKey = keys;

    You can have the primary key information detected and set automatically while filling the data set. You automate the discovery of this information, and consequently the execution of your fetching code, by setting the MissingSchemaAction property of the data adapter that performs the query:

    SqlDataAdapter da = new SqlDataAdapter(strCmd,strConn);
    DataSet ds = new DataSet();
    da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
    da.Fill(ds,"MyTable");

  7. Tip 7: Request Selected Checkboxes
    In any ASP application, you have several checkboxes, all with the same name:

    You can get the corresponding values of the checkboxes that have been selected upon form posting with a single line of code:

    <%a =split(Request.Form("foo"),",") %>

    Request.Form("foo") returns a comma-separated string formed by the value strings of all checked items. You pass this string to the VBScript’s split function and get an easily manageable structure, such as an array.

    The same code won’t work in ASP.NET if you use the server control. To make it work, stick with the HtmlInputCheckBox control and write code such as this:


    Even though the asp:checkbox and input type="checkbox" server tags evaluate to the same HTML code, ASP.NET ensures unique IDs and names for the tags output by asp:checkbox and any other control in the namespace.

  8. Tip 8: Automate Master/Detail Views
    If you have a Windows Forms application that uses the DataGrid control to display master/detail tables, chances are you can have the framework synchronize the views automatically for you.

    The key is creating a data relation between the two tables and using a composed expression to define the data source for the detail table. Let’s assume you have Customers and Orders tables with a CustID field in common. You create a relation in terms of an ADO.NET DataRelation object:

    //ds is an existing DataSet
    Dim dc1,dc2 As DataColumn
    dc1 =ds.Tables("Customers").Columns("custid")
    dc2 =ds.Tables("Orders").Columns("custid")
    Dim r As DataRelation
    r =New
    DataRelation("OrdersByCustomer",dc1,dc2)
    ds.Relations.Add(r)

    Whenever you have a DataRow object representing one row on the master table—Customers, in this case—you can obtain an array with the child rows according to the relation using the DataRow’s GetChildRows method. For Windows Forms, this programmatic approach is buried in this code:

    dGrid.DataSource =ds
    dGrid.DataMember =
    "Customers.OrdersByCustomer"

    When you associate the detail grid with an expression such as MasterTable.Relation, its content is refreshed automatically and properly.

  9. Tip 9: Handle File Change Notification
    .NET integrates the functionality of Win32 file notification objects into the FileSystemWatcher class. Those kernel objects are responsible for notifying client applications about changes detected at the file system level. According to the specified parameters, a notification object signals the status of the applications whenever a file is created, modified, renamed, or deleted.

    It’s difficult for Win32 to know the name of the file being involved and the reason for its involvement with the event under Windows NT and Windows 2000. All this has been superseded in .NET thanks to the FileSystemWatcher class:

    FileSystemWatcher watcher = new
    FileSystemWatcher();
    watcher.Path ="c:\\";
    watcher.Filter ="*.txt";
    watcher.NotifyFilter =
    NotifyFilters.LastWrite;

    Once the object is configured, you begin watching:

    watcher.EnableRaisingEvents =true;

    Any detected event causes an application event to fire. You register for the events you need like this:

    watcher.Changed += new FileSystemEventHandler(OnChanged);

    The handler’s event arguments supply all the file and event information you need.

  10. Tip 10: Compile Code on the Fly
    The .NET Framework exposes classes that let you compile code in a specified language. These classes live in the System.CodeDom.Compiler namespace. This code snippet shows how to obtain an in-memory running instance of the C# compiler:
    CSharpCodeProvider csc = new
    CSharpCodeProvider();
    ICodeCompiler icc =
    csc.CreateCompiler();

    Next, you’ll set some input parameters through the CompilerParameters class:

    CompilerParameters co = new
    CompilerParameters();
    co.OutputAssembly ="foo.exe";
    co.ReferencedAssemblies.Add("system.dll");

    You must specify at least the name of the executable, set GenerateExecutable to False if you want a DLL, and add the list of assemblies to reference:

    icc.CompileAssemblyFromFile(co,
    csfile);

    To run the compiling process, use CompileAssemblyFromFile() and pass it the parameters and the source file name. You can use the class CompilerResults to learn more about the newly generated assembly.

No comments: