Sunday, November 16, 2008

export data into excel

Sigh...the eternal struggle. As you may know, we have some code, a couple versions actually, of a function that takes a gridview from a webpage and exports it into Excel. 2 problems: 1) sometimes it would break if the gridview used .NET controls it hadn't already been written to handle, and 2) what got put into excel was really an HTML table. Thus if someone tried to import it into certain statistical programs for analysis it might not be correctly read as real data. Not ideal!

A couple months ago, Dave found an article about putting a dataset into excel - nice! You don't even need to make a gridview on a webpage, you could create a dataset and send it straight into an excel file. I spent some time this weekend adding it to the toolbox, and making a version that would work with a datatable*. Then I read about a possible issue - what it is exporting into excel is XML formatted data. This could be a problem, not all statistical software our clients use will be able to import XML is my concern.

A little more research and I found an article by someone who explained how to send data into excel without a gridview, and it's not XML formatted. It essentially sends a tab-delimited, plain text translation of the datatable. I created another class based on this method. I ran into one very odd bug - a Microsoft bug, natch - that if the first column is called 'ID' in caps, it break. No comment. 

Please note that in the case of the both the XML formatted data and the plain data exports, since the gridview is not used, the data in Excel is exactly what is in the dataset/datatable. Therefore, if you have a gridview that formats the phone number for display purposes, but you use one of these classes to export the same data that binds the gridview, the end user will see the un-formatted data.

In conclusion, I plan to implement the plain text to Excel version from now on. It is in the Toolbox under DCReports, called ExportData.cs. The version that creates XML data from your data, then exports, is called Workbook Engine. I added the original sample code, and a version that handles datatables.

Questions? Comments? I long to hear the feedback!  ;)

Saturday, November 15, 2008

Helper Functions for gridview

I added a class for helper funtions to format gridview output, that can be called from the gridview in the aspx page like so:

Amount:
< % # DCToolbox.DCReports.GridviewHelpers.FormatShort(Eval("grantStartDate")) %>

FormatShort, for example, takes the object and if it's not a dbnull then it converts it to a short and displays that value, as long as the short is not one of the missing value constants for short in the DCConstants class.

There are only a couple of functions in there so far, please feel free to add more. I didn't find anything like this in the toolbox, but I didn't look hard so please let me know if it's redundant.

Thursday, October 9, 2008

Debugging in Visual Studio in Firefox

I just found out how to make the Visual Studio to debug in Firefox:
1. Right-click on the file in the Solution Explorer
2. Select "Browse with"
3. In the dialog box select Firefox. If Firefox is not there, click Add and browse to the firefox.exe on your computer.
4. Click "Set as Default"

The next time you run the project it will be in Firefox. It's quite easy to switch between IE and Firefox. One thing I noticed is that while using Firefox, closing the browser window won't stop the debug mode, you have to use Shift + F5, or some toolbar/menu item that I can't find, to stop debugging.

Tuesday, October 7, 2008

the membership provider

For my latest project, I decided to try out the built in login/membership stuff that .NET provides. I am following these tutorials. So far it has been easy to follow and the built in stuff has a lot of stuff that is good from a security standpoint. I'll keep you posted!

Wednesday, September 24, 2008

ORDER BY in a view or a nested select statement

I noticed one different behavior in SQL Server 2005 comparing with 2000:

If you run “select * from (select top 100 percent * from [table name] order by lastname) as temp” on SqlServer 2000 and on SqlServer 2005, you will see the difference. In 2000, the list you get is still sorted while in 2005 it's not.

The bottomline is: don’t say “order by” in a view or in a nested select statement. Putting "order by" in a view is never a good practice, in my opinion, because:
1. You have to say "top 100 percent" in order to do that
2. We should put "order by" in the most outer select so it costs minimum workload for the Sql Server (it only needs to sort the things you need at the end).

Thursday, September 4, 2008

Form authentication with SSL

This is the settings we need in the Web.config:
<system.web>
<sessionState timeout="180" regenerateExpiredSessionId="false"/>
<authentication mode="Forms">
<forms name="XXX" loginUrl="login.aspx" protection="All" timeout="180" requireSSL="true"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
<customErrors mode="RemoteOnly"/>
<compilation debug="false"></compilation>
</system.web>

Wednesday, August 27, 2008

DateTime ToString Formats

To format a DateTime:
string a = date.ToString("MM/dd/yyyy"); the string will look like "03/02/2008"

You can also do "MMM dd, yyyy", then you will have "Mar 02, 2008". For the entire list of format options, please see http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx.

Friday, August 22, 2008

toggleOptions

Hi guys!

Miss me? How can you miss me if I keep blogging! :P

