Wednesday, November 10, 2010

Request Variables for ASP.NET Paths, URLs and more

Rick Strahl has done a great job of outlining which Request variables (Request.RawURL, Request.PhysicalPath, etc) to use for different sections of your site's URL, request variables, web server folder structure and more.

Click the link below to access his blog post regarding the Request Properties:
http://www.west-wind.com/weblog/posts/132081.aspx

Tuesday, August 31, 2010

Is the Back Button needed on Web Browsers

A friend recently was ranting about the Back button on a browser and that it often messes up pages he visits. A counterpoint argued that a good developer is always prepared for users to hit the back button and always programs to handle the user trying to go back in time.

As a web developer, I definitely agree that the Back button is a great nuisance. It also creates a layer of uncertainty in where your user is/came from when they arrive at a page. Anytime a user needs to be able to get back to page they came from, there should be an easily accessible link/button, so is the Back Button really needed?

I could foresee a lot of malicious intent if browsers didn't have a Back button. Maybe the true problem is how overused or available it is.

Maybe one alternative would be to present the user with a new tab for every new site (domain) they navigate to and remove the Back button. Each website is now responsible for the navigation around it's own site, yet if you ever pull up something you didn't actually want, you can easily close the tab and you're back at the site that sent you there. It's really just your web history presented different, but it would take up a shit load of memory (depending on the sites you had pulled up). I'm sure other problems would come from such a strategy as well.

I can't really think of a method that would keep you in full control of web surfing yet remove the Back button entirely. Feels like it might be a necessary evil that developers just have to accept and work around.

Friday, August 27, 2010

Nested Gridview Within Another Gridview

I recently came across a project for which I had a need for a gridview within a gridview.
For this example, I will create a grids of documents and guides housed within a parent grid of resource categories.

Let's start with a basic gridview of 4 documents (2 training modules on gridviews and 2 user manuals for cell phones).

<asp:GridView
ID="gvDocuments"
DataSourceID="dataDocuments"
AutoGenerateColumns="false"
DataKeyNames="document_id"
CellPadding="8"
HeaderStyle-BackColor="#e0e0e0"
BorderColor="#e0e0e0"
runat="server">
<Columns>
<asp:HyperLinkField
HeaderText="Resource Link"
DataNavigateUrlFields="document_filename"
DataNavigateUrlFormatString="{0}"
Target="_blank"
DataTextField="document_name"
DataTextFormatString="{0}" />
<asp:BoundField
DataField="document_description"
HeaderText="Description" />
</Columns>
</asp:GridView>
<asp:SqlDataSource
ID="dataDocuments"
runat="server">
</asp:SqlDataSource>


Both could be considered training, but to better organize the page, I will split the documents up into groups, each document having a group column in the database named document_group.
On my backend, I have a new table to complement the Documents table called DocumentGroups that has a docGrp_name and docGrp_id field. The docGrp_id field will link to the document_group column I mentioned.

Now to drop my original gridview in a second gridview of "Document Groups"
This is where the code gets a little more bloated but still relatively simple:
<asp:GridView
ID="gvDocumentGroups"
DataSourceID="dataDocumentGroups"
DataKeyNames="docGrp_id"
AutoGenerateColumns="false"
GridLines="None"
runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<div style="padding-bottom: 12px;">
<div><%#Eval("docGrp_name")%></div>
<asp:GridView
ID="gvDocuments"
DataSourceID="dataDocuments"
AutoGenerateColumns="false"
DataKeyNames="document_id"
CellPadding="8"
HeaderStyle-BackColor="#e0e0e0"
BorderColor="#e0e0e0"
runat="server">
<Columns>
<asp:HyperLinkField
HeaderText="Resource Link"
DataNavigateUrlFields="document_filename"
DataNavigateUrlFormatString="{0}"
Target="_blank"
DataTextField="document_name"
DataTextFormatString="{0}" />
<asp:BoundField
DataField="document_description"
HeaderText="Description" />
</Columns>
</asp:GridView>
<asp:SqlDataSource
ID="dataDocuments"
runat="server">
</asp:SqlDataSource>
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource
ID="dataDocumentGroups"
runat="server">
</asp:SqlDataSource>


I added in some padding for better spacing, but you can play around with the CSS however you want.

