Tuesday, December 15, 2009

A fix for: "Attempted to read or write protected memory " in Visual Studio

I got this error after installing the WPF Toolkit and not closing all my Visual Studios before installing. The error was thrown by Visual Studio when I invoked F5 to run my WPF application in debug mode.
In my case the fix was simple:
Goto: Tools - Import and Export Settings - Reset all Settings

Friday, September 4, 2009

How to fix: "shared heap exhausted or damaged"

The error can occur because your desktop heap is too small. This happened to me especially after opening a large number of windows.

Nview then filled up the application log with the error message:

"NVIEW : Explorer: shared heap exhausted or damaged"

Quick Solution:

1.) Start Regedit:

2.) Browse to

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems

3.) Open the "Windows" key

In the string you find a section like

....Windows SharedSection=1024,4096,512....

Edit the second value e.g.

Windows SharedSection=1024,8192,512


Click OK

4.) Restart Windows

To verify this solution is the correct one for you can:

1. ) Download dheapmon

2.) Open a command shell (Start - Run - "CMD")

3.) Change your directory to the location of the executables (e.g. C:\kktools\dheapmon8.1\x86)

4.) Type: dheapinst.exe -y srv*http://msdl.microsoft.com/download/symbols

5.) Type: dheapmon -l

6.) Type: dheapmon

Now you see:


If you see a high utilization of the "WinSta0\Default " session e.g.:


WinStation\Desktop Heap Size(KB) Used Rate(%)
---------------------------------------------
WinSta0\Default 4096 95,6

then the above solution will do the job for you because:

"
The second SharedSection value (3072) is the size of the desktop heap for each desktop that is associated with the "interactive" window station WinSta0. User objects like hooks, menus, strings, and windows consume memory in this desktop heap."

Warning

As always be careful with what you do. Modifying your registry has the potential to render your system useless.

Thursday, August 27, 2009

Where is Microsoft's XSLT 2?

In January 2007 you found this announcement in the Microsoft XML Team Blog

"We are pleased to note that XSLT 2.0 and XPath 2.0 are now W3C Recommendations. Microsoft contributed thousands of person-hours to the W3C efforts that developed these standards and is committed assist with the further development of XML standards at W3C.
....
Neither are yet implemented over standalone documents in our libraries, mainly because we have a policy of not implementing W3C specifications in the core System.Xml and MSXML libraries until they are official Recommendations. "


As XSLT 2 is still not found in any library published by Microsoft, given their policies XSLT 2 is 2.5 years overdue.

Even worse. I think no one has ever heard of XSLT 2 by Microsoft again. Just lately Microsoft has released the MSXML 6 ServicePack 3. Still nothing about XSLT 2.

XSLT 1 is simply insufficient. Without the non XSLT 1 function node-set() you cannot even sum up two related fields like here.

<Totalvalue>
<xsl:value-of select="sum(./nominal * ./prices)"/><!-- Not working in XSLT 1 -->
</Totalvalue>

What about alternatives? There is for example Saxon that is both available for .Net and Java. But unfortunately Saxxon is still working as an interpreter. This eliminates this choice for high performance XSLT transformations, e.g. if you need to deserialize the result of the transformation into objects.

So for high performance scenarios there is still no available XSLT 2 processor on the market for .Net which is, after Microsoft contributed thousands of hours to the standard, quite awkward in my eyes.

I think it is definitely time for Microsoft to bring XSLT 2 to the masses, including a high performance XSLTCompiledtransform2 library for .Net.

In order to raise the pressure, please write the Microsoft XML team why you need XSLT 2.

On 23.09.2009 is asked through their team blog the following....

"Hi,

I recently found out that IBM published a public beta regarding XSLT 2. Intel is obviously working on XSLT 2 as well.

What is the status of XSLT 2 at Microsoft?

Thanks,"


The answer to my question comes a week later...

"Hi,

While XML continues to be a key part of our platform going forward, we have decided not to pursue an XSLT 2.0 implementation at this time. If there is a specific XSLT task you’re trying to accomplish and are having difficulty with XSLT 1.0, please let us know and we’ll do our best to help.

Thanks,
P."

Saturday, March 28, 2009

