Philippe that's me
Calling One Way WCF Service with BizTalk WCF Adapter, Part 1
If you ever tried to call a One Way web service operation with BizTalk, you might have read that BizTalk's WCF Adapters don't support One Way calls. The orchestration calls the service as expected and carries on running, but some Messaging process still hangs in the BizTalk Server Administration Console. Simply put: BizTalk 2006 R2 WCF Adapters don't support "Fire and Forget" communication pattern (message is sent and reception is acknowledged by the listening service, but no response is sent back).
In the "Using the Windows Communication Foundation (WCF) Adapters in BizTalk Server" paper by Aaron Skonnard, it is clearly stated at page 22:
An important consideration is that the WCF send adapter is only compatible with request-reply operations even when used on one-way send ports. WCF service operations can return void but they shouldn’t be marked with IsOneWay=true if you want to call them from a WCF send port.
This means that if an orchestration calls a service operation marked as One Way (hence not returning anything), the orchestration will continue and terminate fine, but the port that called the service will hang there for a response.
With default settings, the process will try to call the service three more times before giving up raising some CommunicationException:
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
This is not very nice.
This issues has been discussed many times on blogs. One of the solution proposed by Sonu Arora is to remove the IsOneWay operation attribute at the service, so the service sends an empty SOAP message as a response. This is the same solution that what is advised by Aaron. However, this means that you have some control on the service itself, which might not be the case. On top of this, if you have other client calling that service, should they all change because of BizTalk? I don't think so.
An other solution proposed by Josh Twist, who's encountering the same issue but the other way round, is to either modify the orchestration (hence making it aware of the post used, which is not good), or to build an intermediary service that will support the One Way operation (whichever direction you choose) and adapt to make sure BizTalk gets what it needs.
This is what I did and I will explain it is part 2 of this post, as I'm running out of time today :)
BizTalk complaining about Orchestration instances still existing
As I was studying BizTalk 2006 R2, I came across a strange error. This error was reported by Visual Studio 2005 when trying to redeploy.
Could not change the bindings for orchestration 'xxx', Version=1.0.0.0,Culture=neutral, PublicKeyToken=c380e04620d206e8' as one or more instances of the orchestration still exist.
Trying to act on the orchestration itself or even the solution in BizTalk Administration Tool was giving the same error.
The fix was found in this blog post: One or more instances of the orchestration still exist.
So, there are two solutions to fix this issue:
- Terminate instances manually using the BizTalk Administration Tool, which didn't work for me.
- Use a stored procedure to clear BizTalk's message box of all messages. This one didn't work either.
As pointed out in one of the comments of the abode post, the bts_CleanupMsgbox comes empty at BizTalk install. This means that it executes when you call it, but nothing happens. The orchestrations were still in the list of running orchestrations in BizTalk Administration Tool.
However, the script to create the working procedure is located in the "C:\Program Files\Microsoft BizTalk Server 2006\Schema\msgbox_cleanup_logic.sql" file. Once this has been executed, the stored procedure will correctly clean BizTalk's messages database.
Updating XSD file in InfoPath Form
Some time ago, I was asked to build a InfoPath form out of an Xsd file. I didn't had any experience using InfoPath, but it turned out to be pretty easy.
Today, I was asked if I could modify the form in order to take in account some changes in the Xsd.
My first attempt was to have a look in the Data Source part of the Design Task pane of the designer. However, everything in there is grayed out, so there is no way to change the values there.
My second attempt was to naively try to open the .xsn file with a text editor to see what was inside it. The content is, as expected, unreadable.
Then I stumbled upon this InfoPath Help and How-to article: Extract or combine the form files for a form template. This was what I was looking for, as it was showing how to "disassemble" the form into pieces, modify some of the content then build the form back. This is done by right clicking on the "manifest.xsf" file in windows explorer then choosing the "Design" option.
However, there is a catch. Simply replacing the old schema by the new one effectively changed in the Data Source part, but it was not automatically reflected in the form. InfoPath does not have a dynamic link to the Xsd file...
To reflect the new changes from the Xsd, you'll have to delete the part that were changed in the form, and add them again on the form.
LINQ to SQL and auto increment fields
When using LINQ to SQL in Visual Studio 2005, Table and Column mapping has to be coded manually. This is not a very difficult job but it's repetitive and boring (of course, if you are using Visual Studio 2008 to automatically generated the mapping code, this will be done automatically).
I ran into an issue while following a guide on manually map database tables to classes. When I tried to insert a new record, leaving the identity field empty in the object, I had the following error:
"Cannot insert explicit value for identity column in table 'Contexts' when IDENTITY_INSERT is set to OFF."
It was pretty obvious that, as the identity column was and Int32, it was set to 0 as default, and when LINQ tried to insert that row in the table the SQL Server raised an error as this auto incremented field cannot be explicitly set.
This is simply solved by using the IsDbGenerated attribute in the Column annotation description of the field, as shown in the following code.
private Int32 _id; [Column(IsPrimaryKey = true, IsDbGenerated = true)] public Int32 Id { get { return this._id; } set { this._id = value; } }
This attribute tells LINQ not to give a value for this field as it is generated by the database at insert time.
Another very nice thing about this is that once you have inserted the object in the database, this field will hold the value generated by the database. Practically, this means that after executing the following code
DataTable.InsertOnSubmit(obj); DataContext.SubmitChanges();
the obj.Id property will contain the value that was assigned by the database.
WCF Services hosted in IIS
Lately, I had some trouble hosting WCF Services on IIS on a remote VM running Windows Server 2003. Nothing really serious, but I figured out that it wouldn't be bad to write down these errors for future reference.
Enabling hosting of WCF Services on IIS
This is probably trivial, but I'm still writing it here so I can refer to it later.
First, if the .NET 2.0 Framework was installed prior to IIS, IIS is not registered with ASP.NET. It can be done manually running the following command:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -i
Then, you have to register .svc files in IIS, which is done by running the following command:
C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation>ServiceModelReg.exe -i
Once this is done, simply run iisreset in any command line window to restart IIS.
That's it, IIS can now host WCF services.
Please note that if you deploy your website directly from Visual Studio, you'll have to make sure that Frontpage Server Extensions are installed on the server.
Hosting a WCF Service in IIS
Anyway, hosting the service is very easy. The service endpoint will be a .svc file in which you'll have to write only one line, referencing the service that is to be hosted.
<%@ ServiceHost Service="MyService" %>
On top of that, the Web.config file has to be modified in order to contain the service's information like you would do in any WCF host application (ABC, except that you leave the address empty as the endpoint is the uri of the .svc file).
Permission Issues
If the service you are hosting interacts in some way with the file system or any other operation that might require permissions, don't forget that once they are in IIS, they will have the limited rights of ASPNET (XP) or NETWORK SERVICE (WS2003) account, depending on the operating system.
I'm highlighting this because prior to host my services in IIS, I hosted them in a command line window. This is handy for debugging, and very simple to set up. However, this means that the WCF services are running with lots of privileges (power user or administrator, as you are developing). Once in IIS, you can still debug easily by attaching to the IIS process (Ctrl + Alt + P in Visual Studio).