Friday, February 03, 2006

For as long as I've been using outlook, I have always clicked on the "new message" icon to create a message.

I just accidentally double clicked on a whitespace below my message list in unread mail (where I have a red circle and yes I did that with a mouse, not on a tablet) and voila!! A new email message window opened up. Man, this is going to help me be even lazier. I won't have to move the  mouse all the way up into that corner any more!

It works when you are at the bottom of any view that lists emails. Of course, most of my email folders are bottomless pits of endless emails, but at least the unread mail looks minimal when I have the groups closed.



Don't Forget: www.acehaid.org
Friday, February 03, 2006 3:16:10 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Did you know that there are 40 command line utitiles in .NET? [read more ...]

[A DevLife post]



Don't Forget: www.acehaid.org
Friday, February 03, 2006 9:08:20 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Thursday, February 02, 2006

I saw this question in the newgroups and wanted to blog about it because it is a real gotcha that gotme too when I first started working with WSE 3.0.

If you set the WSE 3.0 diagnostics tab to output trace files, you can get a look at the messages going out of and coming into your client as well as going out of and coming into your webservice.

Tip #1 Remember to turn OFF this tracing when you send your client app or web service into production. Left to it's own devices, the trace files will grow and grow and grow and one day you will be wondering why your web service is acting so slowly. That's because of the effort of opening up a 60MB file to add some text to the bottom of it!

Tip #2 The default file names are TraceInput.webinfo and TraceOutput.webinfo. Those extensions suck because you can't open them up in anything easily. I always change them to TraceInput.webinfo.xml and TraceOutput.webinfo.xml. Then I can double click on them and open them up in something like I.E. or an even more intelligent angle bracket reader. (Note:Nathan (a tester on the WSE team) makes a good point about this. If you forget to do #1, then #2 could very easily expose some super critical data for hackers on your production server! So you might be better off without this particular little trick of mine.)

Tip #3: Reading the trace files, remember that there is more than the header and body of the message in there. There is also processing info. That means that in an output file, the first thing you will see is the unprocessed message. Your app has created the message, but it hasn't been through WSE yet to get all it's protection before it's sent out on the wire. This is very confusing and can even be a little frightening because if you have encrypted your message, the first thing you see is a message body with clear text! Notice,though, that it is surrounded by tags that say <processingStep description="Unprocessed Message">. Now at the bottom of that <outputMessage> and you will see the <processingStep description="Processed message">. That is the message that is going out on the wire and hopefully looks more like what you expected.

On the incoming message, the first thing in the door (again the Unprocessed Message) is what just came in off the wire. So that is the real soap message and should display all of the properties you expected - encryption and any thing else you demanded of the message. Then you can read through the processing steps and the last step has the fully processed message that is about to get passed to your application. All of the security goo is gone and you will see clear text again, even when the actual message was totally secured.

Tip #4: If you want to see only the soap that went over the wire, bag the built in tracing and use Mike Taulty's sweet little WSE 3.0 Tracing Tool.

Tip #5: For even more detailed inspection and diagnostics of your web service messages, check out Mindreef's SoapScope.



Don't Forget: www.acehaid.org
WSE
Thursday, February 02, 2006 10:17:18 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Three years ago I did a presentation at Vermont.NET on Architecting Applications with Web Services. (Proof is at the past events page - check Feb 2003!) 

I clearly remember the question of overloaded web methods coming up in that session. I didn't know the answer so I tried it right then and there and it didn't work. Someone mentioned there was a way to get around it and we found that solution another day.

It's still a question for a lot of people who are coming to Web Services as OO programmers (which Visual Studio lets us do) and that is because many are unfamiliar with the attributes that can be used for web services. Or they see them but have no idea what they are there for.

Thom Robbins recently had someone ask the same question and blogged how to use attributes to enable overloading when defining web methods in Visual Studio.NET.

Three years ago, it seemed like a good idea to me. I didn't really grokWeb Services. I was just using them as a means to an end and I knew OO programming, not messaging.

However, now my perception has changed and it's important to note (as Thom does (thanks Thom!)) that just because you can do it, doesn't mean it's a good thing. It's the OO way, for sure, but it just does not jibe with messaging and contracts and it does not conform to WSI Basic profile which demands unique names for operations (web methods). So if you have any intentions of going outside of .NET with your messaging, don't do it. A contract needs to be clearly defined and by providing overloads, that just blows the contract away.

If you are writing what the plumbers call "silo" apps, .NET all the way through and you are controlling the client and the service, there's no harm outside of the damage you are doing to your brain. Still, it's important for the WSDL that represents your web service identifies does not identify itself as conforming to WSI Basic profile. When you create a new web service in VS2005, by default, the service has attributes that claim to conform to the Basic Profile. Thom includes the caveat in there to set the services' conformance claims to "none".

