Rob Kraft's Software Development Blog

Software Development Insights

Archive for the ‘Visual Studio 2005’ Category

The Correct Way to Re-Throw An Exception – .Net Tip

Posted by robkraft on March 6, 2013

When catching and re-throwing an exception, you should include the original exception as a 2nd parameter.  Including the original exception may provide a deeper stack trace that will assist you with solving the exception.

This syntax may not include the full stack trace.

This syntax may not include the full stack trace.

In the code above, if an error occurs in methodWithoutCatch(), the call stack returned will show “methodWithTryCatch” as the deepest method in the stack.

System.Exception: Additional Error Info: blah blahObject reference not set to an instance of an object.
at WindowsFormsApplication6.Form1.methodWithTryCatch(String y) in ...\Form1.cs:line 34 at WindowsFormsApplication6.Form1.button1_Click
This example will include the full call stack.

This example will include the full call stack.

However, if you include the original exception in the throw as shown in the second throw example, then the call stack returned will show “methodWithoutCatch” as the deepest method in the stack.

System.Exception: Additional Error Info: blah blahObject reference not set to an instance of an object.
---> System.NullReferenceException: Object reference not set to an instance of an object.
at WindowsFormsApplication6.Form1.methodWithoutCatch(String z) in ...\Form1.cs:line 40
at WindowsFormsApplication6.Form1.methodWithTryCatch(String y) in ...\Form1.cs:line 29
--- End of inner exception stack trace ---
at WindowsFormsApplication6.Form1.methodWithTryCatch(String y) in ...\Form1.cs:line 35
at WindowsFormsApplication6.Form1.button1_Click

Including the original exception as the second parameter of your new exception provides you with a better call stack.  In this example, it allows you to determine that the error occurred in the methodWithoutCatch method.  In the first case, you are left wondering if the methodWithTryCatch really caused the error, or if one of the three methods it called (method1, methodWithoutCatch, or method3) caused the error.

Advertisements

Posted in Code Design, Visual Studio 2005, Visual Studio 2008, Visual Studio 2010 | 1 Comment »

Fiddler DOES work on your local/cassini/webdevserver/Visual Studio sites

Posted by robkraft on April 7, 2010

If you want to use Fiddler to monitor against the web traffic on your localhost when running in Visual Studio, change your URL to start with ipv4.fiddler: 

http://ipv4.fiddler:2296/Default.aspx

instead of

http://localhost:2296/Default.aspx

Posted in Visual Studio 2005, Visual Studio 2008 | 2 Comments »

Run the same C# program in a Console or a Windows Form

Posted by robkraft on March 9, 2010

I’ve seen a few complicated solutions for writing a C# application to run as both a console application and a windows application, but I’d like to share a simpler example.

  1. Create a new project by selecting a C# “Windows Forms Application”.  This will add references to the project and some starter code necessary for displaying the windows part of your program.
  2. Choose the “Application” tab from your project properties, and set the “Output type” equal to “Console Application”.  This will cause your program to start out running as a console app.
  3. The program I am creating here is a shell to allow you to call the same logic (perhaps generate the SQL Script for a table) and send the script out to the console or have it display in a text box on a form.
  4. Change the Main method in Program.cs to accept the command line arguments as input:
  5.  

[STAThread]
static void Main(string[] commandLineArgs
{
    if (commandLineArgs.Length > 0) //then we have command line args
    {
        Console1.ProcessCommandLineArgs(commandLineArgs);
    }
    else
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

5. For this example, I created 2 classes in addition to Form1 which was created for me.  I created a class called MyScripter.cs, which has all the code to “do the work”.  And I created Console1.cs.  I will have code in both Console1.cs and in Form1.cs that can call MyScripter.cs.  Here is the simple console class:

public class Console1
{
    public static void ProcessCommandLineArgs(string[] commandLineArgs)
    {
        MyScripter scripter = new MyScripter();
        foreach (string tablename in commandLineArgs)
        {
            string output = scripter.ScriptMyTable(tablename);
            Console.WriteLine(output);
        }
    }
}

6. I added two text boxes and a button to Form1.cs along with this event:

private void buttonScript_Click(object sender, EventArgs e)
{
    MyScripter scripter = new MyScripter();
    textBox2.Text = scripter.ScriptMyTable(textBox1.Text);
}

7. Finally, an example of the shell MyScripter.cs, which is where the real work is done:

public class MyScripter
{
    public string ScriptMyTable(string tablename)
    {
        string scriptIGenerate = "This is the script of my table named: " + tablename;
        return scriptIGenerate;
    }
}

8. You can now run this compiled program from a command prompt. If you pass in a command line argument, the program will use that as input to generate output to the console. If no command line argument is provided, the application will display the form you created.

Posted in Code Design, Visual Studio 2005, Visual Studio 2008 | Tagged: , , | Leave a Comment »

How to create a Password column using the DataGridView

Posted by robkraft on December 19, 2008

If you want to hide the password value in a Visual Studio DataGridView control, you can use the code below.  If a user clicks into the cell to edit the value, then the current value becomes visible.
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (
dataGridView1.Columns[e.ColumnIndex].Name == “passwordDataGridViewTextBoxColumn” && e.Value != null)
    {
       
dataGridView1.Rows[e.RowIndex].Tag = e.Value;
        e.Value = new String(
‘*’, e.Value.ToString().Length);
    }
}

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    if (
dataGridView1.CurrentRow.Tag != null)
        e.Control.Text =
dataGridView1.CurrentRow.Tag.ToString();
}

