WCF: values disappeared in response: derived classes and serialization/deseriazlization order error

WCF: values disappeared in response: derived classes and serialization/deseriazlization order error
This is a second article about errors with getting data from the web-services.
“WCF: Deserialization error, the response elementsdisappeared” ( http://geekswithblogs.net/LeonidGaneline/archive/2008/04/01/wcf-deserialization-error-the-response-elements-disappeared.aspx )
First time the whole elements disappeared from the response messages without any errors. Now only values of the elements disappeared.
We got a very strange error.
Our client code to one of the third-part web-service could not get the values from the response message.
Investigation given us such picture:
The response class has a base class. And the disappeared values are exactly from properties of this class. See the client proxy code that was generated by Visual Studio (Pict.1). Nothing wrong with it.
If we look at the wsdl that was the source for this proxy code (Pict.2) there is nothing wrong too.
The most strange thing is we have the right values in the response message (Pict.3). The errorCode and errorMessage elements have values but then we lost them. We can get them in the code (Pict.4). The output is on Pict.5.
How? Why?
The base class properties are the errorCode and errorMessage, the derived class property is the crn.
The question is in what order those two kind of properties serialize to the elements of the Xml message and then deserialize back to the class properties?
If service and client make serialization and deserialization in the “stack-like” order then everything is OK.
We see that service serialize the derived class properties first and the base class properties last (See Pict.3.1). What about our client? The client is waiting the message with different order of elements (see Pict.3.2)
And this is the source of the problem!

In the “Data Member Order ” article in the MSDN Library ( http://msdn.microsoft.com/en-us/library/ms729813.aspx ) we see:

“…The basic rules for data ordering include:
If a data contract type is a part of an inheritance hierarchy, data members of its base types are always first in the order…”

And there is no way to change this behaviour.
That’s exactly how my client proxy is working. It is waiting the base class properties on the first place and have not get them, and because these properties have minOccurs=”0″ and nillable=”true” attributes the proxy just decided that Xml message does not have properties at all and silently goes on to the first derived class property.
Unfortunately the third-part service uses the opposite order (it uses a java Axis2 service), data members of its base types are always last in the order in the serialized Xml messages.
BTW Here (http://www.onjava.com/pub/a/onjava/excerpt/JavaRMI_10/index.html?page=4) is mentioned that Java uses the same algorithm as WCF. Why doesthis consuming service use the opposite order? I have no idea.
Jeff W. Barnes in (http://jeffbarnes.net/portal/blogs/jeff_barnes/archive/2007/05/08/wcf-serialization-order-in-data-contracts.aspx) mentioned thet there isthe solution but does not give it.

Is it possible to change the proxy code on my side to follow the service order? I don’t know such options. Seems the WCF-classes where the whole deserialization occurs cannot be tuned up to change this order. Look one more time to the wsdl code (Pict.2). There is nothing about this order, ther is only the complexType the AddNewCreditCardResponse with the extension base=”ax21:ResponseData”.
Seems the only way to fix the problem is to change the auto generated code for the response message classes and force the right order. (Pict.6) OK from the point of view of WCF it is a wrong code, but what else we could do in this situation?

After these changes we’ve got the right result (see Pict.7).
=======================================================================
[Pict.1: autogenerated proxy code]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace=”http://data.transaction.com/xsd”)]
public partial class AddNewCreditCardResponse : ResponseData {

private string crnField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=0)]
public string crn {
get { return this.crnField; }
set { this.crnField = value; }
}
}
…
[System.Xml.Serialization.XmlIncludeAttribute(typeof(AddNewCreditCardResponse))]
[System.Xml.Serialization.XmlTypeAttribute(Namespace=”http://data.transaction.com/xsd”)]
public partial class ResponseData {

private string errorCodeField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=0)]
public string errorCode{
get { return this.errorCodeField; }
set { this.errorCodeField= value; }
}

private string errorMessageField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=1)]
public string errorMessage{
get { return this.errorMessageField; }
set { this.errorMessageField= value; }
}
}
[Pict.2: wsdl code]
<xs:complexType name=”AddNewCreditCardResponse”>
<xs:complexContent mixed=”false”>
<xs:extension base=”ax21:ResponseData”>
<xs:sequence>
<xs:element minOccurs=”0″ name=”crn” nillable=”true” type=”xs:string” />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
…
<xs:complexType name=”ResponseData”>
<xs:sequence>
<xs:element minOccurs=”0″ name=”errorCode” nillable=”true” type=”xs:string” />
<xs:element minOccurs=”0″ name=”errorMessage” nillable=”true” type=”xs:string” />
</xs:sequence>
</xs:complexType>…
[Pict.3.1: original response message]
…
<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/”>
<soapenv:Body>
<ns:addNewCreditCardResponse xmlns:ns=”http://service.transaction.com”>
<ns:return type=”com.transaction.data.AddNewCreditCardResponseData” xmlns:ax21=”http://data.transaction.com/xsd”>
<ax21:crn/>
<ax21:errorCode>TXN056</ax21:errorCode>
<ax21:errorMessage>Process auth with create profile error</ax21:errorMessage>
</ns:return>
</ns:addNewCreditCardResponse>
</soapenv:Body>
</soapenv:Envelope>
[Pict.3.2: response sample with “WCF” order]
<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/”>
<soapenv:Body>
<ns:addNewCreditCardResponse xmlns:ns=”http://service.transaction.com”>
<ns:return type=”com.transaction.data.AddNewCreditCardResponse” xmlns:ax21=”http://data.transaction.com/xsd”>
<ax21:errorCode>TXN0544</ax21:errorCode>
<ax21:errorMessage>Process authentification with profile error</ax21:errorMessage>
<ax21:crn/>
</ns:return>
</ns:addNewCreditCardResponse>
</soapenv:Body>
</soapenv:Envelope>
[Pict.4: test code]
…
Transaction_Ref.TransactionSvcClient client = new TestTxsServiceConsoleApplication.Transaction_Ref.TransactionSvcClient (“TransactionSvcSOAP11port_http”);
Transaction_Ref.addNewCreditCardResponse addNewCreditCardResponse = client.addNewCreditCard(…);
Console.WriteLine(“crn: [{0}]”, (addNewCreditCardResponse.crn == null ? “null” : addNewCreditCardResponse.crn));
Console.WriteLine(“errorCode: [{0}]”, (addNewCreditCardResponse.errorCode == null ? “null” : addNewCreditCardResponse.errorCode));
Console.WriteLine(“errorMessage: [{0}]”, (addNewCreditCardResponse.errorMessage == null ? “null” : addNewCreditCardResponse.errorMessage));
…
[Pict.5: output with original proxy code]
crn: []
errorCode: [null]
errorMessage: [null]
[Pict.6: changed proxy code]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace=”http://data.transaction.com/xsd”)]
public partial class AddNewCreditCardResponse {

private string crnField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=0)]
public string crn {
get { return this.crnField; }
set { this.crnField = value; }
}

