Tuesday, March 8, 2011

Catching SOAP Faults from CRM 4.0 Web Services

A natural follow up to my BizTalk 2010: Calling Dynamics CRM 4.0 Web Services post is one that deals with the Exceptions, or Faults,  that these Web Services may return.  When using the CRM 4.0 Adapter, the adapter would take care of handling SOAP exceptions and bundling them up into a CRM Response message that had a Return Code and Error Nodes.  Whether your operation was successful or not, you could always expect the same type of response message from CRM.

<ns0:Response xmlns:ns0="http://schemas.microsoft.com/crm/BizTalkAdapter/Response">

<Header>

<ReturnCode>1</ReturnCode>

<ErrorCode />

<ErrorString />

<Retryable />

</Header>

Now that we are not using this adapter anymore we need to be able to catch our own exceptions coming out of CRM.  If we don’t perform these actions below(or similar actions) we can expect an error message like the following.

 

Inner exception: Received unexpected message type 'http://schemas.xmlsoap.org/soap/envelope/#Fault' does not match expected type 'http://schemas.microsoft.com/crm/2007/WebServices#CreateResponse'.

The issue is we have a Solicit Response Send Port in which  we are sending a typed Request message into CRM and are expecting a typed Response message in return.  When we encounter a SOAP Fault, a typed message is being returned, it just isn’t what we are expecting.  In order to avoid these situations, we need to perform the following actions within our BizTalk solution. 

Note: these actions are not specific to CRM, but may be used in other Web Service scenarios.

  • Create a multi-part message that includes a part that is of type BTS.soap_envelope_1__1.Fault.  You will find this schema in the Microsoft.BizTalk.GlobalPropertySchemas assembly.

image

  • Right mouse click on your selected operation and select “New Fault Message”

image

  • Select the Message Type to be the value of our Multi-part message that we just created.

image

  • Add a scope around your send/receive shapes.  The transaction type can be “None” and the Exception Object Type should be set to the Fault that we just created within our Operation.

image

  • So while technically this is defined as a message, within our current scope exception handler it is actually an object.  So if we wanted to dump the contents of this message to the Event Viewer we could perform the following actions by assigning the message to an XML Document and then getting the OuterXml so that we can send this text into the event viewer.

image

  • At this point we can stop if we are so inclined.  If we wanted to actually use this information in our CRM Response message we can assign this “exception” object into an instance of a message that is of the same type (our multi-part message). 
image

 

  • We then can use a Message Assignment shape to assign this object into an instance of our message.
image
  • Now that we have a typed message, we can use this message in a map to instantiate an instance of our CRM Response.  To keep things simple I am just going to concatenate the faultcode, faultstring and faultactor values and assign to the CreateResult node.  If we wanted to get the actual details out, we will need to write a .Net helper method or use XSLT to extract this content out since we have an untyped “Any” node.

image

  • After all of these changes, our Orchestration should look like this:

image

  • We can now deploy our application and test it.  In order to generate a SOAP Fault, I am going to send in the same message as in my previous post, but this time I am going to make the First Name to be greater than 50 characters.

image

  • Now when we process this message, we will not get an unhandled exception or suspended message.  Instead, we will see an informational message in our event viewer that contains the details that we are interested in.

image

  • Also, we will send this error information to a folder in the form of a CreateResponse message that will include some SOAP Fault details.

<ns0:CreateResponse xmlns:ns1="http://schemas.microsoft.com/crm/2007/CoreTypes" xmlns:ns2="http://microsoft.com/wsdl/types/" xmlns:ns3="http://schemas.microsoft.com/crm/2006/Query" xmlns:ns0="http://schemas.microsoft.com/crm/2007/WebServices" xmlns:ns4="http://schemas.microsoft.com/crm/2006/Scheduling" xmlns:ns5="http://schemas.microsoft.com/crm/2006/WebServices" xmlns:ns6="http://schemas.microsoft.com/crm/2006/CoreTypes">

<ns0:CreateResult>soap:Server - Server was unable to process request. -</ns0:CreateResult>

</ns0:CreateResponse>

 

Note: some other blog posts mention using an XPATH statement, within our WCF Send Port,  for both types of messages that we are expecting; typed CRM response and SOAP Fault.  In my scenario, this step was not required since I am expecting a typed SOAP Fault exception object within my Scope – Exception handler.

image

Monday, March 7, 2011

