WCF With GP Web Services

by Jacob 15. March 2009 12:29

I’m at Convergence this week in New Orleans. If you’re unfamiliar with the conference (and don’t want to follow the nifty link), all you really need to know is that it’s Microsoft’s convention for their business solutions products. For me, that means Dynamics Great Plains.

I bring this up because in the last session I attended yesterday, Louis Maresca mentioned a problem I remembered having with GP Web Services. GP WS has a serious problem when you first instantiate the proxy object: it can take seconds (over 30 on our older systems—I put a timer in just to verify) to instantiate the web service proxy. The reason for this is that .Net queries the service to pull down the available methods and objects on instantiation. Since there are very many of them available in GP Web Services, the query and xml serialization adds up to quite a lot.

Now, his solution was very clever, but involved creating a new web service to slim down the contract retrieval. My solution was to saddle up and use WCF. You see, WCF doesn’t do silly things like query for contracts it already knows full well about. I cracked how to use WCF with GP Web Services about a year ago and I haven’t looked back since.

In that session last night I realized that others might want to know what it took to get it working (and thus a blog post was born…) I’m not going to go though creating the WCF bit. It’s pretty straight forward and explained all over.

Crap, I find I can’t actually proceed without at least giving an overview.

  1. Right-click your project.
  2. Select “Add Service Reference”.
  3. Fill out the dialog:

GPWSServiceReference

Okay, now that I got that out of my system there are two things that prevent WCF and GP Web Services from playing nice together.

Security

Since GP WS uses your windows identity to validate things like roles and permissions, your client needs to send the correct identity or “bad things can happen”™. In VS 2005 web services, this was a simple matter of setting .UseDefaultCredentials to true. In WCF it’s a good bit more complicated. It’s a mirror of remotely printing Reporting Services using WCF, though, so techniques used there are applicable (though slightly different).

First, you have to let the binding know the correct security mode and transport. I did this in a basicHttpBinding in the <security> section:

<security mode="TransportCredentialOnly">
  <transport clientCredentialType="Ntlm" />
</security>

I came at this setting obliquely and after much trial and error. I’m not sure why clientCredentialType=“Windows” didn’t work against GP WS when it worked with Reporting Services. Probably something quirky in our environment.

This alone is not enough, however. The binding setting is just the contract. To actually use the correct credentials, your proxy has to be told what to do. Not difficult, but easy to overlook when you’re coming from a 2005 web services background. Here’s all it takes:

DynamicsGPSoapClient service = new DynamicsGPSoapClient();
service.ClientCredentials.Windows.AllowedImpersonationLevel 
    = TokenImpersonationLevel.Impersonation;

Once that’s all taken care of, you’re set to go. Those two lines of code are processed pretty much instantaneously on even our slowest clients, so problem solved. Almost.

Errors

Error handling hung me up for a while and was the final hurdle to being able to truly implement WCF with GP WS. I was so excited when I finally figured it out that I blogged it at the time. The key point is that GP WS wants to check a user’s authorization to view errors before giving up the details of what happened so you have to hit the web service again for details. Thus, while the status message is informative, you only get a GUID for detail in the initial error. This is not a bad thing, but it leads to difficulties when putting together your excuses to the user—particularly when WCF doesn’t make it easy to get at the details of an untyped FaultException.

Simple as That

From here, everything is pretty much the same. You have your objects in the domain you specified in the “Add Service Reference” dialog given above (GPService in my screenshot). Your proxy object has the methods you can use.

Tags: , , , , ,

Programming

Comments


June 24. 2009 01:07
SEO
Good post.But GP WS has a serious problem when you first instantiate the proxy object it can take seconds to instantiate the web service proxy.


June 24. 2009 03:30
Jacob
@SEO: The problem isn't GP WS. It's the .Net web service client object re-querying GP WS for the entire service contract. That's why I want to use WCF. WCF doesn't re-query GP WS for the contract information and is thus able to instantiate the client proxy object practically instantaneously.

Comments are closed

Information

    Recent Posts

    Calendar

    <<  September 2010  >>
    MoTuWeThFrSaSu
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    View posts in large calendar
    Disclaimer
    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010 Scruffy-looking Cat Herder