Documentation Basics 1 (motivation)

Assumption1: The software is developed by more than one person.
Assumption2: Testing is foundational to a good quality product.

Software is complicated so whenever you introduce any change it is most dificult to wrap your arms around the possible repercussions. I wholeheartedly submit to you that the quality of the product is directly proportional to how much you can put your arms around the possible repercussions of making a change. Understanding the relationships between components leads to more complete testing and to a better product. This is the thrust behind documentation.

An example: You have five components, A, B, C, D, & E. Two people do their best to put their arms around these components (understand their relationship to one another) and they come up with two separate understandings.

1)
A affects B
E affects A

2)
A affects B and D
B affects C
E affects A

Consequently, when I introduce a change to A, each person will proceed to test differently, based on their understanding. Here are the tests performed by each person.

1)
test A
test B

2)
test A
test B
test D
test C

If we assume that each test catches one bug, and if we define quality by how many bugs are found in the resulting product, then we can see that the product produced by the second person has twice the quality as the product produced by the first person.

By the example above we can see that our understanding of how components relate to one another directly leads to the quality of our product. If the first person is given the task of testing the software, then only two tests will be performed. If the second person is given the task of testing the software, then four tests will be performed. This happens because their understanding varies. Hence, the quality of the product will vary.

When the understanding is limited to what is in the individual's brains, you cannot do anything but accept the quality variations. How can we solve the problem of varying quality? We can do this by sharing the level of understanding. Practically, sharing understanding is carried out through documentation. What is documented and available to all is what is understood.

Below are two documentation scenarios.

Scenario 1:

1) Learns the product and documents centrally that
A affects B
E affects A

1) performs tests
test A
test B

Software has 40% quality.

2) Learns the product from 1's documentation and adds to it. The document now becomes
A affects B and D
B affects C
E affects A

2) performs tests
test A
test B
test D
test C

Software has 80% quality.

1) Learns the product some more from existing documentation and adds to the documentation.
A affects B and D and F
B affects C
E affects A

1) performs tests
test A
test B
test D
test C
test F

Software has 100% quality.

Scenario 2:

2) Learns the product and documents centrally that
A affects B and D
B affects C
E affects A

2) performs tests
test A
test B
test D
test C

Software has 80% quality.

1) Learns the product from 2's documentation and adds to it. The document now becomes.
A affects B and D and F
B affects C
E affects A

1) performs tests
test A
test B
test D
test C
test F

Software has 100% quality.


The point here is that no matter what the scenario is, the quality of the software will increase with the increase of documentation (or shared understanding). At first, it may seem that sharing the level of understanding will not help the quality (this is true in the first step). However, as the sharing (documenting) continues, quality can only increase.

Ignoring documentation will lead to software of poor quality (at worst) or to software with varying quality (at best). Developers who document what they learn and share the documentation can only help an organization to produce a higher quality product.

with 0 Comments

SQL Interview Question

-- Sample: A table of Employees with their ID, Name,
-- and Manager ID(which is itself the ID of one of the employees).

declare @Employee table (ID int NOT NULL, Name varchar(30), MID int NULL)
insert @Employee values(20, 'Wei', 22)
insert @Employee values(21, 'Brad', 22)
insert @Employee values(22, 'Jeremy', NULL)
insert @Employee values(23, 'Daniel', 22)

SELECT * from @Employee

-- How do you get a list of Managers with their employees?

SELECT Managers.Name, Employees.Name
from @Employee Employees
inner join @Employee Managers
on Employees.MID = Managers.ID

A few years ago when I was asked this question , I didn't know the answer but I said, "some sort of self-join". That was good enough for my interviewer.

with 1 Comments

Backup GoDaddy DotNetNuke database

GoDaddy is one of the cheapest ASP.NET hosts. They have DNN preinstalled for you if you want it. They make it nearly impossible to access the DNN database through their control panel, though, so backup is very hard. 

C A U T I O N: The following advice is too powerful. You can break DNN or delete or corrupt data if you're not careful. By reading this post and/or using its advice, you agree to NOT hold Daniel Acevedo or DotNetJunkies responsible in any way for any changes, damages, or loss incurred.

1) To achieve a backup, you can login to your portal as host
username: host
password: [same as admin pwd]

2) Then, from the host tab, select SQL. Copy something like the following:

select dnn_Tabs.TabName, m.Moduletitle, t.DesktopHtml, dnn_Tabs.TabID, m.ModuleID
from dnn_HtmlText t
inner join dnn_Modules m
on t.ModuleID = m.ModuleID
inner join dnn_TabModules tm
on m.ModuleID = tm.ModuleID
inner join dnn_Tabs
on tm.TabID = dnn_Tabs.TabID
where m.ModuleDefID = 100
order by 1, 2