BizTalk 2010: Calling Dynamics CRM 4.0 Web Services

The project that I am on ran into a critical and somewhat embarrassing situation this past week.  As we moved from a single node project environment into a multi-node test environment we discovered that the Dynamics 4.0 Adapter cannot be installed on multiple BizTalk Servers in the same group.  Yes – you read that correctly.  I have never heard of this kind of limitation and struggle with the idea the adapter was actually made available without this feature.  You can read more about this limitation in the FAQ section here.

With this in mind, we needed to quickly make a 180 degree turn.  I had heard of other people calling the ASMX CRM Web Services from BizTalk via WCF Adapter.  The process of consuming these ASMX services is much like consuming any other Web Service.  That is until you start your application and get the dreaded 401 Unauthorized error. 

 

System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized

This seems like a pretty common error within the BizTalk and CRM forums.  However, I was not able find any resolutions to the issue.  It wasn’t until I started stepping through a .NET SDK sample that I realized that I was missing something and that was a required SOAP header.  For your convenience I have built an end to end sample that will walk through creating a Lead within a Dynamics 4.0 system. Keep an eye open for the Message Assignment shape where I assign this header.

  • Once we have created a BizTalk project we need to “Add Generated Items” and then select “Consume WCF Service”

image

  • Even though Dynamics 4.0 still uses ASMX style Web Services we can select “Metadata Exchange (MEX) endpoint.

image

image

  • Once the WSDL definition has been loaded, click the “Next” button to continue.
  • Click “Import” to create your schemas and sample Orchestration.
  • You should find that the following artifacts have been added to your BizTalk Solution.

image

  • Our “main” schema is called CrmService_schemas_microsoft_com_crm_2007_WebServices.xsd.  Within this schema you will find all of the available Actions (Create/Update/Delete/Fetch etc) and the related entities (both custom and out of box).  In this scenario we are going to create a “Lead” within our CRM system.  So we can find the “Create” node and then scroll down and find the “Lead” entity.

image 

image

  • To keep things simple, I have created a little helper message that I will use in a Map to create an instance of this CRM Create message.

image

  • Inside my map, I will simply map from this helper message to the actual CRM Request.

image

  • With the building blocks in place, the next step was to update the  Orchestration that was generated for us.  Pretty standard stuff going on here.  We want to receive an instance of our “helper” message, transform it, send the request to CRM and then write the response to disk. 

image

  • When we generated our CRM schemas, BizTalk also created a Port Type called “CrmServiceSoap” that contains all of the available operations including “Create”.

image

  • Earlier in this post I mentioned that we need to set a SOAP header on the CRM Request message.  In order to do this we want to add a Message Assignment shape after our Transformation shape.
    image
  • Within this shape we want to set the following:

msgCreateCustomer (WCF.OutboundCustomHeaders) = "<headers><CrmAuthenticationToken xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\"><AuthenticationType xmlns=\"http://schemas.microsoft.com/crm/2007/CoreTypes\">0</AuthenticationType><OrganizationName xmlns=\"http://schemas.microsoft.com/crm/2007/CoreTypes\">YourOrganization</OrganizationName><CallerId xmlns=\"http://schemas.microsoft.com/crm/2007/CoreTypes\">00000000-0000-0000-0000-000000000000</CallerId></CrmAuthenticationToken></headers>";

  • The two important settings are the “AuthenticationType” and the “OrganizationName” properties.    The Authentication property can take one of three values:
    • 0 – AD
    • 1 – Passport
    • 2 – Internet Facing Deployment
  • Since this is an on-premise installation we will go with 0.
  • The “OrganizationName” property becomes extremely important in multi-tenant configurations where you may have multiple organizations or departments sharing a CRM implementation.  Since we only have 1 organization in our deployment it is safe to just set our default value.
  • It is now time to deploy and configure the BizTalk application.
  • When BizTalk generated our CRM schemas and sample Orchestration, it also generated a Binding file.  When we import the binding file we will discover that two send ports have been created.  The first is a basicHttpBinding and the second send port uses a Custom Adapter with a Custom binding.  What is the difference?  Really it comes down to some addition security configuration that is available with the Custom adapter.

image

  • Using these binding as is didn’t work for me.  I needed to change the WCF-Custom Adapter to use the basicHttpBinding.  I also had to make a few Security related changes including setting the Security “mode” was set to “TransportCredentialOnly”

