While working on getting a Java Web service and a .NET Web service client to talk to one another, I ran into an interesting situation. The problem had to do with the WSDL being produced by the Java service. Actually, the entire process involved the following steps:
- An interface written in C# was used to generate a WSDL file.
- That WSDL file was imported into JDeveloper and a web service was created
- The WSDL file exposed by the JDeveloper web service was used (through the wsdl.exe tool) to create a proxy class to be used by a .NET client.
The problem was caused by enumerations being used in the interface. The WSDL file generated using the C# interface included defined a separate type (with a base of string) for each enumeration and then restricted the string values for that type. However, the WSDL file exposed by the JDev web service expected that the enumerated parameters would be of type string. Not the restricted, created type that C# wants to send. The resulting type mismatch caused the requests from the .NET client to the Java web service to be rejected with an ‘unknown type’ message.
The solution, while admittedly a hack, demonstrations a little discussed features of enumerations. Consider property called Status that is declared as an enumerated type of CallStatus. I added a field called StatusString defined as below and decorated the Status property with a SoapIgnore attribute as follows:
[SoapElement(“Status”)]
public string StatusString
{
get { return Enum.GetName(typeof(CallStatus), status); }
set { status = (CallStatus)Enum.Parse(typeof(CallStatus), value); }
}
[SoapIgnore()]
public CallStatus Status
{ … }
The SoapIgnore attribute hides the ‘real’ Status property from the SOAP serialization process. Instead the StatusString property, which is used to convert enumerated values to and from a string, is marked as being the ‘Status’ from the perspective of SOAP serialization. One item that may or may not be a problem is that the assigned value of StatusString could be null. This isn’t considered as part of this example, as the Web service was under a compulsion to return a valid value. But if the field is nilable, then you would need to code for that in the StatusString setter.
For the last little while I have been having an issue using source control under TFS. Specifically, when I go to edit a file that (I believe) is under source control, I'm allowed to do so. What's worse, when I go to save the file (like when the application is executed or I'm running through TestManager), I'm told that the file is read-only and I'm asked if I want to overwrite it. Even if I overwrite the file, I still have to go to the Source Control Explorer and manually check the file out for editing. This is, as I'm sure many of you would agreed, annoying beyond belief. I could easily go on for paragraphs about how I'm being taken out of the flow and why isn't this happening automatically.
When I first discussed this problem with others, I was told to go to the Tools | Options dialog box. Once there, in the Source Control | Environment section, there is a couple of controls that control what happens to files upon Saving and Editing. It was suggested that setting these to “Check out automatically” would work.
Unfortunately, this wasn't the first. First off, it appears that these settings are the default values. At least, they were on my system. Frustration ensued for another couple of weeks.
Then, for reasons which I'm not sure of, some of the projects in my solution started acting the way they were supposed to. As I started editing a file, a quick “checking out” message appeared. I was confused, to put it mildly. Not to mention intrigued. As I started looking I found that the working projects contained a file with an extension of .vspscc. This is the source control bindings information for the project. After a little more work, I discovered how to create this file through the Visual Studio IDE. From the File menu, select Source Control | Change Source Control. In the dialog box that appears, the non-working projects will not be bound to a TFS server. Assuming that you are already connected to the correct TFS server, select the unbound projects and click on the Bind button at the top of the screen. This will check out the project files and you will (naturally) need to revolve any conflicts and check them back in. As well, you may need to restart Visual Studio to get the automatic check-out to work (I'm 50-50 on having to do this). But most importantly, source control will now work more like you would expect.
Just passing this information on to any who might have missed it. Look for the Release Candidate for TFS in early February.
http://blogs.msdn.com/jeffbe/archive/2006/01/19/514801.aspx
One of the things I like about VS 2005 is the integration of FxCop functionality into the IDE. Most of the time, it informs me of better practices to things that I would have done differently in previous versions of .NET. A good example is the IsNullOrEmpty method on the String class. Code analysis pointed out that, for some of my code, this would be a better performing replacement for the
x == null or x == String.Empty
tests that are quite common on parameter validation.
One of the problems that I ran into, however, was when I was trying to correct a code analysis note about validating arguments. Specifically CA 1062 - Validate Arguments on Public Methods. I had a equality operator overload that looked like the following:
public static bool operator==(BusinessObject x, BusinessObject y)
{
return x.Name = y.Name;
}
The code analysis complaint was that I should be validating the arguments of the public method. OK, I said, and modified the code to the following:
public static bool operator==(BusinessObject x, BusinessObject y)
{
if (x == null)
return false;
if (y == null)
return false;
return x.Name = y.Name;
}
First off, the reason for the two if statements was because if I only used one, code analysis still complained. But what's worse is that when I ran my unit tests, I got a fatal exception saying that VSTestHost.exe had crashed. Walking through the code, I discovered a fatal oversight that caused the problem. Feel free to take a few seconds to consider the possibilities before reading the answer.
Figure it out? It's much easier if you debug the app.
The problem is that the if (x == null) line introduces a stack overflow. This is because in order to evaluate whether x equals null, what does the code do? It calls the overloaded equality operator. Over and over again.
The solution is to modify how a null value is checked.
public static bool operator==(BusinessObject x, BusinessObject y)
{
if (Object.ReferenceEquals(x, y))
return true;
if (Object.ReferenceEquals(x, null))
return false;
if (Object.ReferenceEquals(y, null))
return false;
return x.Name == y.Name;
}
Now you should be good to go.
Update: Corrected the fact that I can't write C# code without the benefit of a compiler :) See the comments for the rationale
This question came up in our VSTS for Developers Training Course in Toronto this week. One of my students wanted to know how to undo or rollback a checkin, something you could do in Visual Source Safe.
Unfortunately this feature was cut for V1 of Team Foundation Server. Buck Hodges and Brian Harry from Microsoft share how this was a painful cut to help get V1 out the door in this forum post.
Update: James Manning (via the comments) points out that the Team Foundation PowerToy will do this for you. Great tool btw - check it out. Includes the following tools: Unshelve & Merge local changes, Rollback, Online (syncs offline changes to source control), Get Changset, and Undo Unchanged.
I'm in British Columbia for a few days for the Vancouver stop of the Canadian Launch of Visual Studio and SQL Server 2005. They are expecting a great turnout - should be one of the largest MS events in town in recent memory. Last night we had a User Group reception and I got a chance to meet some of the local community leaders and technorati.
- Rob Chartier is a smart guy who is going to be working at the Ask the Experts Cabana area as well. He is also working on a Code Camp out here in Vancouver on March 18th. Registration is now open.
- Shaun Walker of DotNetNuke open source portal fame was also there. We had some interesting conversations around the challenges of managing an open source project. I was happy to hear how commercially successfully they were as well.
- My friend Mike Flasko was also up from Redmond. He is now the Program Manager for the System.Net team and is doing well in his new role at Microsoft. They have some pretty exciting stuff in the works for Orcas and beyond. He also has an open call on his blog for feedback on what you want in Orcas for System.NET.
- I also had a chance to meet Graham Jones who runs Vantug out here.
All in all in was a fun evening. Ilya Bukshteyn is up from Redmond to do the Keynote presentation which I'm looking forward too. John Bristowe and Ilya are sure to have some lively banter during the demos.
If you weren’t aware, the version of WSE 3.0 built against the release version of Visual Studio was released on the Nov 7. I’m sure that it would have received launch parties and wide mention in blogs were it not for the conflicting launch of Visual Studio .NET, SQL Server 2005 and BizTalk 2006. :)
If you did any work with the CTP versions of WSE or if you are upgrading from WSE 2.0, there is one thing you should definitely be aware of. Specifically, I had created a WSE policy that use Anonymous over Certificate security. It was working in the CTP version. Then I upgraded to the release version. All of a sudden, I received the following error message on the client side:
WSE910: An error happened during the processing of a response message, and you can find the error in the inner exception. You can also find the response message in the Response property.
The inner exception was an InvalidOperationException with a Message of:
Security requirements are not satisfied because the security header is not present in the incoming message.
After a fair bit of digging, I determined that this message is actually a “can’t validate the user’s credentials” message. But the real cause (because, after all, I was still sending the same credentials that I did prior to upgrading) was a little more subtle. In order for the WSE functionality to work in 3.0, a new element needs to be added to the web.config of the service.
<system.web>
<webServices>
<soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</webServices>
</system.web>
When this tag gets added, all of a sudden the message went away. To be fair, this tag is documented as one of the changes between WSE 2.0 and 3.0. What surprised me is that it appears to also be one of the changes between the earlier CTP versions of WSE. Hopefully this post will help others avoid my not-so-brief struggle.
Did you know that the Start page in VS 2005 will display RSS Feeds?
Try this in VS 2005:
- Select Tools - Options on the menu.
- Navigate to Environment - Startup.
- In the Start Page News Channel textbox paste the following: http://www.objectsharp.com/blogs/MainFeed.aspx
Now your start page will be all the ObjectSharp Consultants most recent Blogs. Lucky you!
One of the questions we got during the Q&A of the Ottawa VS Launch yesterday was around problems in migrating ASP.NET applications from 2002/2003 to 2005.
The Web Platform Team has put together a nice step-by-step guide that covers some best practices to ensure a successful migration effort which should take you “the better part of a day” according to them. http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/webprojectsvs05.asp
As I mentioned earlier, I was at the Visual Studio/SQL Server/BizTalk product launch in Ottawa yesterday. I was lucky enough to be included I love getting a chance to talk to people who are just getting into .NET 2.0. I have been working with it on a daily basis for more than 6 months, to the point where I almost forget whas VS 2003 is like. Answering questions helps put my world back into perspective.
But it's not all talk at this sort of event. There is a fair bit of down time while most of the people are in sessions and there is no one to ask us questions. And when a bunch of geeks get bored, you know the results are not going to be pretty. One of my co-experts, Richard Lander, presented the following challenge: http://hoser.lander.ca/PermaLink,guid,20c75894-5947-4a62-a9c6-01b14516ecf8.aspx
Make sure that you give the code a try. I can pretty much guarantee that the number of people who will guess correctly will be incredibly small. After all, Richard is on the CLR team (and smart to boot) and he wasn't jumping up and down with the answer. Even after seeing the results, those of us in the room were scratching our heads looking for the reason. So give it your best shot and let me what you think and why.