Biggest crap ever! Windows Vista

  • Frequent Bluescreens
  • Applications that stop working one day to the next
  • WLAN stops connecting to any network one day to the next even after replacing hardware
  • 5 reinstalls in 1 year with absolutely nothing but 3 games installed
  • Biggest mess in configuration dialogs ever
  • Tons of stupid questions
  • Inconsistencies in what files are in a directory

Thanks Microsoft for the biggest crap a computer has ever seen. Windows Vista.

Friday, March 13, 2009

Code Comments with svcutil

Unfortunately svcutil does not create comments from your XML annotations in your XSD or service WSDL. The more complex your data model gets the more the more you will miss this feature.

Well, you can be helped now.

Injecting Code into .NET Assemblies

What you need for this kind of surgery is:
1.) Reflector
2.) Reflexil (Reflector plugin)
3.) Your DLL or custom Assembly to call some code
4.) 10 Minutes time

The patient:
svcutil.exe (C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\svcutil.exe)

The enhancement:
svcutilImportCommentExtension

Primary Mission Goal:
Pimp svcutil to create nice code comments in my DataContracts from my annotations in XSD ( /dconly Option )
Secondary Mission Goal:
Pimp svcutil to create nice code comments in my WCF proxies from my WCF Service WSDL


1.) Copy the patient

2.) Start Reflector and
a.) Open the copy of svcutil.exe
b.) Open the DLL

3.) Right click on svcutil and select "Go to entry Point".

4.) Click on Main(string[] args) in "return (int) runtime.Run();"



5.) Click on ExecuteToolMode in "return this.ExecuteToolMode(toolMode, inputModule);"

6.) Click on ImportDataContracts in "this.ImportDataContracts(inputModule);"



7.) Click on ImportDataContracts in "module.ImportDataContracts();"

8.) Click on "Tools - Reflexil 0.9"

9.) Right click Line 7 "Call .... WriteConversionErrors" and select "Create New"
Choose
Opcode: ldstr
Operand Type: string
Operand: Calling svcutil extension....

Finish with selecting "Insert before selection"

10.) Right click Line 7 which now contains our "ldstr..." and select "Create New"
Choose
Opcode: Call
Operand Type: Method Reference
Operand: svcutilImportCommentExtension - svcutilImportCommentExtension.dll - ContractGenTest - CommentWriter - Hello(System.String) : System.Void



Finish with selecting "Insert after selection"

11.) Right click Line 8 which now contains our "call Hello(..)." and select "Create New"
Choose
Opcode: ldarg.0
Operand Type: None
Operand:

Finish with selecting "Insert after selection"

12.) Right click Line 9 which now contains our "ldarg.0" and select "Create New"
Choose
Opcode: ldfld
Operand Type: Field Reference
Operand: svcutil - svcutil.exe - Microsoft.Tools.ServiceModel.SvcUtil - ImportModule - schemas : System.Xml.XmlSchemaSet

13.) Right click Line 10 which now contains our "ldfld schemas" and select "Create New"
Choose
Opcode: ldarg.0
Operand Type: None
Operand:

Finish with selecting "Insert after selection"

14.) Right click Line 11 which now contains our "ldarg.0" and select "Create New"
Choose
Opcode: ldfld
Operand Type: Field Reference
Operand: svcutil - svcutil.exe - Microsoft.Tools.ServiceModel.SvcUtil - ImportModule - codeCompileUnit : System.CodeDom.CodeCompileUnit

Finish with selecting "Insert after selection"

15.) Right click Line 12 which now contains our "ldfld codeCompileUnit" and select "Create New"
Choose
Opcode: Call
Operand Type: Method Reference
Operand: svcutilImportCommentExtension - svcutilImportCommentExtension.dll - ContractGenTest - CommentWriter - WriteComments(System.Xml.Schema.SchemaSet,System.CodeDom.CodeCompileUnit)


Finish with selecting "Insert after selection"

This is how ImportDataContracts should look like now....

(Note that the Dissambler part should still display the unchanged code as we did not save it yet. This screenshot is taken from a already modified version...)

Now click on the symbol "svcutil.exe" in the reflector and select "Save as". You will now get a warning that svcutil is a signed assembly. Select "Remove Strong Name - Remove Strong Name and update referencing assemblies" and both windows. Now select "Save as" again and replace the file.