private string errorCodeField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=1)]
public string errorCode{
get { return this.errorCodeField; }
set { this.errorCodeField= value; }
}
private string errorMessageField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=2)]
public string errorMessage{
get { return this.errorMessageField; }
set { this.errorMessageField= value; }
}
…
[Pict.7: output with changed proxy code]
crn: []
errorCode: [TXN0544]
errorMessage: [Process authentification with profile error]
=========================================
Please, give me a feedback!

Enhancements to BizTalk B2B functionality

I have two things to be excited about today. First, we’ve finally had some sunny spring days in Seattle (which means I had plenty of dry time outside this week).  Second, there’s more great news about our B2B technology.   Today, we’re announcing another important update for our customers-we’ve come to an agreement with our partner Covast to acquire advanced B2B capabilities.  This will be incorporated into a new feature pack which will be available as part of Software Assurance benefits to customers who license BizTalk Server (for context on BizTalk Server 2006 R3, see my previous post). 


 


Why is this important? It builds on the most recent B2B improvements in BizTalk Server.  Some highlights include:


%u00b7         New standards for specific retail segments such as warehousing, grocery, energy, automotive and air freight


%u00b7         B2B metadata management for EDI ’super’ interchanges, deeper integration with SQL Server repository/Visual Studio (EDI Explorer) and new reporting capabilities


%u00b7         Advanced B2B transports include new file adapters and transports and VAN connectivity


%u00b7         B2B operations monitor that enables role-based viewing, end-to-end tracking/tracing and automatic archiving


 


For our ISV partners, this increases the breath of B2B solutions that partners can build on top of BizTalk Server.  They can now take advantage of both industry-specific protocols in their own vertical solutions as well as advanced B2B scenarios for their customers.  Over the past year, this has been a specific customer request and adds the growing set of capabilities BizTalk Server brings to businesses.  This will make it easier to address the individual needs of a broad set of customers.  As an example, auto component makers need info about parts, sales, customers, employees and branch offices to store, track and use to execute transactions.   Meanwhile the grocery store down the street needs unique templates, workflows, rules, etc that save development time and work automatically.   These new capabilities will help both of them.


 


We have had a lot of great news about the BizTalk family recently (BizTalk RFID Mobile, BizTalk Server 2006 R3, etc.).  I can’t promise that we will have big updates like this on a weekly basis but it gives you a sense for the investments we are making to continue to improve technologies on which customers heavily rely.

Host /Host Instance Creation and Adapter Configuration Tool for BizTalk Server

I’ve put together a new BizTalk Tool available for download on BizTalkGurus.com.

This tool will do the following:

