2005 2006 2007 2008 2009 2010 2011 2015 2016 aspnet azure csharp debugging exceptions firefox javascriptajax linux llblgen powershell projects python security services silverlight training videos wcf wpf xag xhtmlcss

trycatch in .NET 2.0 - Note

Here is a comment Joe made about my previous post.

... One additional facet that will probably go (mostly) unnoticed is that you can throw exceptions across assembly boundaries, and the wrapping will occur based on the assembly-level attribute on the assembly whose catch block is being evaluated. This makes interoperability with code that isn't on the wrapping plan, e.g. COBOL or Eiffel, work seamlessly as you would expect.

...

This comment is rather hidden in how I have my page designed, but I thought it worthy of it's own posting anyhow.

WCF: A self-hosted service with multiple endpoints

Last night I started playing with more more interesting things in WCF (multiple endpoints) and I kept running into a wall: how do you set more than one http endpoint on the same service!? Nothing I was doing was working, then I ran into Indigo Girl's WCF book chapters online (see my next post). Her examples clearly explain what I was doing wrong. Let me explain how to do what I wanted to do in my own words...

Instead of having a different "server" for each endpoint of the same address scheme (i.e. http), you have a a base address for and then give each a name. There is one WSDL for all the endpoints of a service. That is: one service, one WSDL; not one endpoint, one WSDL. This stems from the fact that by default there are two endpoints repackages: mex and HTTP Get. The HTTP get one is the one that will help out with the WSDL.

Here is the fixed up code. By running this up and generating the proxy, we are able to have the complete mechanism for communication from the client to the service, including the configuration file (below).

Program.cs
Uri httpUri = new Uri("http://localhost:8081/");
using(ServiceHost hService = new ServiceHost(typeof(DemoService), httpUri)) {
 hService.AddServiceEndpoint(typeof(IDemoService), new BasicHttpBinding( ), "BasicService");
 hService.AddServiceEndpoint(typeof(IDemoService), new WSDualHttpBinding( ), "DualHttpService");

 hService.Open( );

 Console.WriteLine("Listening...");
 Console.ReadLine( );
}
client app.config

  <system.serviceModel>
    <client>
      <endpoint
        address="http://localhost:8081/BasicService"
        binding="basicHttpBinding"
        name="BasicHttpService"
        contract="IDemoService" />
      <endpoint
        address="http://localhost:8081/DualHttpService"
        binding="wsDualHttpBinding"
        name="DualHttpService"
        contract="IDemoService" />
    </client>
  </system.serviceModel>
Even when using entitely different protocols (the higher level http and say the lower level tcp), you have one WSDL. Of course in this case, since there are more one address scheme (http and net.tcp), you have more than one base address; one per scheme.
Program.cs
Uri netTcpAddress = new Uri("net.tcp://localhost:8080/");
Uri httpAddress = new Uri("http://localhost:8081/");
using (ServiceHost service = new ServiceHost(typeof(DemoService), new Uri[] { netTcpAddress, httpAddress })) {
 service.Open( );

 Console.WriteLine("Listening...");
 Console.ReadLine( );
}
server app.config

  <system.serviceModel>
    <services>
      <service type="WcfDemo.DemoService">
        <endpoint
          address="NetTcpService"
          contract="WcfDemo.IDemoService"
          binding="netTcpBinding"
          />
        <endpoint
          address="DualHttpService"
          contract="WcfDemo.IDemoService"
          binding="wsDualHttpBinding"
          />
      </service>
    </services>
  </system.serviceModel>
client app.config

  <system.serviceModel>
    <client>
      <endpoint
        address="net.tcp://localhost:8080/NetTcpService"
        binding="netTcpBinding"
        name="NetTcpService"
        contract="IDemoService" />
      <endpoint
        address="http://localhost:8081/DualHttpService"
        binding="wsDualHttpBinding"
        name="DualHttpService"
        contract="IDemoService" />
    </client>
  </system.serviceModel>

As you can see WCF really allows for some pretty powerful scenarios...

Video 4 (FWD) - "Using the Web Developer Toolbar"

One of the most powerful and appreciated extensions for Firefox is the Web Developer toolbar. This is the extension that helped convert me from an independent IEvangelist to a Firefox promoter and standards advocate. This tool puts the keys to client-side web development into the hands of the developer.

With a quick click of the mouse, the developer can now see all elements of a certain type, can disable or enable various portions of development ( i.e. JavaScript), or can view otherwise hidden form information. It's such a powerful tool that you'll never be able to do client-side web development again without it.

I do apologize for being so slow in the posting of these videos. There will be a few more in the future. These videos are from September 2005 and are for Firefox 1.0.x, but are still appropriate for Firefox 1.5.x (and Firefox 2.0)

Gosh I hate SPs/SQL (a.k.a. LLBLGen Rocks!)

...well at least in my C# code. That stuff belongs in the world of reporting, integration services, and other places which are NOT IN CODE. You couldn't get me to use ADO.NET anymore; it's such a pain for large projects. I love it for mass importing and when I do extremely dynamics such as report generation and a few other things, but for a static data access teir it's PATHETIC.

Not only is everything you type not strongly typed and therefore prone to error and has no color syntax; SQL (including SP calls) is just abrupt. You are doing this beautiful array of C# 2.0 greatness. Generic collections all over and BAM you see "select * from Person where..." Yuck!

Long live LLBLGen! If you don't know what LLBLGen is, you are completely missing out. I've been using it for months on all my projects and it's just downright awesome. It's basically LINQ...NOW. It allows you to use strongly typed .NET code to access your data WITHOUT writing any data tier code yourself. Not only that, the full blown enterprise edition is only $300. There is NO reason to ever write any data access layer yourself. It will pay for itself in about a DAY. I recommending getting a copy of LLBLGen even for your HOME projects!