3) Then click "Execute"

4) Finally, copy the results that appear on the web page to Excel or whatever you want and save it somewhere. You've now got a rough backkup of your website. (only the contents of the Text/HTML modules - for now)

You can explore the DNN database and write up your own SQL scripts to get the data you want (AT YOUR OWN RISK). Here's another helpful SQL script to get you started:

select name from sysobjects where type = 'U'
and name like 'dnn%'
order by 1

with 0 Comments

SQL Cursor Quick Reference, and coffee

The SQL Team has this excellent cursor quick reference. It is in plain english and straightforward:

http://www.sqlteam.com/item.asp?ItemID=553

I don't think I've ever learned this much about cursors in just one minute of reading (I also drank coffee for the first time in a year this morning--that was delicious CAFE SELLO ROJO from Colombia. Boy, it really speeds me up in everything I do)!

with 0 Comments

SQL Server 2005: INSERT INTO from a stored procedure

You could NOT do this with SQL server 2000.
You were only able to assign to a simple variable from a stored procedure that returned an output parameter or a single column.

With 2005, you CAN now do the following:
INSERT INTO @MyTableVariable EXEC myStoredProcedure

Thanks to R. Aaron Zupancic for his "coolness" blog post.

 

 


with 2 Comments

C#.NET: InvalidCastException: Specified cast is not valid

I needed to populate a textbox on a web page with a value from the database but I was getting an error.
InvalidCastException: Specified cast is not valid

The following line returns the error:
return (string)ds.Tables[0].Rows[0]["Adjustment"];

This is because the type of Adjustment in SQL Server is decimal(7,2).  The following line first converts the
value to a .NET Double and then to a String.
return Convert.ToDouble(ds.Tables[0].Rows[0]["Adjustment"]).ToString() ;

 That fixed the problem!

with 4 Comments

Reporting Services Line Break in a Textbox

vbCrLf

Example (The following expression returns two fields, each on a separate line in the same text box):

=Fields!FirstName.Value & vbCrLf & Fields!LastName.Value

This example is found in: Expression Examples in Reporting Services, an excellent article with many examples to use as a reference.

with 4 Comments

ASP.NET: programmatically save file to network shared folder

Albeit with unmanaged code...
By default, the account under which your asp.net application runs is a local account on the machine running your application. You could create a domain account with the same login and password and then give that account permission to read and write on the network folder.  If that is not the solution you want, create an account like the one below on the domain with minimal priveledges and give it access to read and write on the network folder. Then use the following code-behind to programmatically impersonate and save onto that folder.

Assume the following:
account login: foo
account passw: bar
domain: mydomain

using System;
...

using System.Security.Principal;
using System.Runtime.InteropServices;

namespace testapp
{

public class WebForm2 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;
 protected System.Web.UI.WebControls.Label Label1;
 protected System.Web.UI.WebControls.Label lbShow;
 
 [DllImport("advapi32.dll", SetLastError=true)]

 public static extern bool LogonUser(String lpszUsername, String
lpszDomain, String lpszPassword, int dwLogonType, int
dwLogonProvider, ref IntPtr phToken);

 [DllImport("kernel32.dll",
CharSet=System.Runtime.InteropServices.CharSet.Auto)]
 
private unsafe static extern int FormatMessage(int dwFlags, ref
IntPtr lpSource, int dwMessageId, int dwLanguageId, ref
String lpBuffer, int nSize, IntPtr *Arguments);