Now when you call svcutil you should get....



and have some nice comments in your code collected from all your

<xs:annotation>
<xs:documentation>.....</xs:documentation>


tags.


Sweet.

If you do the same for ImportServiceContracts() function you will be even able to create fully documented WCF proxies....

Just make sure you this time you call

CommentWriter.WriteComments(WsdlImporter importer, CodeCompileUnit compileUnit)

using the

Operand: svcutil - svcutil.exe - Microsoft.Tools.ServiceModel.SvcUtil - ImportModule - wsdlImporter: System.ServiceModel.Description

instead of the SchemaSet.

This is how ImportServiceContracts should look like after your surgery...



To bad comments don't get exported in WCF WSDL's? Well think again and get WCFExtras. A very nice WCF Extension to get XMLComments into WCF WSDL's as well as a working flat WSDL and support for Soap Headers.

Mission accomplished

Tuesday, March 3, 2009

Using Precompiled XSLT in .NET

Using XSLT in .NET

If you specify a file using

XSLCompiledTranform.Load(string filename)

the first thing XSLCompiledTranform is going to do is to emit/compile a set of unloadable DynamicMethods.

Although this is going really fast this overhead costs around 50 - 200ms. So if total time for your conversion is around that time, using precompiled XSLT's can really improve things quite a bit. We use this scenario to do high performance yet standard translations in WCF-Services.

To precompile your XSLT's you have 2 options:

The XSLTCompiler XSLTC.exe

First option is shipped with .NET 3.5 there and is a tool called XSLTC.exe which is basically a wrapper around the static XSLCompiledTransform.CompileToType() function. There is an excellent article by Anton Lapounov. It even gives you some tips to speed things further up using ngen.


I previously stated that XSLTC.exe can only compile one XSLT per assembly, but Andrew proved me wrong.
I tried:

XSLTC.exe *.xslt

which won't work but if you take a closer look at the options

xsltc [options] [/class:] [[/class:] ...]


XSLTC.exe /out:MyXSLT.dll a.xslt b.xslt c.xslt

should compile the XSLT's into a single assembly.

IronXSLT

Second option for this job is called IronXSLT. It is a Visual Studio plug in, that allows you to create a XSLT Library Project. You simply add your XSLT's to the project and after you build the solution they will be compiled into one DLL assembly. I installed it and it works fine with Visual Studio 2008 SP1. After you installed it you have a new project type called XSLT - XSLT Library. To configure it right click it in the solution explorer and select "Properties".

The problem. Unfortunately it seems that its creator Oleg Tkachenko has abandoned his project and no download is working anymore on the projects website.

I found one of the last working IronXSLT downloads here . I will try to contact Oleg in order to get the source published somewhere.

Performance Comparison

Attached to the already above mentioned article of Anton Lapounov there is some test code attached.

I ran a couple of test and got the following results:

using XSLTranform class

XSLTranform
.Load(string filename)


Load time: 35,86 ms
Load time: 1,533 ms
Load time: 1,450 ms
Load time: 1,441 ms
Load time: 1,504 ms
------------------------
Transform time: 51,94 ms
Transform time: 51,29 ms
Transform time: 49,46 ms
Transform time: 51,10 ms
Transform time: 48,77 ms

using XSLCompiledTranform loading tranformation from file

XSLCompiledTranform
.Load(string filename)


Load time: 51,86 ms

Load time: 2,640 ms
Load time: 2,556 ms
Load time: 2,704 ms
Load time: 2,644 ms
------------------------
Transform time: 56,89 ms
Transform time: 1,909 ms
Transform time: 1,680 ms
Transform time: 4,948 ms
Transform time: 1,427 ms

using XSLCompiledTranform loading XSLTC precompiled Transformation

XSLCompiledTranform.Load(type T)

Load time: 5,252 ms
Load time: 0,057 ms
Load time: 0,034 ms
Load time: 0,061 ms
Load time: 0,031 ms
------------------------
Transform time: 8,936 ms
Transform time: 2,302 ms
Transform time: 1,545 ms
Transform time: 1,457 ms
Transform time: 1,505 ms

using XSLCompiledTranform loading XSLTC precompiled and ngen'd Transformation

XSLCompiledTranform
.Load(type T)