Here's what a .Net web service class that shows what Conformance Claims  looks like. ConformsTo is the claim. Emit embeds the claim in the wsdl.

<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1, EmitConformanceClaims:=True)> _
<WebService(
)> _
Public Class
ShowConformance
  <WebMethod> _
  Public Function HelloWorld() As
String
   Return
"Hello"
  End Function
End Class

If you look at the wsdl (eg http:\\localhost\myservice.asmx?wsdl) you can see that claim. Here is the appropriate section of the wsdl.

- <wsdl:binding name="ServiceSoap" type="tns:ServiceSoap">
- <wsdl:documentation>
  <wsi:Claim conformsTo="http://ws-i.org/profiles/basic/1.1" xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/" />
  </wsdl:documentation>
  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="HelloWorld">

When you explicitly define that the service does NOT conform, there is no claim in the WSDL that says "I do not conform". In that case, no claim is made at all.

So by marking your service with

ConformsTo:=WsiProfiles.None

even if you have EmitConformanceClaims set to true, there will be no wsi:Claim in the wsdl.

If you forget to remove the conformance claims, you will get a big fat error message when you try to call the asmx.

Service 'Service' does not conform to WS-I Basic Profile v1.1. Please examine each of the normative statement violations below.

and the detail tells you:

To make service conformant please make sure that all web methods belonging to the same binding have unique names.

The more you start understanding these things today, the more prepared you will be for WCF.



Don't Forget: www.acehaid.org
WSE
Thursday, February 02, 2006 12:29:55 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
I noticed an ad in the current edition of 7 Days classifieds for someone who is looking for a C++ tutor. Look under Professional Services/Services Wanted.

Don't Forget: www.acehaid.org
Thursday, February 02, 2006 9:34:23 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Tuesday, January 31, 2006

I have a web service that I wrote for one of my smart client apps to check for one of three states of connectivity: no network, local network connection to web server, web connection to the web server.

So I ping the web service at the local i.p. The operation returns a mystical "hello world". If that times out, then I ping the service at the i.p. of the web server as it is exposed to the web via ISA Server. If that times out as well, then they are told (politely of course) that they are S.O.L. and need some type of network access to run these particular functions.

I have a client side assembly dedicated to this as well as the web service.

Now Visual Basic .NET 2.0 has My.Computer.Network.Ping to which you pass a URI and a timeout period. There is one small code benefit to me as I have to dynamically construct the web service URL and using the new method, I can just ping the i.p. and not care about a complete path to the web service. However, the Network.Ping method requires a bunch of permission that I don't need in order to hit the web service. So I think that for now, I'll leave it alone and wokr on other things for my migration.



Don't Forget: www.acehaid.org
Tuesday, January 31, 2006 10:33:46 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Pondering about being a user of development tools vs. being an inventor of these same tools... [read more...]

[A DevLife post]



Don't Forget: www.acehaid.org
Tuesday, January 31, 2006 5:38:16 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Well, it seems really official now. GE purchased Burlington based IDX in 2005 for $1.2 billion. Today I got an email from someone at IDX asking me to update his email address from @idx.com to @ge.com!

That's going to take some getting used to.



Don't Forget: www.acehaid.org
Tuesday, January 31, 2006 1:49:10 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Writing a conclusion or summary at the end of an article is hard work. In addition to it being deflating after the fun of hashing over lots of ideas, you have to be careful to avoid cliches like "powerful features".

Do you even read that last paragraph of a technical article? Does it help you get closure or is it just a dangling preposition, so to speak?



Don't Forget: www.acehaid.org
Tuesday, January 31, 2006 10:47:05 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

As I begin deploying new apps at my client site,  we made a discovery that we were easily able to correct.

After installing a .NET 2.0 app that uses Crystal Reports, we were unable to run Crystal Reports from our .NET 1.1 applications. We got an error indicating that it could not find the CrystalReports.Engine assembly.

The short story is that reinstalling CR .NET 1.1 after CR.NET 2.0 fixes the problem.

For the more curious, I did a little more exploration. I uninstalled the CR for .NET 2.0 but whatever it had stomped on did not fix itself and the 1.1 reports still did not work.

Then I reinstalled 1.1 which worked again and then 2.0 on top of it which again broke 1.1. (Just verifying that this was the direct cause.)

Lastly, we installed CR.NET 1.1 after CR.NET 2.0 and then all of the reporting works fine.



Don't Forget: www.acehaid.org
Tuesday, January 31, 2006 8:36:55 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Monday, January 30, 2006

Well, not quite Paris, but how about the beautiful locale of Nice France?

This year, DevConnections is expanding it's venues to Europe with it's first conference in Nice form April 24 - 27th.

Many of the speakers that you are used to seeing at DevConnections in the U.S. will be there.

I won't be there, but will be doing four sessions at DevConnections in Orlando April 2- 6th.