 [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
 
public extern static bool CloseHandle(IntPtr handle);

 [DllImport("advapi32.dll", CharSet=CharSet.Auto,
SetLastError=true)]
 
public extern static bool DuplicateToken(IntPtr
ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref
IntPtr DuplicateTokenHandle);

 private void Page_Load(object sender, System.EventArgs e)
 { 
 ...
 }

private string SaveRequest(string filename)
{
  IntPtr tokenHandle = new IntPtr(0);
 
  const int LOGON32_PROVIDER_DEFAULT = 0;
  //This parameter causes LogonUser to create a primary
token.
  const int LOGON32_LOGON_INTERACTIVE = 2;
   tokenHandle = IntPtr.Zero;

  // Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser("foo", "mydomain", "bar",
   LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
   ref tokenHandle);
 
  WindowsIdentity newId = new WindowsIdentity(tokenHandle);
WindowsImpersonationContext impersonatedUser =
newId.Impersonate();
   
  Request.SaveAs(filename, true);
 
  impersonatedUser.Undo();
   
  return “success”;
}

private void Button1_Click(object sender, System.EventArgs e)
{
string message = SaveRequest("\\\\comp\\folder\\
request.txt");
  Label1.Text = message;
}
}

I think the best way to implement this is to throw all the extra interop code into its own class (UserImpersonate) which implements the IDisposable interface and simply use the class.
So that it's something like this:

using ( new UserImpersonate ( "foo", "mydomain", "bar" ) )
{
 Request.SaveAs(filename, true);
}

references:

with 6 Comments

Windows Mobile 5 Programming

Speaking of Windows Mobile 5 and the T-Mobile MDA, Microsoft has made available much help for developers and hobbyests to dive into programming for the new platform.

And...

I'm having a hard time finding the MDA in Salt Lake City. I'm probably going to have to go to Chicago to upgrade from my Nokia 3650 to the MDA. In the meantime, I'll enjoy the 3650.

with 1 Comments

Reporting Services Web Services Authentication in C#

The Web Services API that allows you to programmatically connect to a report server requires authentication.

Here's how I generally do it in C#:
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

The ins and outs of getting authenticated by the Report Server are explained in this great article.

with 0 Comments

Reporting Services Therapy: Index was out of range

I got this strange error when exporting to Excel from the designer or from the Report Manager:
"Index was out of range. Must be non-negative and less than the size of the collection."

After pulling my hair out for a while, and after Googling the problem, I found a couple of solutions, (1) Worked for me - it came from my Salt Lake City coworker:

(1) One Detail Cell in my table contained a number like #.#########. Aparently this freaked out Excel. I converted it to a string like this:
=Convert.ToString(Format((ReportItems!ValueOne.Value / ReportItems!ValueTwo.Value), "#.#########"))

(2) As per this blog, disabling the Document Map Labels has the same effect and cures the problem.

with 1 Comments

ASP.NET Therapy: Super Concise Demos

These How do I videos are brought to you by the Microsoft ASP.NET Developer Center.

Common Tasks Covered:

