22 April 2010

Remittance Headaches

For those of you who've worked with X12 835 Remittance documents, you may know my pain. Some time ago at work, I was tasked with finding a more efficient way to handle remittance advice documents for our clients. Since I like BizTalk, I figured this would be a good time to prove its abilities, and I got to work. In short order, I was able to write the remits to a set of tables. With one, teensy problem. BizTalk is (necessarily) unaware of Database relationships. Using the WCF LOB Adapters for BizTalk worked for blowing the information into the DB very quickly, but I couldn't find a way to maintain referential integrity among the tables. Eventually I decided on an "organic key" made up progressively larger strings as one walks down the tables. So, for instance, a Claim Group (LX, TS3, and TS2 segments) would refer back the check on which they're found by using a string made up of the ST02 segment and the Check number. A Claim Payment record would refer back to the claim group by adding onto it the LX identifier and so forth. This works very well, actually, and if I know exactly the check number I want, I can find it very quickly. However, this doesn't actually take care of all of our problems. Those pesky end users want -gasp - to be able to search for remits by Patient! or Provider! What are they thinking?!?! So, I have to fix my database. But how? I mean, I still haven't found a way for BizTalk to keep that referential integrity for me, and having BizTalk pass the 835 to a .NET application kind of defeats the purpose, so what to do? Barring some divine (or reader) intervention, I've settled on this: I'm writing a .NET application which will bundle up remits at the batch level (that is, i have batch object which contains my batch data as well as a list of check objects, which, in turn, hold my check data and a list of claim group objects, and so forth). Once that is done, I'll write the records into a new database (probably nightly?) in a fashion which can be aware of record identities and referential integrity. Please, if anyone has a better option, email me or leave it in the comments- it would be a God-send.

20 April 2010

XML: Nillable="True" vs MinOccurs="0"

This came up at work today, as a coworker was strugling with a WSDL for an outside vendor. I only knew it because BizTalk runs into exactly this kind of error occassionally. The situation is this: A WSDL is defined with several elements. Let's use this for an example:

What you see here is a bunch of elements in an which my coworker is trying to show as null by not including. That is, when, for instance, "address" is null, it simply will not exist in the XML document. Here's how the same code looks as our vendor expects it.