Now. I didn't put connection strings or select commands in the original SqlDataSource because, if you don't know what you're doing there, this tutorial is not for you.
But now that we've embedded this gridview inside another one, that (inner layer) SqlDataSource is more than likely going to be fed a variable from your outer layer grid.
For my purposes, I'm going to use the docGrp_id, which I conveniently fed into the DataKeys of my outer layer SqlDataSource.
For more information on pulling the current row's datakey, click here.

For Each thisRow As GridViewRow In gvDocumentGroups.Rows
CType(thisRow.FindControl("dataDocuments"), SqlDataSource).SelectCommand = "SELECT * FROM [Documents] WHERE [document_group] = '" & gvDocumentGroups.DataKeys(thisRow.RowIndex).Value & "'"
Next




And there you have it!

Friday, August 20, 2010

Word Wrap a Label in Windows Form Applications

I recent was spinning out a quick Windows Form application to help an orders team look up product information and found myself questioning how to wrap text in a label rather than have it venturing off the application into nowheresville.

As a web developer, I always assume my text will find its place within the boundaries of a panel or table cell, whatever medium houses it. But the same should not be assumed for Windows Forms applications. Luckily, there is a simple solution.

Set the label's AutoSize property to Off.

The label becomes a resizable control that you can drag to whatever limits you want the text contained within.

Thursday, July 1, 2010

How Google Works

Ever wonder how Google really works? This is a fun little flow chart published by PPCBLOG that shows you how much goes on behind the plain white background and colorful graphic every second of every day and how fast the Google machine finds new websites, indexes them, rates them and presents them to users searching for a particular string on the internet.

How Google Indexs Searches Works?
Click Picture To Enlarge

Easy Way To Email Errors From Your ASP.Net Site To You

Errors on your site are never good, but it's best when you know about them the second they happen rather than a user telling you- or worse- not telling you.

This is a quick a dirty method I use for emailing myself details about errors when they occur on my sites.

If you don't already have one, add a Global Application Class (Global.asax) to your site. It should come with a sub procedure named Application_Error, but if it doesn't go ahead and create one. In the code I've provided below, I use a custom email class I use to templatize my emails, but you can easily adapt it to any email class you choose.

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when an unhandled error occurs

Dim mm As New MMEmail()
mm.ToRecipients.Add("")
mm.Subject = "[ERROR] " & Request.Url.AbsoluteUri.ToString

Dim ex As Exception = Server.GetLastError().GetBaseException()
Dim body As String = ""

'Get URL where error occured
body &= "[URL]"
body &= "<br/>"
body &= Request.Url.AbsoluteUri.ToString
body &= "<br/>"
body &= "<br/>"

'Brief message of what went wrong and line where error occured in code.
body &= "[MESSAGE]"
body &= "<br/>"
body &= ex.Message.Replace(vbCrLf, "<br/>")
body &= "<br/>"
body &= "<br/>"

body &= "[SOURCE]"
body &= "<br/>"
body &= ex.Source.Replace(vbCrLf, "<br/>")
body &= "<br/>"
body &= "<br/>"

body &= "[STACK TRACE]"
body &= "<br/>"
body &= ex.StackTrace.Replace(vbCrLf, "<br/>")
body &= "<br/>"
body &= "<br/>"

mm.Body = body
mm.Send()
End Sub


Obviously, you'll need to add your email address in and use either the default email class or another class if you'd prefer. You'll need the email to be set up in the web.config - which may be another good topic I could touch on another time. And then, it wouldn't hurt to go intentionally create an error. I made a blank page with the on load function that calls a function s() which doesn't exist:
Public Sub Form_Load() Handles Me.Load
s()
End Sub


If your VB.NET Application won't run on Windows 7

Despite being primarily a web developer, every now and then at my office, I need to create small little Windows Form based applications that perform one or two simple tasks to help out the every day processes of the staff.

Recently a couple people at our office were upgraded to Windows 7, and have experienced issues with those Visual Studio 2008 based applications, either during installation or running them after installing.

After some investigation, I stumbled upon the cause of the problem and a solution. Whether it is the machine or the operating system or gremlins sneaking around in this guy's new computer; for some reason, code compiled to work with the Target CPU value "AnyCPU" won't run on this machine.

To correct the issue, I opened the project settings in Visual Studio and clicked through to the Advanced Compiler Settings:
Project -> Compile -> Advanced Compile Options

Change the "Target CPU" field to "x86" and click OK.
Publish your application and it should install and run on the Windows 7 computer now.


Windows 7 Visual Studio 2008 Project Settings Target CPU