  1. Data Access - I recommend this one!
  2. Form Building for a "Contact Us" Page
  3. Master Pages and Site Navigation
  4. Membership and Roles
  5. Profiles and Themes
  6. Create a Full-Featured Customer Login Portal
  7. Caching (Part 1)
  8. Caching (Part 2)
  9. Web Parts and Personalization
  10. Localization
  11. Tips and Tricks

These demos are also a Featured News item on www.asp.net.

with 1 Comments

T-Mobile MDA - a great phone for .NET apps.

Out today!
It's out today! If you go to T-Mobile's website, Go to Phones. Then select the Tab labeled Handhelds and Sidekick. I check the site every day and today I checked it again. The MDA did not show up until I refreshed the browser.

It'll cost me $349.99 to upgrade to this phone with a two-year extension and no rebates. New subscribers have to pay $399 and wait for their $50 rebate.

Why I'm so interested in the T-Mobile MDA
I've been waiting for this Windows Mobile 5 Phone to come out, and now it has! I can't wait to start developing apps for this phone with Visual Studio 2005. I can use the .NET compact framework!  My wife already has a Dell Axim X50 and I jut don't want to carry two devices so I was waiting for the best PDA-Phone for the price, the T-Mobile MDA.

I hear that a 300 Mhz version of the MDA will be out in the summer, but I don't think I'll wait. Mainly because I won't be using Skype and because I can monitor my open apps and performance and keep it finely tuned.

with 2 Comments

SQL Therapy: SQL Server 2005 Installation problem

I tried installing SQL Server 2005 With the Windows XP Administrator account. At the begining of the installation I got an error that would not let me continue:
Could not find ASPNET account. (summarized)

I had previously installed Visual Web Developer, SQL Server Express, and Visual Studio 2005.
The next thing I did was realize that I didn't have IIS installed. I installed IIS and tried to install SQL 2005 again to no avail.

Then I uninstalled the following:
SQL Server Express,
All SQL Server associated applications
Visual Studio 2005
VWD
.NET 2.0 Framework

Then I installed VS 2005 which did the trick and allowed me to install SQL Server 2005. (I did not install VWD this time). I believe that the culprit was my not having installing IIS before everything else. That step is crucial!

with 0 Comments

ASP.NET Therapy: Salt Lake City ASP.NET 2.0 training Report

(Note: There were about 8 inches of snow on my driveway this morning. I had a little back ache after shoveling but after doing a few McKenzie exercises, I'm all better. Thanks Irene!)

ASP.NET 2.0 Training Report Scott Golightly taught a class on ASP.NET 2.0 in the Microsoft offices in Salt Lake City on February 14 & 15. I went and got the best ASP.NET 2.0 therapy that I've ever gotten. One word to describe my overall experience: Equipping.

More than Gleenings:

  1. Dynamic Profile Properties. I can throw these into the web.config file and they're stored and available for my use with zero code!
  2. SQL 2005 Auto-Notification versus 2000's polling. I now understand and appreciate this much more! (insight: Can I use this to build a tool that notifies team members when stored procedures are edited? Is there something out there that does this already?)
  3. Custom Cache Dependencies. Because the Cache Dependency class is no longer sealed, What could have been rocket science to some, is now easy to implement. I can think of many uses for this.
  4. And, although Master pages fail to excite me too much, I still learned alot about them. One limitation I found (correct me if I'm wrong) is that you cannot go into design mode in Visual Studio when using nested Master pages.
  5. I really like being able to "View in Browser" from Visual Studio without compiling the entire project. In fact, I can open a single aspx file, make changes to it, and "View in Browser". .NET 2.0 takes care of JIT compiling other necessary files.

I received three great books at the training:

  1. Introducing ASP.NET 2.0 (I found one minor inconsistency: The attributes in the @Page Directive that control code-beside don't work as explained in the book. This may be due to a difference between ASP.NET 2.0 Beta and final release. The consequence of this is that the code in the ASPX file and its .CS counterpart don't gel perfectly as partial classes. Private members are not shared.)
  2. The official course book (contains all slides, demos, exercises, and code snippets presented in the training).
  3. Application Architecture for .NET (I already have this book. It is excellent for enterprise-level developers)
with 0 Comments

Reporting Services Therapy: Date Format

I recently revisited date formatting in Reporting Services. The two most common date formats I use are:

formatting result
=Format(Fields!PurchaseDate.Value, “MM/dd/yyyy”) 05/4/2005
=Format(Fields!PurchaseDate.Value, “MMMM d, yyyy”) May 4, 2005

The Reporting Services Textbox Properties windows offers a few prebuilt Date formats, but if you need more formats than that... Here's a great resource for User-Defined Date/Time Formats on MSDN.

with 1 Comments

Reporting Services Therapy: divide by zero = #Error

Problem:
I had some code like this: IIF(value <> 0, 1/value, 0) and it produced #Error.

Solution:
I read Derek Adkins blog and came up with this nifty work-around (which I also posted there):

1) put the division in a HIDDEN textbox named Div
2) keep the following logic where you want the results displayed:

=IIF(value <> 0, ReportItems!Div.Value, 0)

with 2 Comments

Visual Studio Therapy: MSDN Best of Launch

I went to the MSDN Best of Launch event in Salt Lake City and got my free software.
The speaker did a great job of showing off 2005's features. He spoke really fast and was able to get alot in. I appreciated that very much because I was only there for 2 hours.

  • The first session was mostly about ASP.NET 2.0
  • The second session was mostly on Click Once.
  • I didn't stay for the 3rd session (I heard it was on Team System)

I asked a question about Click Once:
(Q: what is required of the server, A: IIS).

In the end, I'm very happy to have gone.

with 1 Comments

Visual Studio Therapy: Intellisense in Visual Web Developer (Correction)

I had previously reported that the day I installed VWD I had no intellisense available. I honestly don't know what fixed it, but that only happened to me the first day. Perhaps it was a matter of saving the files before I began to get intellisense. I really enjoy getting intellisense everywhere now. I use it esepecially when writing CSS. Along with Photoshop, VWD is my tool of choice for working on my wife's Physical Therapy Website: CoreRehabCenter.Com. Any feedback on that site's design is much appreciated. I plan to upgrade my Web hosting service, and use ASP.NET too.

Thank you God for such a great product. And thank you God that Microsoft gives it away for free.

In a coming post, I'll comment on the MSDN Best of Launch event that I went to in Salt Lake City.

Reporting Services Therapy: Visibility of group Header

How to conditionally hide group header based on number of detail rows:

  1. Select the entire row that contains the Group Header.
  2. In the Visibility-Hidden Property enter the expression:

=IIF(Count(Fields!ItemNumber.Value) > 0, False, True)

What is happening here:
In this case, I want to display the group header only if the group has detail rows. A group header can display aggregate information about itself. Since I can enter an expression for the visibility of a row, I can change it's visibility based on the Count of Items in the group. I chose to count on the ItemNumber field, but you can use your own field.

Note: If the detail row is itself grouped, this count will not work.

with 0 Comments