Load time: 4,596 ms
Load time: 0,052 ms
Load time: 0,035 ms
Load time: 0,032 ms
Load time: 0,031 ms
------------------------
Transform time: 2,917 ms
Transform time: 2,446 ms
Transform time: 1,584 ms
Transform time: 1,457 ms
Transform time: 1,472 ms

Friday, February 27, 2009

The Visual Studio 2008 Profiler is....

in nice words....

complete crap.

I just upgraded my Visual Studio Professional 2008 Version to a 2800 USD Team Edition. Of course I installed SP1 first. The reason behind was that our WCF Service project is getting to a point where performance is getting relevant, so we needed to get some profiler results on our code.

So if you think you can install Visual Studio Team or Developer Edition and just hit a "Profile Code" button and get some results you are wrong.

For some reason the profiler does not collect any data

"PRF0025: No data was collected"

is all I got the first day. No matter whether I used the "Sampling" or "Instrumentation" method. All I got was straight nothing.

The documentation seems to be close to nothing as well. But then I stumbled into some web page and found out that the whole profiler thing is located in

%PROGRAMFILES%\Microsoft Visual Studio 9.0\Team Tools\Performance Tools

There is a little batch called VSPerfCLREnv.cmd which then can called with various options.
But when you check out this little tool you find out that the whole profiler thing is based on enviroment variables. And guess what you have to do if you set one of the /global parameters...

Yes reboot. Every time.

After that at least could do some profiling with Instrumentation method.

Linq/Lambda Expressions are not handled appropriately

But if the profiler did not collect any data before, now a single service function call collected more than 600MB of data. That's quite a lot if you think that the service function has not more than 100 lines of user code.

It took a while to find out what happened.


foreach (var item in items)
item.StaticInstrument = fullStatics.Find(fs => fs.ID == item.StaticInstrument.ID);

results in 600MB profiler data.

Rewriting the code to use a dictionary instead the List extension method Find(this List)

var itemDic = new Dictionary<string, StaticInstrument>();

fullStatics.ForEach(singleStatic => itemDic[singleStatic.ID] = singleStatic);

items.ForEach(item => item.StaticInstrument = itemDic[item.StaticInstrument.ID]);

results in 2MB of profiler data.

Functions are not displayed appropriatly in the reports.

But then the next disappointment is right behind the door.

In the report I have various multiple summaries like

Function Name:
0x2B000015
0x2B0000oE

This is not really helpful. Especially as the values for function called by the disguised functions are not displayed at all. Everything just gets summed up.

I took me another half day to find out what is the reason behind this.

In the above mentioned directory you find a tool called
VSPerfReport.exe

if you pass call it like

VSPerfReport.exe PATHTO\Report.vsp

I at least got

Warning VSP2701 : Symbol Engine: File '.....dll' could not be found when looking for debug information. Full symbol/type resolution may not be possible

But when you look at the location there is of course the DLL's symbol or pdb file right next to the dll. Why it still fails to load it, I don't know. I did not find any resolution for this problem yet.

So for most of DLL's the report fails to load the symbols. The resulting report is really useless.

I tried to write some mails to the guys from the Microsoft Profiler Team but it took a while to get some answer. See the comment for some suggestions from Marc Popkin-Paine. Unfortunately his suggestions don't work for me and meanwhile the profiler refuses again to collect any data at all.

Here is what happens...

Successfully attached to process: 4828
VSPerformance Automation warning: Warning VSP2348 : 2 buffer(s) lost in association with process 4828.
Exited from process: 4828
Collection file exited: C:\Development\WCFServices\SCDService\SCDServices090305.vsp
Profiler exited
PRF0025: No data was collected.

So if you ever thought about about spending money on Team or Developer Edition to use the profiler.... Save the money. The profiler is complete crap. You even have to be careful with it. I might crash your system with a blue screen of death. The reason behind this is that they obviously access the bios to get the exact number of clock cycles. Because of the different BIOS this is the reason, why it sampling does work for a certain number of systems. But this raises another question. Why the heck can a user process in Windows still read/write the bios and crash the system?

So in short...

With the Microsoft Profiler I wasted a lot of money and time without getting any useful results.

