Contents tagged with Interop

  • Never, never, never do Office interop on the server

    I’ve been telling people this for years and years, and still I stepped right into the mudhole a month ago. I blame stress, but still I shouldn’t have. It’s so easy to just add the interop assemblies and off you go… until you try running your stuff on the 2008 r2 server, hosted somewhere else, with just enough user rights. And even though I managed to get the !”#!¤¤”% working after a while, I got mem-leaks and follow-up probs due to the workarounds I had to do to get the interop working in the first place.

    Then I sat down and relaxed for a minute and realized I need to do this the right way, which is the OpenXML way.

    The thing is, OpenXML is – compared to Office-interop - not easy, and the Microsoft OpenXML SDK 2.0 is just lipstick on top of the XML and some things which were so easy to do with the interop assemblies gives you nightmares to do with OpenXML. Try fill in formsfields in a protected word document for example. I ditched the SDK and ended up doing it directly against the XML directly instead.

    I also had to fill out a few Excel spreadsheets with data, which was somewhat easier to handle than the Word-story above. But I ran into problems here too, because I wanted to do such a simple thing as setting text wrap on a few cells! I don’t know, but I’m sure Microsoft could have done something better for us poor developers that need to create docs on the server! Are we supposed to spend 40% of the coding time to just create a few simple docs, just because we go the OpenXML way? There are a quite a few pages on MSDN with samples, as well as code snippets to download, but as soon as you need to do something outside the “demo-path” you’re banging your head. Maybe I’m just stupid and doesn’t get it, or maybe I’m getting grumpy, because OpenXML is not a developer-friendly framework! There, feels much better now…

    Now, for Excel spreadsheets there’s good hope because you got more than a few decent packages out there to help you out, and the best one I’ve found so far is called ClosedXML on Codeplex. It’s free and it did everything I needed to do right out of the box! It took me 5 minutes to create the 2 different spreadsheets I needed for my project, including cell formatting, text wrapping and so on. Cheers to MDeLeon for doing this!

  • WCF Client Calling ASMX Service with Soap Headers

    Need to send soap headers from WCF (Service Reference) clients to older ASMX services? The ASMX service not handling the header properly? It may have to do with namespaces being set in the soap header XML in a way differently from what the ASMX service is expecting.

    So, how do you create and add the same type of headers, with the correct namespace, in a WCF client? For every outgoing call?

    First, a simple ASMX service for your pleasure to play with:

    [WebService(Namespace = "http://tempuri.org/")]

    public class Service1 : WebService

    {

        public MyHeader myHeader;

     

        [WebMethod]

        [SoapHeader("myHeader")]

        public string HelloWorld()

        {

            if (myHeader != null)

                return "Got header: " + myHeader.MyFirstValue + " " + myHeader.MyOtherValue;

     

            return "Got no header!!";

        }

    }

    That's it on the server side. Over to the client side... Well, the header itself can be either a class which implements the MessageHeader class, but I prefer to use a normal class decorated with DataContract attribute. Notice the namespace property which matches the one on the service above:

    [DataContract(Namespace = "http://tempuri.org/")]

    public class MyHeader

    {

        [DataMember]

        public string MyFirstValue { get; set; }

        [DataMember]

        public string MyOtherValue { get; set; }

    }

    In ASMX clients you normally create a soap extension to add the header to every outgoing call, but here the ASMX soap extension is replaced by a (Client)MessageInspector in WCF, which is added to a client endpoint via a behavior. I'm cramming the whole sample implementation into one class:

    public class AddSoapHeaderBehavior : BehaviorExtensionElement, IClientMessageInspector, IEndpointBehavior

    {

        #region IClientMessageInspector Members

     

        public void AfterReceiveReply(ref Message reply, object correlationState) { }

     

        public object BeforeSendRequest(ref Message request, IClientChannel channel)

        {

            var myHeader = new MyHeader { MyFirstValue = "Yeeehaaaw!!", MyOtherValue = "Gaaah!" };

            var messageHeader = new MessageHeader<MyHeader>() { Actor = "Anyone", Content = myHeader };

     

            request.Headers.Add(messageHeader.GetUntypedHeader("MyHeader", "http://tempuri.org/"));

            return null;

        }

     

        #endregion

     

        #region IEndpointBehavior Members

     

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

        public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior) { behavior.MessageInspectors.Add(this); }

        public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher) { }

        public void Validate(ServiceEndpoint serviceEndpoint) { }

     

        #endregion

     

        #region BehaviorExtensionElement Members

     

        protected override object CreateBehavior() { return new AddSoapHeaderBehavior(); }

        public override Type BehaviorType { get { return GetType(); } }

     

        #endregion

    }

    The endpointbehavior and behaviorextensionelement member implementations are just boilerplate stuff that should be hidden as default behavior by WCF if you ask me, but you need to type this out.

    Finally, the behavior must be loaded in the config (or via code):

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

      <system.serviceModel>

        <behaviors>

          <endpointBehaviors>

            <behavior name="MyEndpointBehaviors">

              <ClientSoapHeaderAdderBehavior />

            </behavior>

          </endpointBehaviors>

        </behaviors>

     

        <extensions>

          <behaviorExtensions>

            <add name="ClientSoapHeaderAdderBehavior"

                type="MyBehavior.AddSoapHeaderBehavior, MyBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

          </behaviorExtensions>

        </extensions>

     

        <client>

          <endpoint name="Service1Soap"

                    address="http://localhost:4221/Service1.asmx"

                    binding="basicHttpBinding"

                    behaviorConfiguration="MyEndpointBehaviors"

                    contract="ClientProxy.Service1Soap" />

        </client>

      </system.serviceModel>

    </configuration>

     

    Hope it helps someone.

  • [Java][Interop] Testing WSS4J

    Long time since I wrote anything here, but I've actively started to look at what AXIS and WSS4J has to offer when it comes to do WS-Security in Java and how it interops with web services in .NET using WSE 2.0. It's taken me a while to get the Java environment up and running at home because I had to reinstall the whole box. What I've done now is I've installed Virtual PC 2004 and created an XP image with a complete Java environment

    I've downloaded and installed (so far):

    j2sdk 1.4.2_06
    tomcat
    ant
    axis
    maven (to checkout and built wss4j)
    wss4j
    cvs
    junit
    eclipse (java IDE)
    lomboz (j2ee plugin for eclipse)

    It takes a while to configure maven and all the stuff you need for it (cvs, junit and so on) and get it running and in the end I had to go into the ant script and remove the junit testing :( Biggest problem when working with Axis and Wss4j is the lack of documentation. What I'm following now when I do my experiments are some basic documentation about how to do usernametokens with wss4j written by a kind fellow in the wss4j maillinglist.

    I've just got the basic stuff working with a Java client using Axis calling a web service in tomcat using Axis too. That's the easy part, I'll now try to plug in wss4j and do usernametoken... I'll blog the results here before I go to bed :)

  • [Interop] How to Apply the Basic Profile (Web Service practices)

    Got this URL on a Microsoft seminar. Seems to contain some pretty good recommendations and best practices. Especially the chapter about "How to Apply the Basic Profile":

    This chapter details some best practice recommendations. These recommendations explain how to use Microsoft® Visual Studio® .NET to create Web services and Web service clients that conform to the Basic Profile. Some recommendations are general guidelines while others apply to particular directives in the Basic Profile. If a recommendation does apply to particular directives, their numbers are listed in square brackets after the recommendation (for example, [R1120]).

    The whole thingy is available as a pdf file too.

  • Selecting the tools before you know what your needs are

    (blowing off some steam here)

    Someone blogged earlier about selecting tools and platforms before you're sure about what your needs are. Looks like I'm going to be affected by that now. I'm one of the responsible architects for implementing a java based portal that must integrate with a document management system and a search system that knows nothing about each other, has no standard ways of plugging into each other and no one seems to have done this before. Yay! Besides, one of the requirements are to have automatic and seamless login for the windows users into the portal, which, as I said, is based on Java...

    We fixed the automatic login requirement by using JCIFS open source stuff from samba, which implements the CIFS/SMB protocol, but IMHO it's sort of a hacky way of doing it. I'm looking at replacing that part with some 3rd party access management system though... For large enterprise sized portals I prefer using a supported way of doing access, which *is* a pretty important part. No access - no portal, right?

    Well, only thing to do is just smile and dig into each product and make them talk to each other somehow. It will take much longer to implement and it won't be a standard way of integrating portals with content and search, that's for sure.

    Some people complains about the risk of "getting stuck into proprietary Microsoft products", but personally I prefer that to getting stuck into a much smaller product that once sprung up from some open source portal framework initiative and now has evolved into a monster that needs a gazillion of bytes just to wake up and start chewing request! During the time it grew from baby monster to a huge monster the owner of the pet changed a number of times and the price went from zero buckazoids to a price relative to the amount of memory needed to get it running...

    At least I got the power (in my dreams) to select the platform for building the Web Service layer we will need to integrate with other systems. I'll certainly raise my hand for .NET Web Services and use WSE 2.0 (or what there will be in ASP.NET 2.0) for security. I'll see how far AXIS and WSS4J has come...

    I need to say though, that I don't mind being involved in this project because even though that it could have been easier with other products, it's pretty fun to try to solve problems with integration, security, where to store content and how to search for it :)

    (I feel much better now, thanks)