Now, leaving aside the question of why the only way to pass data to the web method is allowed to be null, we can see that the vendor's wsdl expects the nodes to exist. Therefore, instead of simply leaving out "address" the XML document should contain a node like this: <> It makes sense when you think about it in terms of code as well. How many times in C# do we pass something like "foo = new foo(new bar(), null)?" Is there any question that this is different from "foo = new foo(new bar())"? Not really. (At least, not until C# 2zillion when Microsoft decides that any parameter which can accept a NULL is automatically an optional parameter.) I did manage to help steer the coworker in the right direction, and provided him (as I am you) a pretty good synopsis on this whole thing from IBM's website. Link here. (http://www.ibm.com/developerworks/xml/library/ws-tip-null.html) So, in summary, pay attention to your WSDL and Schemas. Nillable is not the same as MinOccurs="0".

07 April 2010

MS .Toolbox

I've been working my way (slowly) through Microsofts new http://www.microsoft.com/design/toolbox/ site. For anyone who wants to know more about UI design (which should be every Mid-tier and back-end developer everywhere), it's a really good resource. But it brings me to something I see to much in the developer world: the idea that if the "functionality" works, UI doesn't matter. "Just give 'em a button" seems to be the mantra all too often. My take on it, however, is this: If the User can't make it do what it's supposed to, or if the user decides the old way was easier than your new way, your program doesn't work. The UI is how the users interact with your functionality; if it's not good, then it's bad. There is no middle ground. With WPF and Silverlight, this consideration has become much easier to handle. Simply implement INotifyPropertyChanged on your Business Layer objects, and then use MVVM to set up the UI. However, for people not using WPF or Silverlight, some consideration has to be made at design time for how the UI will look. If you'll be populating a ListBox control, you probably need a collection of some kind, for instance. This is a place where I've fallen down in the past, and I plan not to do so any more. You should make a similar pledge.

06 April 2010

WCF WTF: Update

I attempted the solution I discovered yesterday when I got into work this morning, and it wasn't working either. I did a little more research and discovered that, for WCF to work with Streams, you really need to pass them via a BasicHttpBinding. As I'm not that great at WCF yet, I've been using the default WSHttpBinding that Visual Studio creates when you add a Service Reference. I didn't really want to spend too much more time working on this- we were already getting to the point of "diminishing returns." So I decided to take stock of where I was and move forward. The OperationContract was defined as a Stream output with a Stream input. However, since I know that a Stream is really just an Array of Bytes, I decided on an alternative approach. I created a new OperationContract (called DecryptBytes) which accepts (and returns) an array of bytes. Then, in my .svc.cs file, I created the new method which really just changes the bytes into a MemoryStream, and then hands the memory stream to my original method: public byte[] DecryptBytes(byte[] inStream) { MemoryStream _iBytes = new MemoryStream(inStream); MemoryStream _oBytes = this.Decrypt((Stream)_iBytes) as MemoryStream; return _oBytes.ToArray(); } So, for 5 lines of code (including the Attribute Tag in the Service Contract, and the Method declarations) I was able to correct the issue. I feel a little silly that it was that hard to figure out, but I'll chalk it up as "lesson learned" and archive it here in case I need it again...

05 April 2010

WCF WTF

So, I have a WCF Service I created to handle PGP encryption/decryption using the BouncyCastle .dll. We wanted just the one, internal, service so that everyone who needs to be able to decrypt data can without having to ask the developers all the time. This service receives and passes streams of data. Unfortunately, I did not realize that this doesn't actually work real well in WCF. Unless I can find a way around it, WCF changes my nice FileStream or even just a base Stream and hides it in a System.ComponentModel.Dispatcher.StreamFormatter (from memory, so that namespace may be a little off). Which is not seekable. My service requires a seekable stream. I'm sure you see the problem. I didn't discover this little gem until about time to go home today. So, tomorrow I'll write a nice little wrapper around the stream that gets passed into the service so I can treat it as a normal stream. I'll post the code here when that's done, so I'll have it someplace relatively safe.

26 August 2009

AWOL

"So," I hear you asking, "Where have you been for three months?" And I answer, Nursing my wife through the last two months of pregnancy, and welcoming my second child (Emily Marie) into the world. So I've had more important things on my mind than this blog. I'll be getting back to the "regularly scheduled" stuff pretty soon, but I wanted to go ahead and chart out some of what I'll be posting about in the next few weeks so I don't forget. So, here's the list: * BizTalk 101 * Pipelines * Adapters / Accelerators * Basic Architecture * EDI 101 * Internal Standards * External Standards * SOP * New work project So, here's hoping I'll be able to get this back up and running...

09 June 2009

Well, Gee...

So, at work I've been trying to get a BizTalk solution together- both to alleviate some actual pain points and as a 'proof of concept' and it's been a real pain in the donkey. It took much longer than it should have to get BizTalk installed and configured, but we finally did it, and now I'm actually coding the solution. Yipee for me. Mostly it's going ok, but I keep running into things which make me wish (again) that I had some kind of formal training. I'm sure these questions are basic, BizTalk 101 type questions, but I can't find the answers anywhere- or, at least, not illustrated well enough to teach the concept. So, dear reader, I'm wondering if you can help me. Below is my list of "Man I wish I knew" for BizTalk:
  • how to: evaluate the inbound filename of a file and make a decision based on that
  • how to: establsih and use a Send Port Group
  • if multiple send groups are necessary for different types of send ports (e.g. SQL Adapter vs. FILE)
  • best practice for sending results to SQL for update, and archive file to seperate folder.
  • how to: use SQL Send Adapater
  • how to: set up SQL Stored Procedure to INSERT or UPDATE DB instead of only querying
  • how to: Configure a .NET assembly/class for use with BizTalk and call it from an orchestration