I have evaluated the current ANTS 4.3 profiler. ANTS works right out of the box and here I can see all functions but the disadvantage is a huge overhead. ANTS tries to eliminate the overhead in the calculation but is not totally succesful with this task.

Wednesday, February 18, 2009

Screw Silverlight

The thought behind evaluating Silverlight 2 was to check whether Silverlight is suited to build rich office applications, that can be handled just like common GUI applications but just in IE. Another central question was to verify that I can use my Xaml controls from WPF applications seamlessly in Silverlight 2.
So I am really not interested in fancy design, multimedia and other special effects that seems to be the general target audience for Silverlight 2.

First thing you have to do when you try to evaluate Silverlight 2 with Visual Studio you have to download a whole bunch off applications. Most important it seemed to install the Silverlight Tools for Visual Studio 2008 SP1 .

After downloading some 70 megs of data the the first frustration is right around the corner, if you have to use an authenticating proxy to get Internet access.

Though you have to download some 70 megs the package needs to download more data. And of course there is nowhere a full package. Even more unfortunate it seems that until today Microsoft has never heard anything of a thing called authenticating proxy and consequently the install fails. Sigh.
Call it a act of despair and interest I programmed my own little authenticating proxy bridge that acts as proxy and forwards each request to the real proxy plus adding the required authentication information. So finally I was able to install the tools.

Ok, so I created a new Silverlight project, opened the toolbox, took a button and dropped it onto the designer and...

the designer won't let me do that.

Although we have a fully fledged Xaml designer in WPF, there is absolutely no way to add a control in the designer in Silverlight. You are supposed to drag the items out of the toolbox into the Xaml text editor where it does nothing but adding the following code

<
Button></Button>


Wow, what an awesome and intuitive feature for my 1500 USD Visual Studio.

Ok, lets hand code my button. After setting the button properties width and height you would like some text on your button.

So you code

<Button Width="100" Height="20">Press me</Button>

This is perfect Xaml, even Expression Blend will code it that way, it works fine for WPF, but .....

that is not good enough for Silverlight.

"Button does not support text content" is the error. It turns out that if you want to get it to work with Silverlight you have to code it

<Button Width="100" Height="20" Content="Press me"/>

So let me get this straight.

  • You have to download at least 4 packages to start with silverlight.
  • Even then these packages need to download more data and neither there are full packages available nor does the setup support simple things like authenticating proxies.
    No Internet access means no Silverlight.
  • The nice Xaml designer shipped with WPF had been crippled for Silverlight to be absolutely useless.
  • The Xaml for Silverlight is incompatible with other Xaml.
  • If you do not want to hand code every GUI element and if even if you have the 1500 USD Team Edition of Visual Studio 2008 you need to buy Expression Blend 2 for just another 699 USD.

Ok guys,

this is where my evaluation comes to an abrupt end after just 60 minutes and tell you what....

Screw Silverlight 2.

Wednesday, January 28, 2009

UDDI SOA Howto

This article describes how to set up and configure and Windows Server 2003 UDDI Services.
UDDI Services are IIS hosted web services that require some kind of database.

So before installing UDDI Services you need to have IIS up and running.

Click on the screenshots to get a larger image.

1.) Add UDDI Server Component
Choose
Start - Settings - Control Panel - Add or Remove Programs - Add Remove Windows Compontents

2.) Pick UDDI Services



3.) Choose your Database

Choose the database component of your choice

If you do not have any SQL Server installed choose "Create a new MSDE database instance"
If you have SQL Server 2000 installed choose "Use the following SQL Server 2000 instance"
If you have SQL Server 2005 installed please follow this instruction before choosing "Use the following SQL Server 2000 instance" option



If you get the error message:
"This database instance does not meet the minimum version or Service Pack level requirements and cannot be used for installation. Please upgrade this instance or select another one."


it means you try to install UDDI Services on a server running SQL Server 2005 and you did not follow the instructions.

4.) SSL-encryption
If you have SSL configured for your IIS you can enable this option. If you do not have SSL enabled you can disable it here and enable it later when you SSL enabled your IIS.



5.) Choose setup location

Just choose the path where to install UDDI Services



6.) Choose the user

Choose the user UDDI Services will use



7.) Pick a name for your UDDI




8.) Disable "self register"
This is somehow related to publish the UDDI in Active Directory. I am not really sure what it does so disable it.