image

  • I also needed to set the “clientCredentialType” to “Windows”

image

  • I wasn’t quite done here.  I also need to add an Endpoint Behavior.  In this case it was a “clientCredentials” behavior.  Within this behavior, I set “Windows” - “allowedImpersonation” = “Impersonation”

image

  • At this point, I am ready to configure the rest of the application and start it.  Once started, I can process my sample helper message.
  • Within my sample file, I have provided the following information.  Once processed by BizTalk, I expect this Lead to be created within our CRM system and the CRM response to be send to disk.

image

  • The response from CRM is a GUID.

image

  • Once we launch the Dynamics CRM GUI, I am able to find my Barry Sanders record. 

image

Conclusion

If you have high-availability requirements then I highly recommend abandoning the Dynamics CRM 4.0 adapter.  Currently, and I am not sure if there are any plans, CRM 2011 does not have an adapter so now is as good as time as any to make the move.   You can read more about CRM 2011 integration on Richard Seroter’s blog.  Also look for a chapter on CRM 2011 integration in our upcoming book.

Tuesday, February 22, 2011

New BizTalk 2010 book unveiled – Line of Business Systems Integration

Received news this morning that the book that I have been working on for the past 7 months has now reached “RAW” status. What is RAW you ask? RAW stands for “Read As we Write”. The idea is to get the book, in soft copy format, into the hands of readers early. The goal is to get early feedback from readers with the possibility of incorporating this feedback before the book is published. This is a relatively new program from Packt but when it was presented to us we decided to get the book into the community sooner than later. I must caution that the book, in this format, is not the final version. Think of it as a CTP (Community Technical Preview) with the polished version of the book set for the end of April timeframe.



What is the book about?


The book primarily deals with Line of Business integration with popular LOB systems like SAP, Dynamics CRM, SalesForce.com, Dynamics AX, SQL Server and SharePoint. In addition to these chapters we also introduce the Line of Business Adapters Fundamentals and connecting to the AppFabric Service bus.



Why write another BizTalk book?


As experienced developers we understand the nuts and bolts of BizTalk. We can create Schemas, Ports, Maps and understand various BizTalk patterns. The challenge is often understanding the systems that we are integrating with. When integrating with commercial products like SAP and Dynamics there is always some pre-requisite knowledge required to effectively integrate with it. The goal of this book is to expose some of this pre-requisite knowledge so that an experienced BizTalk developer can get up to speed quickly with the technology that they need to integrate with.



Who are the authors?


I have yet to meet a person who was an expert in each of these technology areas. With this in mind a talented team of BizTalk specialists was assembled to take on this adventure including:



Technical Reviewers


Anyone who has written a book can appreciate the “unsung heroes” of a published book. The unsung heroes of this book are our Packt publishing team and Technical Reviewers. We have an outstanding roster that includes the following people:


Packt



  • Kerry George

  • Alina Lewis

  • Zainab Bagasrawala

Technical Reviewers



I can say, without any hesitation, that their efforts have significantly increased the quality of the book.



For more details on the RAW program, I encourage you to visit the PACKT website.



Stay tuned for more information as the actual published date nears.


1902en_mockupcover_normal_0

Sunday, January 2, 2011

Off Topic–Payback is a ….

So you may recall a bet that took place around the 2010 Olympic timeframe which had me, and Team Canada, matched up against fellow BizTalk MVP Mikael HÃ¥kansson and Team Sweden.  As we all know, Canada won the Olympic Gold Medal and I won the bet.

The Christmas break is well anticipated holiday for many obvious reasons in Canada.  While most people in Canada are stuck indoors for the coldest part of the year, many are glued to their television sets watching the World Junior Hockey tournament.  This tournament represents the best under 20 year old Hockey players on the the planet.  Most of these players will end up playing professional Hockey somewhere and many will make the NHL.

On December 31st, 2010, Canada squared off against Team Sweden in a round robin game.  Once again Mikael taunted me with a blog post so I couldn’t resist opening up that wound of his from earlier in the year.

This time around it is my time to eat crow.  Sweden beat Canada 6-5 in a shoot-out and in return here is my tribute to Team Sweden and Mikael.

There are still some games left and I am confident that Team Canada can pull it off. There is a good chance that Canada could play Sweden so perhaps there will be a rematch bet?

friberg_73159

Saturday, January 1, 2011

Microsoft MVP Awarded: Part 4