OK so as you know I added a code library to the repo. I put all the Javascript we had already collected into it. The trouble is it's disorganized and some of it is pretty old and possible inefficient or not the best code. Therefore I hope to clean up the library to only have clean and good code :) And in an effort to do this AND organzie, from now on when I can I will add scripts into subfolders. I will label the folders by control type. Then inside the folder will be all the different scripts. So, if the JS is in a subfolder of Javascript, then it has been "quality controlled."

Please feel free to aid my efforts! Remember when you add a script to add a comment with your initials so we know who to ask if we have questions about the code!

Myself, I will try to blog whenever I add a script.

OK on to today's script. We may already have had something like this, I don't know. It was a mess in there so I didn't find it.

This function was written for those times when one of the options you pick should make all of the other options invalid. For example let's say the question is What color do you like best: red, green or none of the above? None of the above should obviously make it impossible to check red or green.

The code below is specifically for ASP:CheckBoxList, hence the part where I format the field's name as name = fieldName + "_" + i; because .NET takes the ListItem in a CheckBoxList and names it controlId_indexOfItem. If in my example the control was called cblColor then in the HTML red would have the id cblColor_0, and green would be cblColor_1 etc etc.

The parameters: optionToFocusOn is the one that triggers the function. In my example it would be cblColor_2, the none of the above. totalOptions is the total number of options, and in my example would be 3. fieldName would be the id of the control itself; in my example it would be cblColor.


//toggle options on and off - for use when one selection should disable the rest of the group
//for use with the ASP:CheckBoxList

function toggleOptions (optionToFocusOn, totalOptions, fieldName)
{
var name = fieldName + "_" + optionToFocusOn;
if (document.getElementById(name).checked == true)
{
for (i = 0; i < totalOptions; i++)
{
name = fieldName + "_" + i;
if (i != optionToFocusOn)
{
document.getElementById(name).checked = false;
document.getElementById(name).disabled = true;
}
}
}
else
{
for (i = 0; i < totalOptions; i++)
{
name = fieldName + "_" + i;
if (i != optionToFocusOn)
{
document.getElementById(name).disabled = false;
}
}
}
}

Thursday, July 24, 2008

document.form1 doesn't work?

In an aspx page, we use two ways to call a form from javascript:
1. document.getElementById("form1"), or
2. document.form1
and they both work.

However, the "form1" means different things in these two lines:
1. document.getElementById("form1") -- the form1 is the id of the form
2. document.form1 -- the form1 is the name of the form

When working on an aspx page, we only put id="form1" in the form tag, but when the page gets processed and sent back to the client, ASP.NET adds a bunch of stuff to the page, including name="form1" in the form tag (it puts a name in every server control in a page). So that is why document.form1 works in an aspx page without a name for the form.

If you works on an html page, you will have to put name="form1" to get the second method to work.

Monday, July 14, 2008

Form validation - part 2: the .NET validators

Since as we move forward, some of the team which does more of the front-end work, will start to delve more into contributing by doing some of the client-side validation, I thought it would be good to give an overview of the .NET validators. The first version of ASP.NET I worked with - 1.1 - had validator controls as part of the .NET framework. I bet they had them in the 1.0 version as well although I don't actually know for sure. Now the way these validators were supposed to work was like other .NET controls such as the datalist, or the repeater; you could just drag the control onto your page and hook it up. When the aspx made the round trip to the server and rendered in a browser, it would actually serve as client side validation of whatever field you hooked the validator control up to. The trouble was the 1.1 validators created javascript which only worked on IE. :P AND if javascript was disabled...no validation at all!

Furthermore, they were somewhat limited in what you could do with them. In the kind of forms we build, we frequently end up with skip patterns. "If you answered No to 12, go to 14" for example, meaning if you answered no to 12, 13 was not required; but if you answered yes to 12, then it WAS required. This was fairly simple javascript to create, but there existed no validator control that could handle it, except for the CustomValidator. And since we already had an extensive library of javascript functions covering most situations that cropped up, it was much simpler to just not use the validators and stick to the javascript.

In 2.0 however, Microsoft vastly improved the way these validator controls worked. Now they:

1. are cross browser compatible. WOW!
2. still work when javascript is disabled
3. have this neat option where you can tell them to ONLY turn on if the javascript is not enabled. COOL!

Our blog user known as tiger figured out how to work out #3 quite elegantly. Therefore #3 is the way we have been going, unless we don't have the hours to cover it. However as our code library goes, it is taking less and less time to even handle this task :)

Now I am going to show you a basic example. Let's say we have a form with one field with id 'greekGod' for "Favorite Greek god" and one field with id 'faveNumber' for "Favorite Number up to 20". Color is a textbox and Number is a dropdown starting with "Choose Number" for the zero index and going to 20.

