Friday, October 19, 2012

System.ServiceModel.ExceptionDetail is not marked as serializable.

I have two different environments, test and prod with the same dll:s deployed, on production, the orchestration throws an error and suspends the orchestration when it tries to serialize something after a message has been sent through the outgoing port. The receiver of the message sent to "SendGeneralLog" has successfully received the message.

I figure that this error has to do with the state serialization of the orchestration. I.e. after each send or receive operation Biztalk saves the state for normal and long-running transaction scopes.

The thing I don't understand is why a 'System.ServiceModel.ExceptionDetail' message has been created and by who? The service that the port calls do return HTTP 202 return code and has successfully saved the received message, the service do not return any soap exception. 

Please I appreciates all ideas.




xlang/s engine event log entry: Uncaught exception (see the 'inner exception' below) has suspended an instance of service 'AMRForDMS.AMRQueryCurrent(8fecfabe-9d3a-8fde-f582-660051209750)'.
The service instance will remain suspended until administratively resumed or terminated. 
If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.
InstanceId: 3080c288-758e-4cb5-8517-f325d706b9a3
Shape name: SendGeneralLog
ShapeId: e41fa0df-20ca-4149-b2fb-d5df9ec1042e
Exception thrown from: segment 15, progress 12
Inner exception: Type 'System.ServiceModel.ExceptionDetail' in Assembly 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.
        
Exception type: SerializationException
Source: mscorlib
Target Site: System.Reflection.MemberInfo[] InternalGetSerializableMembers(System.RuntimeType)
The following is a stack trace that identifies the location where the exception occured

   at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
   at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
   at Microsoft.XLANGs.Core.ObjectSerializer._serialize(Object graph, StringLookup sl)
   at Microsoft.XLANGs.Core.ObjectSerializer.SerializeStateManager(IStateManager stateMgr, StringLookup lookup)
   at Microsoft.XLANGs.Core.Service.Persist(Boolean dehydrate, Context ctx, Boolean idleRequired, Boolean finalPersist, Boolean bypassCommit, Boolean terminate)
   at Microsoft.XLANGs.Core.LongRunningTransaction.PendingCommit(Boolean ignore, XMessage msg)
   at Microsoft.XLANGs.Core.ExceptionHandlingContext.PendingCommit(Boolean ignoreCommit, XMessage msg)
   at Microsoft.BizTalk.XLANGs.BTXEngine.BTXPortBase.SendMessage(Int32 iOperation, XLANGMessage msg, Correlation[] initCorrelations, Correlation[] followCorrelations, Context cxt, Segment seg, ActivityFlags flags)
   at AMRForDMS.AMRQueryCurrent.segment15(StopConditions stopOn)
   at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)

        


Sunday, April 22, 2012

XLANGMessage mockup

If you pass Microsoft.XLANG.BaseType.XLANGMessage to a helper function from an orchestration, you probably need a mockup version of the XLANGMessage, I do not want to run the whole orchestration to test out my helper functions. I google and i found a blogpost by Mark describing how to do this.
http://biztalk-dev.blogspot.se/2009/06/unit-testing-with-xlangmessage.html

The main thing is that the class XLANGMessage is abstract and can't be instantiated, we need to make an implementation of it. Mark has mocked the basics of an concrete class that derives from XLANGMessage.

Here is a copy of Marks classes, I have also included an example where i used XSD.exe to create a serializble class of a customer message ASCC_CONTAINER. Please don't ask for ASCC_CONTAINER it's not mine to give.

My helper class need to use message.RetrieveAs(typfo(XMLDocument) conversion which I have implemented in the mockup.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.XLANGs.BaseTypes;
using System.Xml;
using System.IO;
using BiztalkHelper.UnpackBase64.Component;
using System.Xml.Serialization;

namespace BTHelperTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //Sample message
            FileStream sf = new FileStream(@"..\..\Sample\2a5e4eed-52c5-4fb6-8a1a-dadbd678bc1a.xml",FileMode.Open,FileAccess.Read);
            System.Xml.Serialization.XmlSerializer serializer = new XmlSerializer(typeof(ASCC_CONTAINER));
            ASCC_CONTAINER msg = (ASCC_CONTAINER)serializer.Deserialize(sf);

            //Create mockup with sample message
            MockXLANGMessage<ASCC_CONTAINER> ContainerMsg = new MockXLANGMessage<ASCC_CONTAINER>(msg);

            // Test Biztalk helper library
            unpackMessage objUnpack = new unpackMessage();
            XmlDocument retXML = objUnpack.unpackBase64(ContainerMsg);
        }
    }


    public class MockXLANGPart<T> : XLANGPart
    {
        T m_obj;

        public MockXLANGPart(T obj)
        {
            m_obj = obj;
        }

        public override void Dispose()
        {
        }

        public override object GetPartProperty(Type propType)
        {
            throw new NotImplementedException();
        }

        public override Type GetPartType()
        {
            throw new NotImplementedException();
        }

        public override string GetXPathValue(string xpath)
        {
            throw new NotImplementedException();
        }

        public override void LoadFrom(object source)
        {
            throw new NotImplementedException();
        }

        public override string Name
        {
            get { return "MockXLANGPart"; }
        }

        public override void PrefetchXPathValue(string xpath)
        {
            throw new NotImplementedException();
        }

        public override object RetrieveAs(Type t)
        {
            if (t == typeof(T))
            {
                return m_obj;
            }

            if (t == typeof(XmlDocument))
            {
                XmlSerializer serial = new XmlSerializer(typeof(T));
                MemoryStream memStream = new MemoryStream();
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memStream, Encoding.UTF8);
                serial.Serialize(xmlTextWriter, m_obj);
                memStream.Seek(0, System.IO.SeekOrigin.Begin);
                XmlTextReader textReader = new XmlTextReader(memStream);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(textReader);
                return xmlDoc;
            }
            return null;
        }

        public override void SetPartProperty(Type propType, object value)
        {
            throw new NotImplementedException();
        }

        public override System.Xml.Schema.XmlSchema XmlSchema
        {
            get { throw new NotImplementedException(); }
        }

        public override System.Xml.Schema.XmlSchemaCollection XmlSchemaCollection
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class MockXLANGMessage<T> : XLANGMessage
    {
        List<MockXLANGPart<T>> m_parts = new List<MockXLANGPart<T>>();

        public MockXLANGMessage(T obj)
        {
            m_parts.Add(new MockXLANGPart<T>(obj));
        }

        public override void AddPart(object part, string partName)
        {
            throw new NotImplementedException();
        }

        public override void AddPart(XLANGPart part, string partName)
        {
            throw new NotImplementedException();
        }

        public override void AddPart(XLANGPart part)
        {
            throw new NotImplementedException();
        }

        public override int Count
        {
            get { return m_parts.Count; }
        }

        public override void Dispose()
        {
        }

        public override System.Collections.IEnumerator GetEnumerator()
        {
            return m_parts.GetEnumerator();
        }

        public override object GetPropertyValue(Type propType)
        {
            throw new NotImplementedException();
        }

        public override string Name
        {
            get { return "MockXLANGMessage"; }
        }

        public override void SetPropertyValue(Type propType, object value)
        {
            throw new NotImplementedException();
        }

        public override XLANGPart this[int partIndex]
        {
            get { return m_parts[partIndex]; }
        }

        public override XLANGPart this[string partName]
        {
            get { return m_parts[0]; }
        }
    }
}


Many thanx to Mark for pointing me in the right direction.