I recently received word that I have been re-awarded for another year.  Contributing to the BizTalk community continues to be something I enjoy and am passionate about so it is always nice to be recognized by Microsoft for my efforts.

Looking back at 2010, it sure was a busy year.  I spent a lot of time in the areas of SharePoint and SAP integration.  I attended TechEd in New Orleans where I also helped out at the BizTalk booth.  I gave a SharePoint and App Fabric Service Bus presentation to the Calgary .Net User group and had the opportunity to go to Sweden and speak about Monitoring your BizTalk environment with SCOM.  Travelling to Stockholm and spending time with Mikael HÃ¥kansson and Johan Hedberg was one of my highlights even if Mikael signed both Johan and I up for an Olympic distance triathlon.

2011 is shaping up to being just as busy if not busier than 2010.  Here are some of the things coming up for me:

  • I am currently the Integration Architect on a Dynamics CRM/Project Server 2010/SharePoint 2010/SAP project so I will continue to be very involved with integrating line of business systems.  Expect more SAP and Dynamics CRM content on this blog.  I am thinking about building a series around CRM 4.0  integration much like the ShareTalk series that I previously published on this site.
  • Speaking of Line of Business systems, the rumor is true.  I have teamed up with a group of really talented authors to write a BizTalk book.  The book will be unlike any of the current BizTalk books and will target experienced BizTalk developers.  The list of authors and technical reviewers is impressive, I am very confident that the end product will be great.  More information will be forthcoming, but you can expect the book to be available towards the end of April 2011.
  • Learning more about AppFabric is also on my “resolution” list for 2011.  While I have a very good idea of what AppFabric is and what you can do with it, I just haven’t had a lot of “hands on” experience with it.
  • While unrelated to this blog, I just love my Windows Phone 7 device and have previously written the “BizTweet” app for it.  I look to expand my skills in this area as well.  I have a couple ideas that I plan on pursuing, one that does involve BizTalk and SAP.

While no where near Seroter numbers, this blog received just over 40 000 hits over the past year, so I thank you for taking the time to stop by and read my content.  All the best for the upcoming year.

Thursday, November 18, 2010

Off Topic: Introducing BizTweet for Windows Phone 7

In addition to blogging about BizTalk, I have decided to start blogging about Windows Phone 7.  Therefore, I have created a new blog to focus on WP7 and will continue to blog about BizTalk here. 

I recently had my first WP7 App published in the marketplace.  The app is called BizTweet and may be found in the Social category.  The purpose of the application is to aggregate information related to BizTalk and AppFabric.  So if you have a WP7 and are interested in BizTalk and/or AppFabric then I encourage you to check it out. 

For more details, check out the BizTweet blog post.

Monday, October 4, 2010

BizTalk: HTTP Adapter and preventing Cached Responses

A while back I blogged about a service that would go fetch Natural Gas Prices, the price of Oil and Stock Quotes from Yahoo.    The information that is returned from BizTalk is surfaced in an Xcelsius dashboard along with a lot of other business critical data from SAP.  Our executive team accesses this information from a web part in SharePoint site.  As people launch their browsers, they see the Stock Quotes and other commodity prices get updated.  Since this is a dashboard, people will view the data for a few minutes and then close their browser.  This type of user behavior never uncovered a flaw in the application.  It is not like someone sat on the dashboard all day long waiting for the stock price to change.

A request came in to turn this Dashboard into a Windows 7 widget.  Once this widget was in place, we uncovered that the stock quotes were not being updated.   The Widget simply acts as a container for the dashboard.  So we dug out Fiddler and could determine that the BizTalk service was not being called on a regular interval.  The reason?  Caching.  There was no cache command or expiration date sent on the HTTP header going back to the dashboard so it would not be called on a regular basis.  Since this Widget does not get restarted like a Web Browser does, the stock quotes would remain static for the duration of a user’s desktop session.

To avoid this situation, I needed to provide an explicit command in a Message Assignment Shape to prevent my responses from being cached:

msgStockQuoteResponse(HTTP.UserHttpHeaders) ="Cache-Control: no-cache";

Since the client was instructed not to cache the response, it would now go ahead and call the service when it goes to refresh the rest of its data.

 

image

 

There are many options that you can set within the HTTP Header.  For example,  if you wanted to expire content every 2 minutes, you could set your header to  Cache-Control: max-age=120.  If you are interested in what other features can be set in an HTTP Header, I recommend checking out this site.