Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Saturday, 9 May 2009

Repeater NamingContainer Gotcha

Here was an odd thing. Take one repeater
<asp:Repeater runat="server">
<ItemTemplate>
<asp:CheckBox ID="chkBox1" AutoPostBack="true"
OnCheckedChanged="CheckBox_Click" runat="server" />
<asp:TextBox ID="txtBox1" runat="server" /><br />
</ItemTemplate>
</asp:Repeater>


Bind it up to something and get a list of textboxes and checkboxes. Like so



The task is to wire up the Checkbox click event so that when it is clicked the corresponding textbox is disabled i.e.

Easy peasy I thought and wired it up with this code
protected void CheckBox_Click(object sender, EventArgs e)
{
CheckBox myCheckbox = (CheckBox)sender;
TextBox textBox = (TextBox)Page.FindControl("textBoxId");
textBox.Enable = !myCheckbox.Enable;
}

The surprising result is that no matter which checkbox is clicked it is always the first textbox that is disabled. The problem is with finding the control. The line fourth line has changed -
protected void CheckBox_Click(object sender, EventArgs e)
{
CheckBox myCheckbox = (CheckBox)sender;
TextBox textBox = (TextBox)myCheckbox.NamingContainer.FindControl("textBoxId");
textBox.Enable = !myCheckbox.Enable;
}


I suddenly realised what a NamingContainer was. Previously I just thought it was a piece of arcane .Net knowledge – defined in MSDN as

Gets a reference to the server control's naming container, which creates a unique namespace for differentiating between server controls with the same ID.

Yeah right whatever. Well apparently it’s actually important stuff.

In the first example the code finds the first textBox called “textboxId” in the page. This is always the first one hence my code doesn’t work. In the second, corrected code – the control is searched for within the NamingContainer of the event sender – in this case it’s the RepeaterItem. So in the repeater there are any number of texboxes called “textboxId” but the don’t clash and can be accessed because each one exists in it’s own NamingContainer – i.e. unique naming space.
I appreciate this will be obvious stuff to many people but I felt like a super-brained coding rock star when I found this out. Then again I’m easily impressed.

Saturday, 18 April 2009