Normally this might be your validation. Note that the following function actually calls 2 others, expecting them to return true or false individually. The following function is a handy way of checking numerous fields at once, and just returning false (in other words not letting the form submit) if ANY of them are invalid/have a problem:


function checkForm() <-- note it takes no arguments/parameters
{
if (
(isNotBlankAlpha(document.getElementById('greekGod'))) &&
(isSelected(document.getElementById('faveNumber'))
)
{
return true;
}

return false;
}


And this might be how you hook your form up to the javascript:


form onsubmit="return checkForm();"


If we were using the validator controls as well as the javascript, our javascript would be slightly altered:


function checkForm(source, clientside_arguments) <-- note it takes 2 arguments {
if (
(isNotBlankAlpha(document.getElementById('greekGod'))) &&
(isSelected(document.getElementById('faveNumber'))
)
{
clientside_arguments.IsValid = true;
}
clientside_arguments.IsValid = false;
}


And instead of hooking the form tag to the javascript, our aspx file would include a CustomValidator that might look like this:

asp:customvalidator id="CustomValidator1" runat="server" errormessage="" clientvalidationfunction="checkForm" onservervalidate="CustomValidator1_ServerValidate" display="Dynamic" setfocusonerror="True"


Note that it is the ClientValidationFunction property of the control that you use to tie it to the javascript. Note that you don't need the parens to call it either. However, notice that the javascript function itself now has 2 arguments. These are a mandatory signature; the source argument refers to the HTML tag that represents the validator control, and the clientside_arguments parameter refers to an object with 2 properties, IsValid and Value. The Value property is the value stored in the input control to be validated. The IsValid property must be set to false or true according to the result of the validation (Programming Microsoft ASP.NET 2.0 by Dino Esposito).

Note that the Value property is not relevant to the way we are using the CustomValidator - we are not using it to validate a single control, which is what the Value would be the value of - but instead we are validating a group of inputs all at the same time. Further, note that the javascript now takes 2 arguments - and it appears that these 2 arguments are in fact passed to the client function by the server, probably passed by the CustomValidator itself. Finally, the client function (javascript function), now that it is being tied to the CustomValidator, needs to set the IsValid property of the args parameters passed into it.

I hope this overview is somewhat helpful in explaining how to tie javascript to the ASP.NET CustomValidator control. Questions, comments, corrections are all welcome.

Form Validation - on the client side (part 1)

I just thought I'd put up a little overview on form validation. First here is a list of good articles on the subject.

http://developer.apple.com/internet/webcontent/validation.html
http://www.elated.com/articles/form-validation-with-javascript/
http://www.w3schools.com/js/js_form_validation.asp


OK, so here is my summary: whenever you are working with any form that is transmitted over the internet, you want to do some kind of validation of the input before you do anything with it. The point is not just to make sure that the input is correct - like you want to make sure a zip code has only numbers and no letters in it - but because forms are a gateway for malicious attacks on a web server. Secure forms will validate on the client side, usually using Javascript, and also on the server side, in the programming language of choice - after all not every client will have Javascript enabled.

However, for this post we are focusing on client side validation - so this is the checking that should be done before the form submits to the server. So when you are a validating a form you are doing a couple things:

1. making sure required fields are answered
2. making sure input is in a correct format

1. is self explanatory to me but more on 2:


Making Sure Input Is In a Correct Format


First, keep in mind that this should be done on ALL fields - both required and optional fields. As for what this means: you want to make sure that the input adheres to what you are expecting. Keep in mind that sometimes you can help achieve this by just designing for it. For example if you are collecting a date - don't give them a text field, give them 3 drop downs. They can't type "yesterday" if you don't give them something to type into ;)

More examples:
- SSN
- email
- phone number
- zip code
- valid range (i.e. if the answer should be 100-500, or 0 to 100%)

Let's look at SSN. To validate it, you would want to make sure that there are 9 characters, all of which are numeric. If you give the user one text field to enter SSN into, then you might start by stripping the field of all non-numeric characters, including whitespace. You would then test the length of the resulting string to see that it is 9.

This is the end of part 1. In my next post, I'll talk about doing client side validation within a .NET project that is also using the built in .NET validators.

Wednesday, July 9, 2008

Remove Whitespace

I added this method to the StringManip class in DCToolbox:


protected string RemoveWhiteSpace(string str)
{
if (str.Length > 0)
{
while (str.IndexOf(" ") > 0)
{
str = Regex.Replace(str, " ", "");
}
}
str = str.Trim();
return str;
}

Tuesday, July 8, 2008

Update a table with data from a view

Well this was my first (that I can remember) update query using data from an outside source - in this case, a view. It was actually documented quite clearly in Books Online. Nevertheless, code example, in case it is of use:


UPDATE table SET table.apple = v.apple
FROM table as t
INNER JOIN view as v
ON t.id = v.id


Why I had to use aliases for this to work is more than I understand. Explanations? Comments?

validators in DCToolBox

I copied into DCToolBox a bunch of the validators that Jinghua has written. The idea is that client side validation will be run first but in a client with Javascript disabled, these server side validators will run instead. I modified a few of them, which were for optional fields, to take an optional T/F parameter. Eventually all of the validators should have this, then they can be used for both required or optional fields.

I also added some new ones, including this:


public static bool AtLeastOne(List listOfResults, string msg, CustomValidator validator)
{
bool bOK = false;
foreach (bool i in listOfResults){
if (i == true)
{
bOK = true;
break;
}
}
//check only if no true items - meaning no field was answered
if (!bOK)
{
validator.ErrorMessage += String.Format(msg);
bOK = false;
}

return bOK;
}


This is for those situations where at least one of several fields must be answered - for example if you have 4 phone number fields, at least one of them must be filled in. Check all of them, returning a bool indicating if they are answered, and then collect those bools into a List<> and send that list to this function.

I have also written a few functions for returning a simple t/f to indicate whether a field has an answer to work with the above function.

Questions? Comments? Let 'er rip! If you need an example of how to use these validators in a project then let us know and one of us can post it.

Monday, June 23, 2008

Videos!

I made us an account at vimeo, which is like youtube, but not as big, and also I like the interface way, way better. I uploaded some demo videos there to embed in blog posts, because uploading video to blogger isn't working right now. ANYWAY, I will add a link to the our page on vimeo to the right hand side ----->

And I'll email you the login.

Web Form Tips by Layla

Here are some tips for making web forms. I welcome your feedback!

1. keep form names lowercase: Generally, I try to do this. Every once in awhile I have to work with a system that is case sensitive, and having to know the cases in my filenames is most annoying.

2. Keep pages short: You don't want to have users scrolling much. One page in a word document does not need to take up one web form. You can break it up into nice, user-friendly chunks.

3. Make text readable: don't user oversaturated colors, don't make the text to small, and put lots of whitespace - the reading equivalent of breathing room.

blank solution

Dave & I were modifying a solution the other day because it needs multiple projects, and the default project needed to be renamed and not be in the root of the solution. We started over by making a blank solution. Then I started thinking that it was probably best it we started ALL of our new web application projects in Visual Studio as blank solutions, from now on. Watch the attached movie for details.


How To Make a New Blank Solution in Visual Studio 2005 from CRHCDataCenter on Vimeo.

Monday, June 9, 2008

New Office extension

Hey guys,
This just came to my attention so I thought I'd mention it as a heads up - if you've built anything that takes uploads, and you check the extension, you might want to account for the new Office extensions (docx, pptx, etc).

UPDATE:

The server needed some configuring so that one's browser could handle these new Office 2007 extensions (see this article). Don has handled it but just a heads up if you ever encounter that links to these extension don't work, this might be the culprit.

Friday, May 23, 2008

case statement

Access has an IIF statement, SQL has the case. Want to display your bit data as "yes" or "no"? Enter the case statement! Example:


SELECT thisVariable, thatVariable,
CASE
WHEN likesApples = 1 THEN 'yes'
WHEN likesApples = 0 THEN 'no'
WHEN likesApples = 2 THEN 'not sure'
else 'not answered'
END AS appleVariable
FROM thatTable

Thursday, May 15, 2008

organizing your stylesheet

UPDATE (7/12/09): Having read Andy Budd's CSS Mastery, I favor the structure he demonstrated. I highly recommend that book by the way. See sampleCSS.css in the resources folder of our repo.

----------------------------------

Organizing a css file is something we should probably think a little more about. I have tried various ways. If the stylesheet is very clearly organized you not only make it easier to read and modify, but also to debug later. Here is a sample I found online of a stylesheet for a free wordpress theme. I like the way the author organized their styles.

Do you have a good example? Blog about it! ;)

ARTICLES ON THE TOPIC ---> links at the bottom.


/*
Theme Name: statement
Theme URI: http://www.blogohblog.com
Description: The "Statement" WordPress theme has been built by Blog Oh! Blog and comes under a Creative Commons License.
Version: 1.0
Author: Jai Nischal Verma
Author URI: http://www.blogohblog.com
*/

/*+++++++ BODY +++++++*/
* { margin: 0px; padding: 0px; list-style:none; text-decoration:none; }
body { font-family: Arial; font-size: medium; color: #4d4b4c; background: #fff url(images/bkg.gif) repeat-x; }

/*+++++++ H1,H2,H3 HYPERLINKS +++++++*/
h3 { padding:10px 0 10px 0; font-size:14px;}
a:link { text-decoration: none; color: #006666; border: 0px;}
a:active {color : #006666; border: 0px;}
a:visited { color :#006666 ; border: 0px;}
a:hover { color:#333333; border: 0px;}
a:focus { outline: none;}
.clear { clear: both; }

/*+++++++ MAIN +++++++*/
#wrapper { width: 1000px; margin:auto; }
#frame,#content { width: 975px; margin:auto; }

/*+++++++ TOP +++++++*/
#header { height: 106px; width: 1000px; }
#logo { float: left; width: 210px; padding-top:30px; padding-left:10px; }
#logo h1{text-indent:-10000px;}
#logo h1 a{display:block; background: url(images/logo.gif) no-repeat; height:63px; outline:none;}
#topleft { float: right; height: 106px; width: 630px; }
#searchbox { float:right; width: 233px; height: 36px; background: url(images/s.gif) no-repeat; margin:20px 5px 0 0; }
#searchbox #s { float: left; margin: 4px 0 0 6px; border: 0; width: 200px; background: none; color:#999999; }
#searchbox #go { float: right; margin: 3px 4px 0 0; width:18px; height:18px; }

/*+++++++ NAVIGATION +++++++*/
#nav { float:right; padding-right:10px; margin-top:10px;}
#nav ul { }
#nav ul li {display:inline; height:35px; line-height:35px;}
#nav ul li.current_page_item a { background:url(images/navbg-acho.gif) repeat-x; color:#fff; }
#nav ul li.current_page_item a:hover{background:transparent;color:#fff;}
#nav ul li a { color:#fff;float:left; text-transform:uppercase; padding:0 0 0 20px;}
#nav ul li a:hover{background:none;color:#dadada; text-decoration:none;}

/*+++++++ INFOBAR +++++++*/
#infobar { height: 30px; width: 975px; line-height:30px; font-size:11px; margin-bottom:15px; }
#browse { float: left; width: 570px; background:url(images/folder.gif) no-repeat 0 6px; padding-left:22px; }
#rss { float: right; height: 30px; width: 383px; background:url(images/feed.gif) no-repeat right; }
#rss p { padding-right:22px; text-align:right;}

/*+++++++ ENTRY +++++++*/
#left { float: left; width: 570px; }
.entry { width: 540px;
padding:4%;
background:#fff;
border:1px solid #dadada;
margin-bottom:10px;
line-height:140%;
font-size:0.9em;
color:#4F5B5F;
}
.entry h2 { font: bold 1.3em "lucida grande",georgia,"Myriad Pro","Myriad Set","Myriad Apple",Myriad,Helvetica Nueue,Arial,Verdana,Sans-serif;letter-spacing: -1px;margin-bottom:0; margin-top:0;margin-left:-8px;}
.entry h2 a { color:#327489; }
.entry h2 a:hover {color:#B80EA2;}
.entry p { padding-bottom:10px;}
html>body .entry ul { padding: 0 0 0 30px; padding-left: 10px; }
html>body .entry li { margin: 7px 0 8px 10px; }
.entry ul li:before { content: "\00BB \0020"; }
.entry ol { padding-left: 2em; margin:0;}
.entry ol li { background:#fafafa; list-style-type: decimal; line-height: 120%; font-size:0.9em;}
.entry img {margin:0 10px 10px 10px;}
img.centered { display: block; margin-left: auto; margin-right: auto; }
img.alignright, img.alignleft { padding: 11px; margin: 7px; display: inline;background:#EBE5EF; border:1px solid #C7BBD0; }
.alignright { float: right; }
.alignleft { float: left ;}
.allinfos { font-size:0.7em;font-family:georgia;font-style:italic; height:20px; padding-bottom:1.4em;margin-left:-8px;}
span.date {font-weight:bold;font-family:'lucida grande';font-style:normal; }
span.comments { background:url(images/comment.gif) no-repeat; padding-left:20px; }
span.category { background:url(images/posted.gif) no-repeat; padding-left:20px; }
.navigation { width: 540px; padding:10px; line-height:140%; font-size:11px; }
.entry p a {color:#9C0F6F;}


/*+++++++ SIDEBAR +++++++*/
#sidebarbottom { float:right; width: 400px; }
#right { float:left; width: 400px; }
#topsidebar { width: 380px; padding:0 10px 0 10px; border:1px solid #dadada; background:#fff; margin-bottom:10px; }
#lsidebar h2 { font-size:15px; margin-bottom:10px; color:#4c4c4c;}
#rsidebar h2 { font-size:15px; margin-bottom:10px; color:#4c4c4c; }
#lsidebar { float:left; width:160px; padding:5px; border:1px solid #dadada; background:#fff;}
#rsidebar { float:left; width:195px; padding:5px 10px 5px 10px; border:1px solid #dadada; background:#fff; margin-left:8px;}
#sidebarbottom ul{ margin:10px auto 20px;}
#sidebarbottom ul li{}
#sidebarbottom ul li ul{}
#sidebarbottom ul li ul li{display:block; background:url(images/bullet.gif) no-repeat 0 0; padding-left:24px; padding-bottom:5px; border-bottom:1px dotted #dadada;}
#sidebarbottom p{padding:0 5px;}
#lsidebar li, #rsidebar li {font-size:0.8em;}

/*+++++++ COMMENTS +++++++*/
.postmetadata { padding:5px; background:#feffe5; }
#commentform p { padding-bottom:10px;}
#commentform #author { border:1px solid #dadada; height:20px; width:200px; }
#commentform #email { border:1px solid #dadada; height:20px; width:200px; }
#commentform #url { border:1px solid #dadada; height:20px; width:200px;}
#commentform #comment { border:1px solid #dadada; height:200px; width:500px;}
.commentlist cite { background:#f9f9f9; padding:5px 5px 5px 10px; }
.commentlist cite a { color:#333;}
.commentlist .ctext { background:url(images/doth.gif) repeat-x bottom; font-size:11px;}

/*+++++++ FOOTER +++++++*/
#footer { background: #222222 url(images/footer.gif) repeat-x; width: 100%; margin:15px auto 0px; height:100px; font-size:10px; }
#foo { background:url(images/foobg.gif) no-repeat right; width: 955px; margin:auto; padding:10px; height:80px; color:#fff; }
#foo a:link { color : #FF9900; border: 0px;}
#foo a:active { text-decoration: underline; color : #FF9900; border: 0px;}
#foo a:visited { color : #FF9900; border: 0px;}
#foo a:hover {color: #FFFFFF; border: 0px;}
#foo ul { float:left; margin-top:10px; }
#foo ul li {display:inline; height:35px; line-height:35px; font-weight:700;}
#foo ul li.current_page_item a { background:url(images/navbg-acho.gif) repeat-x; color:#fff; }
#foo ul li.current_page_item a:hover{background:transparent;color:#fff;}
#foo ul li a { color:#fff;float:left; padding:0 20px 0 0;}
#foo ul li a:hover{background:none;color:#dadada; text-decoration:none;}

/**************** Misc *********************/
acronym, abbr, span.caps { cursor: help; }
acronym, abbr { border-bottom: 1px dashed #999; }
blockquote { margin: 15px 30px 15px 10px; padding-left: 20px; border-left: 5px solid #ddd; }
blockquote cite { margin: 5px 0 0; display: block; }
.center { text-align: center; }
hr { display: none; }
a img { border: none; }
pre {border: solid 1px #9a9a9a;color: blue;margin: 10px;padding:10px;background: #f3f2ed}
code {font-size:1.0em;color: #000}

/**************** Gallery *********************/
.gallery {text-align:center;}
.gallery img {padding:3px;}
.attachment {text-align:center;}
.attachment img { padding:5px; border:1px solid #999999;}
.imgnav {text-align:center;}
.imgleft {float:left;}
.imgleft img{ padding:5px; border:1px solid #999999;}
.imgright {float:right;}
.imgright img{ padding:5px; border:1px solid #999999;}


- 5 Tips for Organizing Your CSS
-Tips from Doug Bowman

Firefox add-ons: source code viewing tools

Two helpful tools for viewing the source code of any pages:
View formatted source: https://addons.mozilla.org/en-US/firefox/addon/697
View source chart: https://addons.mozilla.org/en-US/firefox/addon/655

Friday, April 4, 2008

interacting with Active Directory


Recently I had to work on a web application that authenticated via Active Directory/IIS. In other words in IIS, anonymous access was turned off for my app, and Windows Authentication was turned on (image shows default setting for a web app; for this situation you need to uncheck anonymous access and check windows integration). When you do this, you then set at the folder level in Windows explorer who has access. It is at the folder level that it was indicated, in my case, to use Active Directory. For the current ePortfolio, on the other hand, users were added, account by account, to the folder via the Security tab.


Here are some articles on the topic:

Integrated Security with Web Application

Accessing the Active Directory from Microsoft .NET

Howto: (Almost) Everything In Active Directory via C#

Now I didn't really use the methods describes in these articles because they all demonstrate a way to interact with Active Directory that involves connecting directly to the Active Directory server. In my situation, I was not able to obtain the information needed to create the connection (LDAP server info). So below I will show you the code I did use.


string strADUser = Request.ServerVariables["LOGON_USER"].ToString().Substring(Request.ServerVariables["LOGON_USER"].ToString().LastIndexOf("\\") + 1);


Note that for ePortfolio Dave accessed the "HttpContext.Current.User.Identity.Name" property. I tried this first but it appears AD does not populate this property.

The last of my code:

Here I compare the SAMAccountName of the logged in user, to see if that person is a member of a specific AD group:


DirectorySearcher search = new DirectorySearcher();
search.Filter = String.Format("(SAMAccountName={0})", strADUser);
search.PropertiesToLoad.Add("memberOf");

SearchResult result = search.FindOne();
if (result != null)
{
int groupCount = result.Properties["memberOf"].Count;

for (int counter = 0; counter < groupCount; counter++)
{
string str = (string)result.Properties["memberOf"][counter];
if (str.Contains(editGroupName))
{
return true;
}
}
}


Any questions, suggestions for improvement? Post to the comments!

Tuesday, April 1, 2008

transaction

I am always looking through our code for a previous example of using transactions in .NET, so I am posting the code here. That's what here is for!



private void TRANSACTION EXAMPLE(int example)
{
using (SqlConnection conn = new SqlConnection(dsn))
{
conn.Open();
SqlCommand cmd = conn.CreateCommand();
SqlTransaction transaction;

transaction = conn.BeginTransaction("GiveItAName");
cmd.Connection = conn;
cmd.Transaction = transaction;
try
{
//1st query, initializes sql variable
string sql = "INSERT INTO someTable etcetc";
cmd.CommandText = sql;
//define needed parameters is any
cmd.ExecuteNonQuery();

//next query
sql = "UPDATE or WHATEVER QUERY etc etc";
cmd.CommandText = sql;

// define needed parameters
// NOTE you don't have to define any param if it was already defines and used for a previous query
cmd.Parameters.Add("@something", SqlDbType.VarChar, 50).Value = exaple;
cmd.ExecuteNonQuery();

//next query
sql = "UPDATE etc etc";
cmd.CommandText = sql;
cmd.ExecuteNonQuery();

// Attempt to commit the transaction.
transaction.Commit();
}
catch (Exception)
{
// Attempt to roll back the transaction.
try
{
transaction.Rollback();
}
catch (Exception)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
throw;
}
throw;
}
}
}

Thursday, March 13, 2008

adding using statements

anyone know a good shortcut for adding it to all cs files in a project in Visual Studio?

Wednesday, March 12, 2008

Calculation in an UPDATE statement

This is how you do it:
UPDATE myTable SET myField = myField + 1 WHERE myId = XXX

Tuesday, March 11, 2008

Store application information in web.config

To store application information in web.config is easy:

In Web.config

<appsettings>
<add value="xxx@xxx.com" key="adminEmail">
</appsettings>

In the program, this is how you retrieve the information:

string sEmail = System.Web.Configuration.WebConfigurationManager.AppSettings["adminEmail"].ToString();

Storing this type of info in the web.config allow you to set it at anytime without recompiling your program. So when you are testing, set it to your own email address so you will set the email. I am tired of getting and deleting the testing emails :)

Friday, March 7, 2008

Images and Clipart

Good morning every,
I have been doing some research on images and vector images (clip art) for us to use for stock photography for our web site development. I found this site from microsoft.

http://office.microsoft.com/en-us/clipart/FX101321031033.aspx

This link allows you to download photographs, vector images, and some other stuff. I downloaded the organizer and it worked very well for me. It is also free, or at least I didn't get charged.

Might be good for us when we need pictures. Let me know if you have any questions...

Wednesday, March 5, 2008

CSS Shorthand Guide

I was looking up some CSS help for displaying background images correctly in IE and Firefox and I came across this:

http://www.dustindiaz.com/css-shorthand/

Its a CSS Shorthand guide that some of you may want to look at. I havent had a chance yet but it looks good :)

Dave

Thursday, February 21, 2008

web.config debug="false"

I think we should change all the live sites' web.config with debug="false". It's both insecure and inefficient to leave debug="true" on a live site based on these two articles:
http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx
http://networking.itbusinessnet.com/articles/viewarticle.jsp?id=135133

If we remember to do that every time we publish a site, we might be able to use that info to tell if it's from test site or live site.

Ignore settings in TortoiseSVN

Hey guys, 

Just wanted to check in and see that everyone has this stuff set in their TortoiseSVN Settings. Does anyone have something different than shown in this pic?

Thursday, February 14, 2008

sqlbulkcopy

I have just used sqlbulkcopy for the third or so time. This is a handy thing built into 2.0 that you should be familiar with. In the past I have used it in my code to copy a row into an "archive" table before deleting it from the initial table. Today I used it to copy data to a database housed at another school. I had a copy of their schema. I built a view of our data, such that the view held just what needed to go into their table. Here is my sample code:


string sql = "SELECT * FROM sourceView";
using (SqlConnection conn = new SqlConnection(dsn))//source dsn
using (SqlCommand cmd = new SqlCommand(sql, conn))
using (SqlBulkCopy copy = new SqlBulkCopy(dsn2))//destination & source dsn are the same
{
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
copy.DestinationTableName = "destinationTable";
//have to map the columns because the tables are not an exact match
copy.ColumnMappings.Add("fieldname", "samefieldButSlightlyDifferentName");
copy.ColumnMappings.Add("fieldname2", "samefieldButSlightlyDifferentName2");
copy.WriteToServer(rdr);
conn.Close();
}


A couple things to note. I copied code from the last time I did this. Reading my comment I'm not sure I actually needed to map out the columns, because from my view to the destination the schemas matched up. Last time I did this however, there were a few more columns in the destination table, hence my comment about the not matching up. Second, I got this error early on: SqlBulkCopy: the locale id '0' of the source column ' ' and the locale id '1033' of the destination column '' do not match. This was because the ID column in my table was an int and in theirs was varchar. I therefore modified my view for that and one other column so that the data types matched using CAST(field as varchar) AS field.

Wednesday, February 13, 2008

firesizer

Guys,
I've tried out and like a new extension for Firefox. It's the third of its kind that I have tried & so far I like it the best. It's just a window resizer, but this one integrates into the status bar so no menu interaction is needed to access it, and it keeps your current size available for you in the status as well. Nice! Here is a link: https://addons.mozilla.org/en-US/firefox/addon/5792

Tuesday, January 29, 2008

Javascript Object Visibility

Hey all,

I am trying to do some error checking in my javascript code and I have ran across an issue with the visibility of an object.

I am hiding an object on the page using document.getElementById('objectname').style.display = 'none';

When I go to see if it exists using the code below (the object IS not visible on the screen at the time), nothing happens

if(document.getElementById('objectname').style.visibility == 'hidden')
{
alert('message');
}


I have also used with no avail:


if(document.getElementById('objectname').style.display == 'none')
{
alert('message');
}

Any ideas?

browser for debugging in Visual Studio

Anyone know if you can set the specific browser for VS to use when it runs the debugger? I can't remember but I thought I had set it to IR even though my default browser is Firefox.

Friday, January 11, 2008

Max Length for Text Boxes

I know a while back that we had mentioned putting MaxLength values on all text boxes to prevent OverFlow Exceptions.

I would like to get opinions on certain Text Box values and what we could use as a MaxLength in these cases:

Common Dollar Figures: since these include a decimal sometimes they may require a larger MaxLength Correct? What do we think a typical MaxLength would be in this situation?

Integer Amounts: Since a MaxLength of 9 here and a MaxLength of 9 in a Currency field are different, this could cause for Overflow Errors. 999999999 (Overflow) is much larger than 999999.99 (No OverFlow) (MaxLength 9 TextBox example)

Percentage amounts? Im thinking 4 MaxLength but what do you all think?

Obviously in certain situations:

Question directed at Sidney Crosby: "How much money did you sign your contract for?" Would be at the programmer's discretion.

Thanks for reading!

Bills Fan Dave

C# method documentation

Maybe you have known about this, but I just found that you could put this before a method.
/// <summary></summary>
/// <param name="field"></param>
/// <param name="msg"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <param name="validator"></param>
/// <returns></returns>

I just put this before my method "isValidIntegerRng".
/// <summary>
/// check if an integer field is valid and within range, the field is optional
/// </summary>
When I made the call to this method, I wasn't sure if the field is optional or not. This way you can hover over the method call and see the comment so you don't need to open the class to see it.

Thursday, January 10, 2008

What does "hth" mean?

Team,

As I google for answers to my coding questions, I notice that when people end their blog entries they use the abbreviation "hth".

I have always been perplexed by this. What does it stand for?

Bills Fan Dave

Wednesday, January 9, 2008

Session State (Web.Config)

Does anyone know how to programmatically change the web.config's timeout property for Forms Authentication?

I have a few different seminar types and only one of them gets a 30 minute timeout the others are 60 minute timeouts.

I tried this:

if (seminarcode == 2)
{
Session.Timeout = 1; (for testing purposes)
}

This only sets it so that the page timesout after 1 minute of no use where I want to make everything cease after a minute no matter what the user does.

I thought I had the answer but it appears I do not.

PLEASE HELP!

also... what does "hth" mean?

Dave

Monday, January 7, 2008

New Tortoise

Has anyone upgraded to the new version of Tortoise SVN yet? Any issues with it if so?

Wednesday, January 2, 2008

sanitize data


Welcome back everyone! Here is an enjoyable little comic for you all:

From http://xkcd.com/327/