– Create Hosts

– Create Host Instances

– Assign Adapters to the new Hosts

This tool can early be set up using a Configuration file and will allow for a consistent server setup throughout your environments.

It also has the option to prompt the user for account passwords at run time and set all Adapters back to the default host.

You can download the tool here and get more information here.

Creating Multi-Part Messages in BizTalk

Creating Multi-Part Messages in BizTalk

Last year I wrote an entry about adding arbitrary
binary attachments
to a Multi-Part message in BizTalk 2006 using a helper C# component.
That entry has been fairly popular (as far as BizTalk posts go, which is not usually
much!), and I occasionally get questions about it.

The sample uses a bit of clever code to insert arbitrary attachments into an existing
XLANGMessage instance during construction. However, it’s not very clear that this
is actually a supported scenario and so there’s always a chance it might get you into
trouble.

I recently thought of another way, possibly much better supported to accomplish the
same in BizTalk 2006, though with a little performance hit: Use the Invoke Pipelines
feature in BizTalk 2006 Orchestrations.

Basically, the idea would be to create a custom pipeline component (depending on what
you need it could be a regular encoding/pre-assemble or an assembler component), generate
a new multi-part message in it, and return that to the orchestration.

I haven’t tried it yet, but I think it should work.

technorati BizTalk

BizTalk Host Creation and Adapter Assignment Tool Available for Download

What is one of the biggest problems with having to set up BizTalk in a new Environment?  Creating all the Hosts, Host Instances, and assigning the Adapters to these new hosts.  This process has been made much simpler with the help of the BizTalk Host Setup Tool.

This tool is fed by a configuration file to set up the Hosts, install Host Instances, and assign Adapters to those Hosts.  This tool also has the ability to prompt for a user password and reset all the Adapters back to the default Host (this was used extensively when I was testing the tool).

This will allow one developer to create the solution host layout and easily distribute it to others!

How should you set up your Hosts?  For starters, you should have a Receive Host, a Send Host, a Process Host, and a Tracking Host.  Then, continue to build out the Hosts as needed.  In general, it is best for each Adapter to run in its own Host.  But I’m a big fan of not taking this to extremes – specifically on single or double server BizTalk installations.

This tool will help you design and build your solutions by making it easy to separate out your processes into multiple hosts even on your developer boxes.  It will also make sure all your developers and environments are using Hosts with the same names – a total nightmare to manage.

You can find the download here.

Note: This is intended as a starting point and you are free to build off of it and customize it as needed.  It is nothing exciting as I am just wrapping WMI calls with what I hope is more user friendly XML tags.  Please remember this and all other code on BizTalkGurus.com is AS-IS and not intended for production use.

I have included two sample config files.  The two samples are HostConfig-Demo.xml and HostConfig.xml. Both have comments that should make it easy to figure out what is going on.

I have not tested this tool with remote setups or on anything other than BizTalk 2006 R2 (but anything 2004 to present should work).

Here is a sample of the XML Configuration File:

<BizTalkHostConfig Version=”1.0″ defaultHost=”BizTalkServerApplication” defaultIsoHost=”BizTalkServerIsolatedHost”>
    <MakeHosts>
        <!– Basic Sample to create a HOST
            <Host>
            <HostName>MyTestHost</HostName>
        Host Type: Isolated or InProcess
            <Type>InProcess</Type>
            <NTGroup>BizTalk Application Users</NTGroup>
            <AuthTrusted>false</AuthTrusted>
        Action: true to install or false to skip
            <InstallServers Action=”false” />
        Action: true to set adapters or false to skip
            <SetAdapters Action=”false” />
        AdapterName Type: Receive or Send
        </Host>
        Detailed sample to create a host, install it, and set up an adapter to use the new host
        <Host>
            <HostName>MyTestHost123</HostName>
        Host Type: Isolated or InProcess
            <Type>InProcess</Type>
            <NTGroup>BizTalk Application Users</NTGroup>
            <AuthTrusted>false</AuthTrusted>
        Action: true to install or false to skip
            <InstallServers Action=”true”>
                <Server>
        Start: true to start host or false to not
                    <ServerName Start=”true”>LPT154</ServerName>
                    <UserName>SomeUserSomePassword</UserName>
        Prompt: true to get a pop up to end password or false to enter it here
                    <Password Prompt=”false”>SomeUserSomePassword</Password>
                </Server>
            </InstallServers>
        Action: true to set adapters or false to skip
            <SetAdapters Action=”true”>
                <Adapter>
        Type: Receive or Send
                    <AdapterName Type=”Receive”>File</AdapterName>
                </Adapter>
            </SetAdapters>
        </Host>
        –>
</BizTalkHostConfig>

Enjoy! 

Host Instance Creation and Adapter Configuration Tool for BizTalk