All you have to do is point the LLBLGen app to the database, select the tables (and other entities) you want, and hit generate. It automatically creates a Visual Studio 2005 (or 2003 if you HAVE to use that icky thing) project for you. You can either include that project into your solution or compile the assembly and just us the compiled files. You only need to use LLBLGen again when you schema changes, which, as every architect knows...shouldn't be happening that often.

This rant is brought to you by the following sponsor...

DataSet dataSet1 = new DataSet( );
SqlDataAdapter sqlDataAdapter1 = new SqlDataAdapter( );

SqlConn1 = new SqlConnection(connString);
SqlConn1.Open( );

SqlCommData = new SqlCommand("GetDraftBox", SqlConn1);
SqlCommData.CommandType = CommandType.StoredProcedure;

sqlDataAdapter1.SelectCommand = SqlCommData;
sqlDataAdapter1.Fill(dataSet1, "MailList");

return dataSet1;
I was porting this old app from .NET 1.x to .NET 2.0 and I kept seeing stupid garbage like this. I got SO sick of it I decided to disconnect the logic tier and connect it to the LLBLGen access layer. Here's what I have now...
DraftMailCollection draftMailBox = new DraftMailCollection( );
draftMailBox.GetMulti(null);
return draftMailBox;

THAT'S IT!!! Short, sweet, strongly-typed, intellisense LOVES it, it's pretty (you gotta LOVE the VS2005 color scheme), and it's VERY easy to extend.

As another quick example here's how you would translate the following code into LLBLGEN code. First, the SQL code...

select *
from Person
where
PersonUserName = username and
PersonPassword = password;

Now the LLBLGen code...

   
PersonCollection people = new PersonCollection( );
IPredicateExpression filter = new PredicateExpression( );
filter.Add(PredicateFactory.CompareValue(PersonFieldIndex.PersonUserName, ComparisonOperator.Equal, username));
filter.AddWithAnd(PredicateFactory.CompareValue(PersonFieldIndex.PersonPassword, ComparisonOperator.Equal, password));
people.GetMulti(filter);

Yes, joining is also BEYOND easy and, yes, it databinds to GridViews with no extra work. I use it all the time in my ObjectDataSources.

OK one last example... well two. This one should be the straw that breaks...something. Look at this ADO.NET code (I'll leave some of it out though)

sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "insert into Customers (CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax )values(@CompanyName, @ContactName, @ContactTitle, @Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax)";
sqlCommand.Parameters.AddWithValue("@CompanyName", companyName);
sqlCommand.Parameters.AddWithValue("@ContactName", contactName);
sqlCommand.Parameters.AddWithValue("@ContactTitle", contactTitle);
sqlCommand.Parameters.AddWithValue("@Address", address);
sqlCommand.Parameters.AddWithValue("@City", city);
sqlCommand.Parameters.AddWithValue("@Region", region);
sqlCommand.Parameters.AddWithValue("@PostalCode", postalCode);
sqlCommand.Parameters.AddWithValue("@Country", country);
sqlCommand.Parameters.AddWithValue("@Phone", phone);
sqlCommand.Parameters.AddWithValue("@Fax", fax);

sqlConnection.Open();

string id = (string)sqlCommand.ExecuteScalar();

sqlConnection.Close();

Some would say that it would not look so bad if the insert was in an SP. Um, ok...so you want to code in more than one place? No thank you. Also, what happens if there is no id to return? I've noticed that .NET 2.0 doesn't like that too much.

Now heres the LLBLGen code...

CustomersEntity customer = CustomersEntity( );
customer.CompanyName = companyName;
customer.ContactName = contactName;
customer.ContactTitle = contactTitle;
customer.Address = address;
customer.City = city;
customer.Region = region;
customer.PostalCode = postalCode;
customer.Country = country;
customer.Phone = phone;
customer.Fax = fax;
customer.Save( );

string id = customer.CustomerId;

Yeah...wow. Not only that, but in the SQL code you also have to do all that ADO.NET stuff. Not with LLBLGen, it's all in one!

I've been using LLBLGen for almost a year now and I have to say that my productivity has SOARED because of it. LLBLGen + .NET 2.0 + Firefox is a smart, er..., GENIUS match that should not be ignored, but rather ran towards!

To get a 30-day trial copy of LLBLGen follow the below link. I'm sure you will love it and for only $300, your manager will as well.

"Common Language Runtime detected an invalid program"

If you've ever gotten this error you've probably been one of the most confused people in the world. In your debugging you may have seen that this message came from an InvalidProgramException.

Well, while this problem should be rare, here's an example harness of where you may see it.

// ThrowerHarness.cs
namespace ThrowerExample
{
  class ThrowerHarness
  {
    static void Main(string[] args)
    {
        try
        {
            Thrower.Start( );
        }
        catch (System.Exception ex)
        {
            System.Console.Write("Error: " + ex.Message);
        }
      }
    }
}

Alright, so where's it coming from?

In this case, it's actually coming from the IL.

// Thrower.il
.assembly ThrowerLib { }

.class public Thrower {
  .method static public void Start( ) {
    stloc.0
    throw
    ret
  }
}

This actually comes from invalid IL. In this case I'm putting 0 on the stack and then throwing...well, nothing really. This is not something a good compiler would create. If you see this it's probably a bug in the compiler or manually written IL.

Anyhow, to test the above do this...

ilasm /dll ThrowerLib.il
csc /r:ThrowerLib ThrowerHarness.cs

Powered by
Python / Django / Elasticsearch / Azure / Nginx / CentOS 7

Mini-icons are part of the Silk Icons set of icons at famfamfam.com