Azure / azure-functions-servicebus-extension

Service Bus extension for Azure Functions
MIT License
65 stars 36 forks source link

There was an error deserializing the object of type System.String. Unexpected end of file. #108

Closed Purbasha closed 4 years ago

Purbasha commented 4 years ago

I am trying to deserialize the body of Message, and I am getting this deserialization error. I browsed some previous issues and it looked like this issue was fixed in Microsoft.Azure.ServiceBus 4.1.1, however, I see the same issue when using the said version. I am providing the code, exception trace, a sample console app where the issue is reproducible and the library versions.

Code

image

Library versions

image

Exception stacktrace Message: System.Runtime.Serialization.SerializationException : There was an error deserializing the object of type System.String. Unexpected end of file. Following elements are not closed: . ---- System.Xml.XmlException : Unexpected end of file. Following elements are not closed: . Stack Trace: XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) DataContractSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName) DataContractBinarySerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName) XmlObjectSerializer.ReadObject(XmlReader reader, Boolean verifyObjectName) XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName) XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) XmlObjectSerializer.ReadObject(XmlDictionaryReader reader) DataContractBinarySerializer.ReadObject(Stream stream) MessageInteropExtensions.GetBody[T](Message message, XmlObjectSerializer serializer) ScheduleRollUpTests.CreateSchemaOnFirstResponse() line 81 --- End of stack trace from previous location where exception was thrown --- ----- Inner Stack Trace ----- XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3) XmlExceptionHelper.ThrowUnexpectedEndOfFile(XmlDictionaryReader reader) XmlBufferReader.ReadBytes(Int32 count) XmlBinaryReader.ReadName(StringHandle handle) XmlBinaryReader.ReadNode() XmlBinaryReader.Read() XmlBaseReader.IsStartElement() XmlBaseReader.IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri) XmlReaderDelegator.IsStartElement(XmlDictionaryString localname, XmlDictionaryString ns) XmlObjectSerializer.IsRootElement(XmlReaderDelegator reader, DataContract contract, XmlDictionaryString name, XmlDictionaryString ns) DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver) XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)

Sample app - error is reproducible

MessageReadingError.zip

Purbasha commented 4 years ago

To explain my situation, I need to write unit test for a function that is triggered on service bus message. Like this:

image

The function to be tested has the code : var str = mySbMsg.GetBody();

I cannot change that code because it is running well in prod.

However when I create the Message object from my UT and call this method passing my Message object, the GetBody extension method fails with the above exception.

This is how I create the Message object:

image

Attached a sample executable where I can reproduce the issue.

Can you please tell me how can I create the Message object so that GetBody works as expected?

Purbasha commented 4 years ago

Hi, is anyone looking into this issue?

DavidJFowler commented 4 years ago

Try this:

using System.IO;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.InteropExtensions;
using NUnit.Framework;

namespace MyUnitTests
{
    [TestFixture]
    public class Class1
    {
        [Test]
        public void MessageTest()
        {
            var content = "some string";
            using (var ms = new MemoryStream())
            {
                DataContractBinarySerializer<string>.Instance.WriteObject(ms, content);
                ms.Position = 0;
                var msg = new Message {Body = ms.ToArray()};

                var s = msg.GetBody<string>();

                Assert.That(s, Is.EqualTo(content));
            }

        }
    }
}
Purbasha commented 4 years ago

Thank you very much. works.

soninaren commented 4 years ago

Closing as resolved.