The Power of (C# Keyword) As

I’ve been coding in C# now for 5 years. Other than with my wife, C# is my longest standing relationship. While I don’t celebrate my anniversaries with C# (yet – though I might on our 10th) I did think that I was familiar, maybe even intimate, with the language. Why then had I never heard of the as keyword.

Previously I would cast object like so
try
{
Checkbox myCheckBox = (Checkbox)strangeObject;
//do some clever stuff
}
catch(Exception)
{}
- which works fine. My niggle with this that you’re getting towards using exceptions to manage the flow of code and the seven circle of hell is reserved for coders that indulge in this satanic practice. Enter the angelic keyword as

Let’s do the same thing, this time with our new friend.
Checkbox myCheckBox = strangeObject as Checkbox;

if(myCheckBox != null)
{
//do something clever
}
The as casts the object but instead of spewing out an exception it gracefully nulls it. Therefore it’s same code but with no exception unpleasantness. I like this a lot better – it’s like wholemeal fibre vs. saturated fats. It’s just a lot better for you.

Wednesday, 8 April 2009

.Net Control Collection Gotcha

Making puff pastry is something that sounds like it should be easy but when you’ve got the butter, flour and mixing bowl out it turns out to be excessively difficult. In the same vein – iterating through a collection of .Net controls and finding all the ones that are checkboxes sounds straight forward but is in fact a bit of a pen chewer.

My first attempt. This is a winner surely.
foreach (Control control in thisPanel.Controls)
{

if (control.GetType() is CheckBox)
{
//never going to work
}

}
Nope – the compiler complains straight away that ‘Control control’ will never be of type checkbox. OK sounds reasonable. After some discussion with colleagues a fellow programming minion suggested that it’s the foreach that’s the problem – so try the following.

for (int i = 0; i < thisPanel.Controls.Count; i++)
{
if (thisPanel.Controls[i].GetType() is CheckBox)
{
//won’t get here either
}
}
Looking good – but sadly again won’t work. The problem is that the control collection has already been downcast to a generic control. Therefore it doesn’t ‘know’ anything of its original type. What’s a boy to do? The best 4 programmers could come up with a combined amount of programming experience of over thirty years was –
foreach (Control control in thisPanel.Controls)
{
CheckBox checkBox = control as CheckBox;

if (checkBox != null)
{
//now we can do something
checkBox.Enabled = false;
}
}
This solves the problem so hurray. I have a nagging feeling that there is a better solution. It seems a simple request that should be achievable without guessing what types are in there. It’s probably something wildly clever with generics/delegates/lambda expressions or some such. Further pondering required I think.

Saturday, 28 March 2009

Hard-Coded Passwords Gotcha

Everyone agrees we should give to charity but not that many people do. In the same way everyone agrees we should write secure software but I’ve seen again and again web applications that you could break with a Swiss army knife and a bent paper clip. I think part of the problem that security advice seems overwhelming and hectoring. Reading the recent list of CWE/SANS Top 25 Most Dangerous Programming Errors is like been nagged at by your office manager. I can’t disagree but I can’t take in anymore.

The best way to know and appreciate something is to see it. CTW-259 warns of hardcoded passwords. It was only when I downloaded reflector that I realised how much of a problem this was.

Consider this fragment of a class
public class TestClass

{

private string _password = "supersecretpasswordnoonecansee";

private int _testInt;



/// <summary>

/// Test Int

/// </summary>



public int TestInt

{

get { return _testInt * 6; }

}



//etc....

}
That password is secure as houses when complied. Well once it’s loaded into Reflector and disassembled then probably not


That took me about 30 seconds to break. Reflector is a free download so it’s not even costly for the hacker. Bit more costly for the victim though.

Monday, 16 March 2009

Reflector: Disassemblement for the Masses

I appreciate it’s probably an unpopular pastime for many of us geeky developer types but sometimes talking to colleagues does have its benefits. Once we’d finished discussing the latest BattleStar Galactica episodes and reminiscing about tabletop war gaming our conversation turned to tools of a cool nature, particularly reflector.

Reflector is a disassembler for .Net provided by the lovely people at Redgate. It’s so good that it seems almost magical in its power. Previously if I wanted to poke around in a dll then I’d use MSIL disassembler (ildasm.exe) and then feel all manly that I was interfacing directly with the intermediate language code. Since I was feeling all scientific I whipped up a quick test class to compare the two.

The test class
using System.Collections.Generic;
using System.Text;

namespace TestProject
{
/// <summary>
/// Test Class
/// </summary>
public class TestClass
{
private int _testInt;

/// <summary>
/// Test Int
/// </summary>
public int TestInt
{
get { return _testInt * 6; }
}

private string _testString;

/// <summary>
/// Test String
/// </summary>

public string TestString
{
get { return _testString; }
set { _testString = value; }
}

/// <summary>
/// Test Class
/// </summary>

public TestClass()
{
_testString = "TechSplurge";
_testInt = 99;
}

/// <summary>
/// Test Method
/// </summary>
/// <param name="maxCount"></param>
/// <returns></returns>
public void TestMethod(int maxCount)
{
for(int i=0;i<maxCount;i++)
{
Console.WriteLine(_testString + i.ToString());
}
Console.WriteLine("End");
}
}
}
With Ildasm

It’s a bit cryptic in there. Let’s look at the manifest






OK I can see namespaces but the rest is mysterious


With Reflector



Wow – the scales have fallen from my eyes and I see real code buried in the dll.

In fairness it’s a little like comparing apples with oranges. Ildasm.exe is for looking at what the code actually does once it’s been compiled - useful when really going for performance tweaks. Reflector is for seeing what the programmer intended and for seeing how on earth that third party dll works.

Monday, 9 February 2009

Trivalent Logic

My two favourite posts on DailyWFT is the Brilliant Paula Bean and What is Truth. Whereas the Paula Bean post is just, well, brilliant the What is Truth post I’ve started to feel is a tad harsh.

The post describes the most bizarre enum – a custom Boolean with three values – True, False and FileNotFound. Hahahahaha – how dumb. However the Infragistics Excel component I’ve been using recently also has a three part Boolean

ExcelDefaultableBoolean.True
ExcelDefaultableBoolean.False
ExcelDefaultableBoolean.Default

Mmmm – less dumb. And it doesn’t take much to dream up circumstances that you may need more parts to your Boolean

True
False
Default
Unknown
Not Specified

We seem to expect that because computers work with 1s and 0s we should too and any attempt to extend Boolean logic is just wrong. However, while jamming file not found into a bool may well be a little odd, I’ll certainly be liberating my Booleans this week from the tryanny of binary logic. 10 part Booleans anyone. You know you want to.

Saturday, 31 January 2009

Testing for Database Nulls in C#

Things I always forget

  1. Mother’s Day (sorry mum)

  2. My mobile phone telephone number

  3. The 7 times table

  4. How to test for Database nulls

There’s not much hope for the first three – however maybe a quick blog might help with the last one

How I always try to test for database nulls


If(drDataRow["FieldName"] == null)

{

//Nope this never works. I won’t hit this

}

How I should test for database nulls


If(drDataRow["FieldName"] is DBNull)

{

//It works! Shirt off and do the victory dance

}

Now if I can just work on those times tables ………

Saturday, 24 January 2009

Estimating Lines of Code

I’ve always been a bit puzzled on why people would use lines of code to estimate projects. It seems that estimating (more realistically guessing) lines of code (LOC) to estimate effort and schedule is way harder that splitting the project into jobs and undertaking an estimate for each job. However reading Steve McConnell’s Rapid Development book has changed my mind.

In it he has charts linking lines of code to effort over a range of criteria. So if you know the LOC for your projects you can plug them into the tables and see how you projects measure up. Moreover you could get lines of code for a project to build a historic set of data tailored to your team to take some of the guess work out of that blackest of all arts – software estimation.

Which got me thinking of how you would quickly get non-commented, non-whitespace lines of code for a Web Application written it ASP.Net



C#
Count the semicolons C#.

CSS
I would count the number of {

HTML
LOC are more difficult here. Possibility to count open angled brackets (<) and maybe divide by 5 – making the assumption that there is 5 tags per line JavaScript and VB.Net
Semicolons doesn’t work so well here as they are optional in the code. You’d need to be a bit cleverer and count the number of carriage returns without comments and with a length of more then one when been trimmed

OR

Quick and dirty: arbitrarily estimate the number of characters per line then whip through all the files and could the characters and divide by the per line estimate.

SQL stored procedures and functions
Like JavaScript you’d be looking at using carriage returns or using the quick and dirty method

Other elements.
For example SQL reports, Data extract components etc…
Can’t do anything with these so get the back of the envelope out and estimate what fraction of the project was spend on these activities. Multiple the LOC by this ratio.



In the best of all worlds we would all use function points or some kind of automated formula based approach but I moved out of the best of all worlds sometime ago and sadly my software development occurs in the dirty old real world. In this world one frequently doesn’t have time to spend half a day calculating historical effort but you’ll always have the opportunity to spend a sneaky 15 minutes seeing how many LOC were wrote and how long it took. It’s always good to marvel at how much work you’ve done and it may even make software estimation a slightly less black art in the future.

Sunday, 14 December 2008

DataTable Filtering Gotcha

The mission – if you choose to accept it is to filter a .Net DataTable to return results from a year or more ago. The code is
DataTable dtDataTable = GetDataTableMethod()

//.. limit the dataset
DataView dvDataTable = new DataView(dtDataTable);
dvSurveyList.RowFilter = "DateField < '" + DateTime.Now.AddYears(-1) + "'";
Our spies tell us that it doesn’t actually work. Agent tech splurge what is the solution? Stand well back folks while I insert the missing line.
DataTable dtDataTable = GetDataTableMethod()
dtDataTable.Locale = CultureInfo.CurrentCulture;

//.. limit the dataset
DataView dvDataTable = new DataView(dtDataTable);
dvSurveyList.RowFilter = "DateField < '" + DateTime.Now.AddYears(-1) + "'";
To me this makes sense. If you’re playing with dates then you’ll need the culture information – dates being different in different cultures. The odd thing is that the first set of code worked perfectly – until it stopped working. I have to confess I still don’t know why.

Saturday, 15 November 2008

ExecuteNonQuery Gotcha

Here’s something that made me roll my eyes this week. I’ve been trying to get the number of rows executed returned from SQL Server to an ASP.Net data layer. It promised to be straight forward but it had a cheeky little gotcha nestled in the middle of it. To take the simplest example for demo purposes (all error handling type stuff omitted)

The stored procedure

CREATE PROCEDURE usp_TestProc
@PersonId int
AS
BEGIN
Set Nocount On

Update Person
Set
FirstName = 'Willy',
Surname = 'Wonka'
Where
Id = @PersonId
END

The calling business layer

conn.Open();
cmdNonQuery = conn.CreateCommand();
cmdNonQuery.CommandType = CommandType.StoredProcedure;
cmdNonQuery.CommandText = “usp_TestProc”;
cmdNonQuery.Parameters.AddRange(sqlParameters);
numberOfRecords = cmdNonQuery.ExecuteNonQuery();
 

Logic (and the .Net API documentation) dictates that the ExecuteNonQuery method returns the number of rows. But it steadfastly returns -1 no matter what is occurring in the database.

So what is happening?? It turns out that the Nocount setting stops this information coming back. Removing the statement – or setting NoCount Off causes the ExecuteNonQuery method to behave as expected. It returns -1 if no rows affected otherwise the number of rows actually affected.

This would probably be too arcane to worry about except the SQL Server standard template for creating stored procedures includes the Set NoCount On statement. In other words – select ‘create new procedure from the SQL Server menu’ and you get this template

CREATE PROCEDURE <Procedure_Name, sysname, ProcedureName>
-- Add the parameters for the stored procedure here
<@Param1, sysname, @p1> <Datatype_For_Param1, , int> = <Default_Value_For_Param1, , 0>,
<@Param2, sysname, @p2> <Datatype_For_Param2, , int> = <Default_Value_For_Param2, , 0>
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
SELECT <@Param1, sysname, @p1>, <@Param2, sysname, @p2>
END
GO

Very lovely – except it contains the very code that disables the proc return values. Ouch.

Wednesday, 15 October 2008

Alternative HTTP Output

Websites are tricky fellows. They'll churn out HTML output all day long without any thought or consideration to other mime outputs. If you want your ASP.Net website to chuck out other response types – then use the Http Response Stream as below

For PDF
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ContentType = "application/pdf";
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=ePIMSDataExportReport.pdf");
System.Web.HttpContext.Current.Response.OutputStream.Write(bytes, 0, bytes.Length);
For Excel
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=ePIMSDataExportReport.xls");
System.Web.HttpContext.Current.Response.OutputStream.Write(bytes, 0, bytes.Length);

Thus easy to extent to other mime types such as images and video and so forth. Of course you'll need a source of bytes – e.g. from a Sql Server Report

byte[] bytes = report.Render(
"PDF", null, out mimeType, out encoding, out extension, out streamids, out warnings);

But once you have that – it’s in the pool kids and away you go.