See you in Orlando!

 



Don't Forget: www.acehaid.org
Monday, January 30, 2006 10:22:14 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Sunday, January 29, 2006
Filing all of the payroll and other tax paperwork. Not just paying the taxes, but getting all of the paperwork done for federal and state every quarter (if you are small like me, monthly if you are a big company) and the year end stuff. Hooray for accountants. I just got an envelope filled with forms all filled out, the envelopes already to go and a list of checks to write. Then slap the stamps on and off they go. This is not the biggie - doing the corporate return quite yet as I still have a lot of review to do before I send her all of that paperwork.

Don't Forget: www.acehaid.org
Sunday, January 29, 2006 3:25:18 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

There's a cool new .net 2.0 feature I didn't know about until I needed to do this a few days ago. If your application has FullTrust, you can use the System.Data.Sql.SqlDataSourceEnumerator to get a list of available SQL servers (2000 and 2005 only). The query returns a DataTable which you can just attach to a combobox or drop down list.

 Dim instance As SqlDataSourceEnumerator =      SqlDataSourceEnumerator.Instance
 Dim dt As DataTable = instance.GetDataSources()

Remember, though, this requires the assembly to have full trust. There is not a specific permission you can apply to use this otherwise.



Don't Forget: www.acehaid.org
Sunday, January 29, 2006 1:50:05 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

I'm experimenting with a simple .NET 2.0 WinForms application and ClickOnce and still, as is my destiny, banging my head on the wall.

My latest frustration (while trying to use all of the built-in automated functionality) is trying to limit who has access to the downloads.

For a particular application, we only want it to run in-house on the intranet, yet our webserver is exposed to the www. Windows Authentication sounds like a good solution, but it doesn't work if you are trying to deploy requirements in addition to the main application.

If I have the IIS properites of the deployment site set to allow anonymous users, everything works peachy-keen. However if I use integrated authentication and no anonymous users, I'm going around in circles and getting "access denied" errors which are buried in a log file (not something I want my users to deal with). If I pre-install the prerequisites manually (.net 2.0, etc.),then I can install the application from the "launch" hyperlink.

I can't believe that I am still in this hole and trying to out-think the available tools to get what I want. Is it so unusual to not want the entire world to have access to my client's applications?

There is an msdn document called Server Configuration Issues in ClickOnce Deployments which addresses the authentication problem directly.

Server Authentication Issues

When you publish to a remote server that has "Anonymous Access" turned off, you will receive the following warning:

"The files could not be downloaded from http://<remoteserver>/<myapplication>/.  The remote server returned an error: (401) Unathorized."
Note

You can make NTLM (NT challenge-response) authentication work if the site prompts for credentials other than your default credentials, and, in the security dialog box, you click OK when you are prompted if you want to save the supplied credentials for future sessions. However, this same workaround will not work for basic authentication.

But even after following the above recommendation (where I have turned off anonymous access and selected integrated authentication, and am then prompted to log in) I can't follow through a full setup with requisites and the application. I have already described the result above.

Now I have the choice between just figuring out my own solution to this (not using the automatically generated publish page and building my own asp.net page for downloading some things anonymously and some things securely) or continuing to google endlessly to see if anyone else has dealt with this seemingly commonplace scenario.

Sadly this is just a tiny little exe and this down-the-toilet-again-weekend is making me more worried about getting my big multi-layered app working with ClickOnce.

Update about 2 hours later: After venting (in this blog post :-) ) I came up with a solution that is somewhat clunky but does the trick for now. I am modified the publish.htm in the following way:

  1. For the .NET 2.0 requirement, I put a hyperlink to the Microsoft's .NET 2.0 x86 redistributable download page.
  2. For the crystal reports .net 2.0 msi, I put a hyperlink to the msi on our web server.
  3. I changed the Install button to point to myapp.application, instead of setup.exe. Setup.exe tries to install the requirements.
  4. I wrote text for #1 and #2 to explain to the users how to determine if .NET 2.0 or crystal reports needs to be installed, how long it might take and that this only needs to be done once on their computer.

I also had to muck with proxies on the machines on the intranet. They get at the web through isa-server. So for the local link to publish.htm and the msi for crystal, everything was okay. With the isa-server proxy set up for non-local sites, the microsoft link was okay. But even with "don't use proxy for local urls", I couldn't get the myapp.application to install. Therefore, I had to explicitly put the ip address of intranet web-server into the exceptions list on the Advanced page for the proxy settings. What I'm talking about here is in Internet Explorer/ Tools / Internet Option / Connections / LAN Settings/ "Use a Proxy Server" with my proxy info and "By Pass Proxy Server for Local Addresses" are both checked. Then click on the Advanced button and add the ip of the local web server into "exceptions".

I have not tried this over the web yet, but remember, my goal is for intranet only installs on this application.