Great, we have UDDI Services up and running. Whats next?

Configuration of UDDI virtual directories access

1.) Open Computer Mangement snapin
Choose
Start - Settings - Control Panel - Administrative Tools - Computer Management

2.) Configure IIS "uddi" virtual directory to use Windows Authentication
in the computer management snap in go to
Internet Information Services - Web Sites - Default Web Site

Right click "uddi" and select Properties

Click on Directory Security, disable anonymous access and tick Integrated Windows authentication.

3.) Configure IIS "uddipublic" virtual directory to use UDDI Authentication
in the computer management snap in go to
Internet Information Services - Web Sites - Default Web Site

Right click "uddipublic" and select Properties

Click on Directory Security, enable anonymous access.


Great, we have configured UDDI Service authentication. Whats next?

Create Windows Publishing User account

In standard configuration every user in servers Administrators group has the right to publish Services.
But I really recommend creating a special user account for publishing UDDI service. That has the advantage you get all services published under one user, which gives you a much better overview over your running services.

In this case I created a User "UDDIAdmin" and added him to the "Administrators" group.

Now log in with your "UDDIAdmin" account, open Internet Explorer and type:

Publish a service on UDDI


http://localhost/uddi/

Now Click on Publish on you will see:



First thing we have to do is to create a provider. A "provider" is also referred as a "business" in UDDI terms. Basically the provider or business is just an embracing category for our services.

Create a Provider

Right click on provider and select "Add Provider". Then click on the new provider and edit the name to be "MyProvider".


Create a Service
Now right click on Provider and select "Add Service". Then click on the new service and edit the name to be "MyService".



Create a binding
Now right click on Service and select "Add Binding". Then click on the new binding and edit the URL to be the URL to your Service. "http://myserver/myservice.svc" in this case.


Create a tModel
Now right click on tModels and select "Add tModel". Then click on the new tModel and edit the name to be "MytModel".
What not really required but what makes it more UDDI is the following...
Click on the "Categories" tab and click on "Add Category". Now select "uddi-org:types" "Specification for a web service" "Specification for a web service described in WSDL" and click on "Add Category".
Now click on the "Overview Document" tab. Click on "Edit" and paste a link to the wsdl document of the service. e.g. http://myserver/myservice.svc?WSDL.

You could use these attributes later to pick the right tModel


Add instace Info
Now as a last step right click on your service select "Add instance info". Now type in "My" in the search box click on search and select "MytModel" from the list.

Done. We have published our first service in the UDDI.


Great, but what I do now with my UDDI?

A simple UDDI query in C#

You can install the Windows Server 2003 SDK or simply add a link to Microsoft.UDDI.dll in your C# project. Where to find those is described here.

Now implement the following code:

//URL to your UDDI directory
string uDDIURL = "http://myserver.com/uddi/";

// Take your tModel Key here. Look on the screenshots
string modelKey = "uuid:25f0c31f-1846-4f8c-919b-3164ffae3ed2";

// Take your service Key here. Look on the screenshots
string serviceKey= "49263d91-85e7-4285-b36c-a217d6a8e1b9";


// Create UDDI location object
UddiSiteLocation _siteLocation = new UddiSiteLocation(uDDIURL + "inquire.asmx",
uDDIURL + "publish.asmx",
uDDIURL + "extension.asmx",
string.Empty,
Microsoft.Uddi.AuthenticationMode.WindowsAuthentication);

// Initialize a new instance of the FindBinding class used to locate the service.
// Add the service key to the binding.
FindBinding _findBinding = new FindBinding(modelKey);
_findBinding.ServiceKey = serviceKey;

// Create the managed URL object. It is dynamically updated by the UDDI Registry
UddiConnection _connection = new UddiConnection(_siteLocation);
ManagedURL managedURL = new ManagedUrl(_connection, _findBinding);

if (managedURL.Count > 0)
Console.WriteLine("Hooray we did it");


Please keep in mind the managedURL object now keeps a steady connection with the UDDI and gets information on newly published or removed services. So there is absolutely no need to recreate the manageURL object in order to refresh it.

Further tips regardings UDDI Services can be found here.

For further examples please see this article on codeproject.com which includes some source code.

Tuesday, January 13, 2009