This tool will help you design and build your BizTalk solutions by making it easier to consistently separate out your processes into multiple hosts even on your developer boxes.  It will also make sure all your developers and environments are using Hosts with the same names.  This can be a total nightmare to manage and maintain.

This tool is fed by a simple config file to set up the Hosts, install Host Instances, and assign Adapters to these new Hosts.  This tool has the ability to prompt for a user password and reset all the Adapters back to the default Host (this was used extensively when I was testing the tool).

This tool should work with BizTalk Server 2004, BizTalk Server 2006, and BizTalk Server 2006 R2.  I have not tested it running against any remote servers. 

For more information, see the full blog post at: http://www.biztalkgurus.com/biztalk_server/biztalk_blogs/b/biztalk/archive/2008/04/30/biztalk-host-creation-and-adapter-assignment-tool-available-for-download.aspx

SSO Database – external credentials are more recent

Hey folks – while flying through different timezones and working away on my VPCs I
came across the problem below.

Basically no further work could be done on the Application within the BizTalk Admin
Console.

 

Couldn’t stop/start, undeploy…delete etc.

 

The only thing I had done was to adjust my time to reflect local time….which as
I found out causes the problem.

 

I adjusted my clock back to Sydney time and we’re good to go!!!

 

Trap for young players……

 

 

SSO AUDIT
Function: SetConfigInfo
Tracking ID: df1dd0b0-c9d5-4012-bb97-336aa8df78b3
Client Computer: BTS06-Platform.contoso.com (mmc.exe:1884)
Client User: BTS06-PLATFORM\Administrator
Application Name: {D2241406-0767-4C13-98EB-43EECE80F8A0}
Error Code: 0xC0002A40, The external credentials in the SSO database are more recent.

Thomson Elite 3E – introduction

Wanted to start writing about our experiences with using the product.

We have just been awarded a contract to enhance some of the functionality in the product.

I don’t have a lot of information about the product other than the Thomson’s product site, some press release information, and Karen Jones singing it’s praises (there are some questionable pictures on this last blog page, so look at it at home!).

Keep your eyes on this Thomson category, as I explore what we are doing and how others might benefit from our enhancements.

By the way, if you have any experiences, feel free to contact me through the blog’s contact page, or you can contact me (Eric) directly on the contact information page, or even feel free to post a comment to this entry.

BizTalk: Architectural Tips: Custom Audit

The audit can be implemented by BizTalk Tracking (BizTalkDTADb) database.
But there is one big “But”. This database has predefined, undescribed structure, it should be used only by special BizTalk tools as HAT. We cannot change the audit points, cannot freely create user queries, cannot change structure of this database.
It is not so hard to create the custom audit, it is the standard practice to make the custom audit database and gather data for it from the BizTalk application with additions for the Orchestrations.
It is good practice to use some standard for the audit architecture. Here I give you two of them.
They are pretty easy and repeat the “Generic Error handling” pattern. They use the Direct port subscription.
I. One audit send port, the audit messages are created in different ways. All audit messages have the same message type. The Audit send port is subscribed to the one audit message type.
II. One audit send port with set of the maps, the audit messages are created by these maps.The Audit send port group is subscribed to the all audited message type.
We create the standard audit message type; send all audit messages in all audit points to the Direct send port shape; create the Direct send port with subscription to this audited message type. That is all.
[The audit points are the all audited milestones as receiving/sending themessage; transforming themessage; routing the message , etc.]
ToDo list:
  1. Create the generic_audit schema. It can, for example, include elements: “Operation datetime”, “Operation type”(Send/Receive/…), “Original message parameter (like File Name)”, “Success/Fail status”, “My_Specific_parameter” etc.
  2. Create simple maps to produce the generic_audit schema from all other messages. It is not necessarily all audit parameters be mapped from the source message. Some of them might be produced inside map or expressions, for example, the “Operation datetime” parameter.
  3. Create the Audit Send Direct port with these maps in the entry.Make filters for all audited message types, i.e. subscribe to all these message types.
  4. If we want to save the audited messages in the database: Create the Audit database. The simplest database might be with one table and one stored procedure to fill-in this table.
FYI You can see in MSDN forum (http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2452186&SiteID=1) a comment of Kent Weare [BizTalk MVP] about using BAM for auditing:

“…On at least a couple of occasions I have heard MS employees endorse BAM for auditing. We brought a Microsoft consultant to review our architecture and design with respect to auditing. He suggested we use BAM for this purpose. Note he did not endorse message body tracking inside of BAM. The other place that I have seen it endorsed is at TechEd at one of Darren Jefford’s sessions.
Without a doubt building up the required BAM infrastructure is not a trivial task(especially in an enterprise scenario). Keeping things simple is often the best solution, so I do think that you have brought up some valid points. …”

One more discussion about using HAT to tracking messages is here (http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1991237&SiteID=1).