Don't Forget: www.acehaid.org

Sunday, January 29, 2006 10:42:25 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Saturday, January 28, 2006
The sessions for DevTeach have been announced and the early bird discount of $300 is only good for a few more days. So if you are hoping to go to beautiful Montreal in early May, register sooner than later for savings. I'll be doing 3 sessions at DevTeach. I love presenting at this conference and it's oh so close to home!

Don't Forget: www.acehaid.org
Saturday, January 28, 2006 4:41:49 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Friday, January 27, 2006

There was a time when indies felt a need to pretend they were a big company. That's changed a lot. [Read more...]

[A DevLife post]



Don't Forget: www.acehaid.org
Friday, January 27, 2006 4:25:49 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Tuesday, January 24, 2006

I'm pretty slow on the uptake sometimes. Leon Bambrick's TimeSnapper app was the top pick of the Larkware 2005 Developer Tool contest. I knew then that I needed to look at this program, but it unfortunately was on a long list of things I needed to do. Over the last few weeks, however, it bubbled up to the top, as I have been thinking about the crazy way I work when I'm in front of the computer. With little patience at my disposal and always so much to do, I can't even wait 5 seconds for something to load up on my computer, and will go do something else to fill the void. Check email (which of course could steer me on a whole new course at the flip of a switch), newsgroups, the news, my blog reader, my own blog stats, another client project that I had a thought about. Anything and everything. And it's got me a little worried.

So I decided I would try TimeSnapper to really see if it's true. How long do I stay focused on any one project over the course of the day. And the answer is scary, but I will keep that to myself.

The program is surprisingly lightweight, taking advantage of our massive hard drives rather than memory. Not only can I gather evidence of my terrible habits (which can someday be used to cure me of them?), I can also go back and figure out when I stopped working on something billable even if I forgot to log out of my timeclock application.

Not only that, but in it's simplicity, as one user testimonial says "it just works". Thanks Leon. I'm not really sure if this is going to be a healthy mirror to hold up to myself, but hopefully it will have good effects!!



Don't Forget: www.acehaid.org
Tuesday, January 24, 2006 9:40:24 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Monday, January 23, 2006

Have you gone out of your way to avoid .NET namespaces that just sound too scary? [Read more...]

[A DevLife post]



Don't Forget: www.acehaid.org
Monday, January 23, 2006 5:42:31 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Friday, January 20, 2006

Although my own recent DLL hell with VS2005 is in design time, I have learned quite a good lesson about dynamically loading assemblies and the dll hell you can introduce in that way.

I have an application that makes heavy use of Reflection.Assembly.LoadFrom where I pass in the path of a DLL to be loaded. The DLLs are randomly added to the application as we create them.

What I learned was from this post of Suzanne Cooke's about the difference between Load and LoadFrom. Load will load assemblies that are in the GAC (and a few other .NET locales) and is a big help in avoiding dll hell because the GAC does a good job of versioning. LoadFrom will load from a  file that you explicitly tell it to and cares not about versioning. There are a lot more pointers to be aware of here. Check out her post on choosing a binding context (Load and LoadFrom are binding contexts) as well as her related post about switching your code from using LoadFrom to using Load. Suzanne writes the kind of posts that cant' be read lightly and I can't really absorb their lessons unless it's something that I need to know. And I needed to know this today!



Don't Forget: www.acehaid.org
Friday, January 20, 2006 12:27:48 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

One of the pain in the rear parts of doing a lot of travel is doing a lot of travel coordination. It actually is quite time consuming to find the right flights at good times, with short layovers and not overly expensive rates. Then there's finding hotels, dealing with the usual variety of room rates and lastly coordinating anything else that might be involved. Even when you have a travel agent helping you, there are still a lot of decisions to make. I think for every event I go to, I probably spend at least a few hours on this.

Even with my little overnight trip to do an INETA gig at TechValley .NET in Albany next week, I spent time figuring out where to stay (finally settled on a hotel in Saratoga Springs with the benefit of meeting up with a friend), if I should take a train (turns out it would be a lot more hours than driving and still include driving) or even rent a car (though I discovered the only option there was to drive 30 miles north to Burlington to get a car before heading south to Albany). So in the long run, I  have a simple plan - hop in my car and drive to Albany. But given the options, the budget and my own schedule, it was not a "no-brainer" and I infectiously put way too much thought into it.

When Kate and I sent to South Africa, we spent hours and hours on i.m. trying to find flights that we could meet up on that would be amenably priced for Microsoft and would get all of the mileage credits to our own frequent flier accounts. Then we had to go back and forth with Microsoft's travel coordinator over a series of about 20 emails. I bet we each spent at least 4 hours doing that. This, of course, does not include planning our outings.



Don't Forget: www.acehaid.org
Friday, January 20, 2006 11:52:14 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  |