Dealing with Microsoft UDDI services

How do I install and setup Microsoft UDDI Services?

Read the UDDI SOA Howto.

Where to get the UDDI samples?


Microsoft did not include the UDDI samples in the current Windows SDK for Windows Server 2008 and .Net Framework 3.5.

Therefore you need to install the old Windows Server 2003 SDK .

After you installed the Core SDK you find the samples in

%PROGRAMFILES%\Microsoft SDK\samples\UDDI


Where to get Microsoft.UDDI.DLL?

You find it if you install the Windows Server 2003 SDK you find it in

%PROGRAMFILES%\Microsoft SDK\bin

or if you installed .NET 3.0 you find it in

%PROGRAMFILES%\Reference Assemblies\Microsoft\UDDI\v2.1\bin\system32


How to turn on Debugging?


If you want to turn on Debugging use regedit and goto:

[HKLM\SOFTWARE\Microsoft\UDDI\Debug]

set FileLogLevel to the appropriate value. Possible values are:

0 = None
1 = Error,
2 = Warning,
3 = FailAudit,
4 = PassAudit,
5 = Info ,
6 = Verbose

where 6 (Verbose) prints the most information into the file specified by LogFileName

How to configure another virtual directory for UDDI?

Open the IIS Manager, right click on Default Web Site and select New Virtual directory. Select a name for the alias, then select the UDDI/webroot folder (e.g. "c:\inet\uddi\webroot" ). Then select the Read, Run Scripts and Browse permission. After the wizard finishes right click on the virtual directoy and select Properties. Now change the Application Pool to "MSUDDIAppPool". Last thing is to select the ASP.NET tab and change the ASP.NET Version to 1.1.4322.

How to configure Authentication?

Microsoft UDDI offers basically 2 different types of authentication.

Windows Authentication and UDDIAuthentication. The difference is that in Windows Authentication you do not have to specify a Username and Password when you create the UDDIConnection object.

Windows Authentication
In Windows Authentication you do not have to specify a Username and Password. UDDI simply takes the Usercredentials received by the UDDI web service. To configure UDDI for using Windows credentials open the IIS Manager, right click the virtual directory (e.g. uddi or uddipublic), go to the Directory Security tab and click on Authentication and access control. Now make sure "Enable anonymous access" is disabled and Authenticated access is set to Integrated Windows authentication.

Ok, whats UDDIAuthentication?
When you use UDDIAuthentication you specify a Username and Password when you create the UDDIConnection object. However this user has to be a valid windows user account and has to have appropriate permissions. Using UDDIAuthentication the authentication of the account is not enforced by IIS but the UDDI Service will authenticate the user.
To configure UDDI for doing UDDI authentication open the IIS Manager, right click the virtual directory (e.g. uddi or uddipublic), go to the Directory Security tab and click on Authentication and access control. Now make sure "Enable anonymous access" is enabled.

Now use the following pattern:

UddiSiteLocation location = new UddiSiteLocation(
httpServerName + "inquire.asmx",
httpsServerName + "publish.asmx",
httpServerName + "extension.asmx",
"My Site",
AuthenticationMode.UddiAuthentication);

UddiConnection oConnect = new UddiConnection(location, @"Domain\Username", "Password");

oConnect.AutoGetAuthToken = true;

The secret to UDDI Authentication
1.) Try to the current user out the current HTTPContext (Windows Authentication)
2.) Query the Security.Authentication Mode Parameter which is set in the UDDI Database in table UDO_config.
3.) If the Security.Authentication Mode parameter is set to 8 UDDI tries Passport authentication.
4.) Windows Authentication is only used if the current user is not the anonymous user (Anonymous Access is disabled) and you did not specify a username in the connection.
5.) By Default UDDIAuthentication is used.


