If you’ve ever tried to write Add-ins for Microsoft Office, you know that it can be a pretty intimidating task. Sure the splash screens might look the same, but underneath, Office is a whole collection of different versions of different products, and this becomes really apparent when you look under the hood at the various API interfaces.
There have been several attempts by Microsoft to add consistency to the way that solutions are developed on the office platform (with Visual Studio Tools for Office being the latest, and probably best entry), but when it comes down to it, to deploy anything really useful, you have to resort to learning 4 different versions of 5 different object models.
Or do you? As you fumble your way through looking for sample code to make your life easier, there’s a high probability that you’ll end up on the Add-in Express site. When I first came across these guys, I checked out their claim that their product, Add-in Express, allows you to “Make office programming fast, comfortable and trouble-free”. I snorted.
“C’mon. Nothing can do that…” I then hit the back button and clicked some link to Experts-Exchange and auto-scrolled all the way to the bottom. You can’t believe everything you read on the Internet, right?
Much later, Dean found another positive review for the Add-In Express guys on StackOverflow, and as we were about to begin a new iteration of our Office add-ins, he suggested that we should give them a try. I spoke to Andrei about getting a demonstration license, and installed the toolkit to build the next version of our Outlook Add-in. Within 2 days, I was converted. Add-in Express is a remarkable piece of software.
Using Add-in Express is weird, but then, writing Office Add-ins is weird, so I guess that makes sense. Rather than have a traditional WYSIWYG designer, there is a canvas that allows you to add big icon-like controls, and then you set those controls’ properties through various properties dialogs. You handle events, write module level code, add references and any control you like.
When you’ve configured these things to your liking, you simply register the add-in from the build menu, and then start your target office application. Your add-in is configured for you. If you want to debug it, you just attach to the process, and step through your code. It has dramatically improved the reliability, speed and most importantly development time for our MS Office integration.
Add-in Express also adds a setup project to your solution, and builds you the MSI as you go. When you want to deploy your add-In, you simply run the MSI on the target machine.
Support from the Add-in Express guys via their forum was prompt and very helpful. It became patently clear to me that these guys have already fallen into, and successfully gotten out of, all of the traps, potholes and tricks that are awaiting you in the mysterious world of Office Development. If you are planning on doing some serious Office Integration, this kind of knowledge is invaluable. Highly recommended.
I spent Sunday afternoon battling an odd WCF error.
System.InvalidOperationException: Incoming message for operation [your operation here] contains an unrecognized http body format value ‘Xml’. The expected body format value is ‘Raw’. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.
Troubleshooting this issue sucked. Here’s the deal: WCF helpfully attempts to parse any incoming “text/xml” requests automatically. If you’ve defined the input parameter on a WebInvoke operation to be a Stream, WCF can’t bind to the method and returns an HTTP 400.
There’s two ways to solve this problem: Change the input parameter from Stream to XmlElement, or configure WCF to treat this request as Raw. I picked the former method. Carlos Figueira explains the latter method.
If folks are interested, I can post some more detail about the problem and the resolution. For now, I have to finish making things work.
Edit: So here’s the rest of the story, since Brad asked.
I wasn’t sure exactly what triggered the issue. I got this behavior with just one WebInvoke and one WebGet operation using the same URI template. What I’d done was to create a generic ObjectService that exposed the same RESTian operations for several different types of objects. The particular operation in question looked something like this:
PostListAsXml had accepted a Stream. That seemed to work in other places, but then I started noticing the
I think the right way to solve this problem is to follow Carlos’ advice, and create a new WebContentTypeMapper-derived class. But I didn’t have time to figure out exactly where to plug it in, and I was afraid that I might introduce other problems. I just didn’t know enough about the inner workings of WCF to know whether that was a safe operation.
Since we hadn’t shipped the interface yet, I was free to change the return type from Stream to XmlElement for the one or two WebInvoke operations that were returning errors. Fewer lines of code needed to change, and I knew I wouldn’t break anything else.
Of course, I’m probably just setting myself up for more pain down the road, but sometimes you just need to get things done, y’know?
Anyway, since I’ll likely revisit this decision in a later release, I’d love to hear what other folks did in this situation.
One of the things that I had to do in Outlook this week was to determine if an outlook MailItem is part of a conversation.
To determine if an Outlook Item is part of a Conversation, you need to look at the first 22 bytes of the hex string reported for ConversationIndex. If they are the same, then the message is part of the same conversation.
That’s all well and good, but note that this property is somewhat unreliable. For starters, in versions of outlook prior to 2003, it returned binary data, instead of a hex string (but if you’re working with versions of Outlook prior to 2003, you probably have other problems…) The other reason this property is unreliable is because it is set by the client – Outlook appends a 5 byte timestamp to the ConversationIndex when you reply. Which is cool, as long as you reply through Outlook.
But – our Infovark mail server is hosted by Google, and I occasionally use the gmail web client to reply to mail, instead of Outlook. For these conversations, when the replies were eventually retrieved into Outlook via IMAP, they ended up with unique conversationindexes, and so I couldn’t identfy them as being part of the same conversation.
In these cases, that’s where the ConversationTopic Property can help give you a clue. The ConversationTopic is the normalized subject of the message, that is, the subject without all the prefix strings (“Re:Re:” etc.) By comparing ConversationTopics, you can usually piece together the conversation, even if the ConversationIndex is not correct.
The question was: What is the best / most flexible way to have WCF output XHTML?
Here’s how we do it at Infovark. While I’m not sure that our approach is the best way, it does the job.
Our approach is to use the DataContractSerilizer to generate XML, then apply a Complied XSLT transform and return the result stream, which should now contain XHTML. Here’s a simplified version of our code:
It works for us, but if you’ve got other, better ideas, please let me know!
I know it’s possible to transmit Internet Protocol by carrier pigeon, but I’m not sure I could recommend it to our customers with a straight face. By the same token, I’m continually surprised to hear vendors and consultants insist that Web Services can be done without the web.
Yet I’ve seen that claim repeated all over the Internet. Sure, it’s true in the academic sense. Technically, there’s nothing wrong with “webless” web services, just like IP by avian carrier will eventually get the job done (though latency and packet loss are a challenge). But practically speaking, why would you use anything other than HTTP?
The “webless web services” meme has infected a number of good ideas. The SOAP standard is a case in point. At first, SOAP was a simple XML wrapper around an XML payload. (Remember when the S in SOAP stood for Simple?) Then a variety of industry heavyweights jumped on the bandwagon, and soon SOAP could be used with any protocol.
Nicholas Allen recently shared a great presentation on REST and SOA given by Stefan Tilkov at QCon. Stefan makes some great points about how RESTful web service design aligns well with the goals of Service Oriented Architecture (SOA).
Sure, you could use the WS-* stack if you like, but RESTful web architecture is a proven, scalable and truly simple approach, as long as you don’t mind having to use HTTP.
Much of the added plumbing in the WS-* stack is there to help transition older computer-to-computer network communication technologies. It allows applications that depend on CORBA or DCOM to tunnel through firewalls. But unless you’re trying to retrofit a system built before, say, 1998, you can skip all that stuff.
Wasn’t using web protocol the whole point of web services anyway? As Stefan said in his closing comments: “Protocol independence is a bug, not a feature.”
Use a RESTful architecture for new development. Put the web back in web services.