I found the example above on this web page, in a non-english language:

Posted in Visual Studio 2005, Visual Studio 2008 | Tagged: , | 2 Comments »

How to access the internal methods of another DLL (and compile it all with nant)

Posted by robkraft on December 26, 2007

C# provides a lot of scoping options for classes, methods, and properties.  However, one scoping option that you may think is missing is the ability to allow a DLL to reference an internally scoped method that resides in another DLL.

Why would I want to do this?

Q.      Why would you want to reference an internal method in another DLL?  Didn’t the author of the DLL scope it internal specifically to prevent such access?

A.  The answer is “Yes”, but sometimes, the author of LOWLEVEL.DLL and the author of HIGHLEVEL.DLL are the same person or on the same team and they trust each other.

Q.  So why not just scope the method as public in LOWLEVEL.DLL?

A.  The reason is that you don’t want 3rd party programmers to access the method directly; but you do want your own DLLS to be able to access them.

When would I want to do this?

There are 2 scenarios where this is common:

One scenario is that you have a method in LOWLEVEL.DLL that runs an SQL query in the database.  The method is generic and could be used by several HIGHLEVEL.DLLs, but you don’t want to make the method public because you don’t want 3rd party programmers to run SQL, you want 3rd party programmers to go through your HIGHLEVEL.DLLs that check permissions and syntax before calling the base LOWLEVEL.DLL to run the query.

Another scenario where you want to call internal methods in other DLLs is when you want to write unit tests to test those internal methods, and you don’t want to include your unit test assembly in the same solution as the DLL you are testing.

How do I do this?

To call an internal method in another DLL you must:

  1. Strong name both DLLs
  2. Update Assembly.info of the LOWLEVEL.DLL to allow the specific HIGHLEVEL.DLL access to internal methods

Strong Naming DLLs

You can think of strong-naming as a way to make your DLL globally unique.  You want to use a strong name when allowing access to internal methods; otherwise, 3rd party programmers could simply name their DLL to the simple name that your LOWLEVEL.DLL allows.

A number of articles provide information for strong naming DLLs, such as this one: http://msdn.microsoft.com/msdnmag/issues/06/07/CLRInsideOut/default.aspx, or this one: http://msdn2.microsoft.com/en-us/library/xwb8f617(VS.80).aspx

Identifying the DLLs to allow access

You must add an entry in the AssemblyInfo.cs file of the LOWLEVEL.DLL (the DLL that has the internal method to be accessed by another DLL) in order to identify the HIGHLEVEL.DLL that is allowed to access internal methods.  You do this with the InternalsVisibleToAttribute attribute (aka InternalsVisibleTo).  Unfortunately, as I researched this I found many examples that were not exactly accurate.

This example will work:

[assembly: InternalsVisibleToAttribute(@”HighLevel, PublicKey=0024000004800000940000000602000000240000…BigLongValue…”)]

  • You must include the CompilerServices namespace in AssemblyInfo.cs:
    • using System.Runtime.CompilerServices;
  • You must use the long form of your public key name.  You can obtain the long name of the public key by running the sn tool at the command prompt:
    • sn –Tp HIGHLEVEL.DLL
  • You must use InternalsVisibleToAttribute (not InternalsVisibleTo)

Compile both DLLs with their strong names.  Then, recompile the LOWLEVEL.DLL with the above attribute, and the HIGHLEVEL.DLL should be able to access internal methods of the LOWLEVEL.DLL.

One step further:

For those of you using NANT to automatically create your AssemblyInfo.cs files, you need to do three things:

  1. Add the CompilerServices namespace,
  2. Add the InternalsVisibleToAttribute attribute as shown below
  3. Include the keyfile on the csc task when building the dll.

     <asminfo output=”Properties/AssemblyInfo.cs” language=”CSharp”>

     <imports>       

       <import namespace=”System” />    

       <import namespace=”System.Reflection” />        

       <import namespace=”System.Runtime.InteropServices” />

         <import namespace=”System.Runtime.CompilerServices” />

   </imports>

<attributes>       

     <attribute type=”ComVisibleAttribute” value=”false” />

     <attribute type=”CLSCompliantAttribute” value=”true” />

      <attribute type=”InternalsVisibleToAttribute” value=”HighLevel, PublicKey=002400000480000094000…BigLongValue…” />

</attributes>

</asminfo> 

<csc target=”library”  platform=”x86″ warnaserror=”true” output=”${build.dir}/bin/${project.name}.dll” keyfile=”mykey.snk“>  

Posted in Visual Studio 2005 | Leave a Comment »