views:

59

answers:

2

I'm on the other side of a BizTalk 2009 integration, and I have a fairly simple contract stood up that looks something like this:

[ServiceContract(Name = "ReceiverService", Namespace = "http://services.company.org/")]
public interface IReceiverService : ILoadBalanced
{
 [OperationContract]
 void FinishedRouting(long applicationId);

 [OperationContract]
 void ResponsePending(long applicationId, string stringId, short count);

 [OperationContract]
 void ReportException(long applicationId, string errorMessage, string stringId);

 [OperationContract]
 void SaveResponse(WebResponseDto decision);
}

However, when the BizTalk group attempts to use the WCF Service Consuming Wizard, it chokes and provides this stack trace:

[5096] System.NullReferenceException: Object reference not set to an instance of an object. 
[5096]    at Microsoft.BizTalk.Adapter.Wcf.Consuming.Exporters.BindingInfoExporter.CreatePrimaryTransport(ServiceEndpoint serviceEndpoint, Boolean custom) 
[5096]    at Microsoft.BizTalk.Adapter.Wcf.Consuming.Exporters.BindingInfoExporter.CreateSendPort(ServiceEndpoint endpoint, Port port, Boolean custom) 
[5096]    at Microsoft.BizTalk.Adapter.Wcf.Consuming.Exporters.BindingInfoExporter.Export(ServiceEndpointCollection endpoints, ServiceDescriptionCollection wsdlDocuments, Boolean custom) 
[5096]    at Microsoft.BizTalk.Adapter.Wcf.Consuming.Consumer.CreateBindingFiles(MetadataSet metadataSet, String serviceName) 

And then again here:

[5096] System.NullReferenceException: Object reference not set to an instance of an object. 
[5096]    at Microsoft.BizTalk.Adapter.Wcf.Consuming.Implementation.ClientImplementation.AddFilesToProject(String schemaNamespace) 
[5096] System.NullReferenceException: Object reference not set to an instance of an object. 
[5096]    at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous) 
[5096]    at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args) 
[5096]    at Microsoft.BizTalk.Adapter.Wcf.Consuming.Consumer.Consume(ISynchronizeInvoke synchronizeInvoke, DTE dte, MetadataSet metadataSet, Project project, String importNamespace) 

Anyone know where to start looking on this one?

A: 

WCF client applications cannot use service contracts with one-way operations to send messages to your WCF receive locations. The operations on the client-side contract should be annotated with IsOneWay=false and ReplyAction=”*”. The only exception is when you’re using NetMsmqBinding, in which case all operations on the client contract should be one-way.

Howard Edidin
+1  A: 

It might be similar to these - here and here, viz:

  • Use svcutil.exe and / or wsdl.exe against your WCF client to ensure that a proxy can be generated by a non-BizTalk client
  • Check all the WSDL to ensure target namespaces exist for all elements - in your instance, also remember to check your base contract (ILoadBalanced) and your Entities (WebResponseDto)

Can you confirm that you can use the WCF Consume Wizard on a trivial WCF service (no base interface, one Operation, string input and string return)? If not, it may be that your VS IDE is corrupt.

FWIW the void returns don't seem to be an issue - BTS creates the following response schema for void operations

  <xs:element name="GetDataResponse">
    <xs:complexType>
      <xs:sequence />
    </xs:complexType>
  </xs:element>

And placing the Contract and Base Contract interfaces in different namespaces was also OK.

However adding a non-serializable property to the DTO / entity failed both svcutil and the BizTalk WCF Wizard

HTH

namespace WcfService1
{
    [ServiceContract(Namespace = "http://someorl.org/ns1")]
    public interface IBase
    {
        [OperationContract]
        void SomeBaseMethod(int value);
    }

    [ServiceContract(Namespace = "http://someorl.org/ns2")]
    public interface IService1 : IBase
    {

        [OperationContract]
        void GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        // TODO: Add your service operations here
    }


    // Use a data contract as illustrated in the sample below to add composite types to service operations.
    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }

        //[DataMember]
        //public XmlDocument NonSerializable
        //{
        //    get;
        //    set;
        //}
    }
}
nonnb
Thanks for the thorough response! This ultimately led me to my answer...digging into the LoadBalanced contract, there was a WebGet method that ends up breaking BizTalk's import. The WCF test client can see it just fine but does put a little red exclamation point next to it...I guess BizTalk just refuses to proceed in that case.
Brandon Linton