public AuthToken GetAuthToken(GetAuthToken gat)
{
Debug.Enter();
AuthToken token = new AuthToken();
try
{
IIdentity identity = HttpContext.Current.User.Identity;
int @int = Config.GetInt("Security.AuthenticationMode", 3);
if (8 == @int)
{
if (!(identity is PassportIdentity))
{
throw new UDDIException(ErrorType.E_fatalError, "UDDI_ERROR_PASSPORT_CONFIGURATION_ERROR");
}
Debug.Write(SeverityType.Info, CategoryType.Soap, "Generating credentials for Passport based authentication
dentity is " + gat.UserID);
PassportAuthenticator authenticator = new PassportAuthenticator();
if (!authenticator.GetAuthenticationInfo(gat.UserID, gat.Cred, out token.AuthInfo))
{
throw new UDDIException(ErrorType.E_unknownUser, "USER_FAILED_AUTHENTICATION");
}
if (!authenticator.Authenticate(token.AuthInfo, 0x3840))
{
throw new UDDIException(ErrorType.E_unknownUser, "UDDI_ERROR_USER_FAILED_AUTHENTICATION");
}
if (!Context.User.IsVerified)
{
throw new UDDIException(ErrorType.E_unknownUser, "UDDI_ERROR_NOT_A_VALID_PUBLISHER");
}
}
else if ((!((WindowsIdentity) identity).IsAnonymous && ((@int & 2) != 0)) && Utility.StringEmpty(gat.UserID))
{
Debug.Write(SeverityType.Info, CategoryType.Soap, "Generating credentials for Windows based authentication
Identity is " + identity.Name);
new WindowsAuthenticator().GetAuthenticationInfo(gat.UserID, gat.Cred, out token.AuthInfo);
}
else
{
if ((@int & 1) == 0)
{
throw new UDDIException(ErrorType.E_unsupported, "UDDI_ERROR_AUTHENTICATION_CONFIGURATION_ERROR");
}
Debug.Write(SeverityType.Info, CategoryType.Soap, "Generating credentials for UDDI based authentication");
new UDDIAuthenticator().GetAuthenticationInfo(gat.UserID, gat.Cred, out token.AuthInfo);
}
Debug.Write(SeverityType.Info, CategoryType.Soap, "Windows Identity is " + WindowsIdentity.GetCurrent().Name);
Debug.Write(SeverityType.Info, CategoryType.Soap, "Thread Identity is " + Thread.CurrentPrincipal.Identity.Name);
Debug.Write(SeverityType.Info, CategoryType.Soap, "HttpContext Identity is " + identity.Name);
Debug.Verify(Context.User.IsPublisher, "UDDI_ERROR_NO_PUBLISHER_CREDENTIALS", ErrorType.E_fatalError, new
bject[] { Context.User.ID });
Debug.Write(SeverityType.Info, CategoryType.Authorization, "Authenticated user (userid = " + gat.UserID + " )");
}
catch (Exception exception)
{
DispositionReport.Throw(exception);
}
return token;
}


Errors and Solutions

If authentication fails with "Authetication failed" and in the UDDI log you will see.

FAIL AUTH 2009/01/13 18:09:14 System.ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length
at System.String.Substring(Int32 startIndex, Int32 length)
at UDDI.API.Authentication.UDDIAuthenticator.GetAuthenticationInfo(String userid, String password, String& ticket)

Dont forget to put an @ before the string specifying the username so use:

string szUsername = @"Domain\User";

Monday, January 12, 2009

How to get rid of http://tempuri.org/ in WCF WSDL

"Each XML Web Service needs a unique namespace in order for client applications to distinguish it from other services on the Web. By default, ASP.Net Web Services use http://tempuri.org/ for this purpose. While this suitable for XML Web Services under development, published services should use a unique, permanent namespace." (http://tempuri.org)

By default WCF maps all service operations to the targetnamespace http://tempuri.org/ .
The problem with this approach occurs as soon as you as you need to uniquely indentify a service operation and you have more than just one service. e.g. in Biztalk or Microsoft Managed Service Engine.
Guess you have a 2 services both with the DoSomeThing() function. As both use the http://tempuri.org namespace for their operations, you can't uniquely indentify them.

To get rid of http://tempuri.org/ in your WSDL in WCF do the following:

1.) In your ServiceContract attribute constructor define the Namespace property.

[ServiceContract(Namespace = "http://myservice.com")]

public interface IMyService

2.) For your ServiceClass create the ServiceBehavior attribute with Namespace property

[ServiceBehavior(Namespace = "http://myservice.com")]

class MyService : IMyService

3.) In all your bindings set the bindingNamespace property

<endpoint binding="basicHttpBinding" bindingNamespace="http://myservice.com"....