question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Deserialize List of complex type

See original GitHub issue

I’m have very simple service that I want to port to .NET core. SoapCore is the obvious choice. But for some reason a client to the service is not able to deserialize a List<Whatever>. I don’t get any error, but the List simply contains 0 items. What I see is that on the host side, the client information is being returned. And if I use WcfTestClient, I see that the the items are there in the xml, but on the client they don’t seem to be deserialized.

Below you can see the difference between the existing WCF server response and the SoapCore powered server response. And I also added the code.

WCF:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://tempuri.org/IClientInformationService/GetClientInformationResponse</a:Action>
    <a:RelatesTo>urn:uuid:678f4e26-2364-4fbf-897c-687eae35eb2d</a:RelatesTo>
    <ActivityId CorrelationId="fb08dafd-37af-4385-9dab-c5b3096c6c3c" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">678f4e26-2364-4fbf-897c-687eae35eb2d</ActivityId>
  </s:Header>
  <s:Body>
    <GetClientInformationResponse xmlns="http://tempuri.org/">
      <GetClientInformationResult xmlns:b="http://schemas.datacontract.org/2004/07/Name.Is.Changed.To.Protect.The.Innocent" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <b:ClientInformation>
          <b:ClientId>21810</b:ClientId>
          <b:ClientName>Acme</b:ClientName>
          <b:IsActive>true</b:IsActive>
        </b:ClientInformation>
        <b:ClientInformation>
          <b:ClientId>26441</b:ClientId>
          <b:ClientName>Evil Corp</b:ClientName>
          <b:IsActive>true</b:IsActive>
        </b:ClientInformation>
        <b:ClientInformation>
          <b:ClientId>32197</b:ClientId>
          <b:ClientName>Emca</b:ClientName>
          <b:IsActive>true</b:IsActive>
        </b:ClientInformation>
      </GetClientInformationResult>
    </GetClientInformationResponse>
  </s:Body>
</s:Envelope>

SoapCore:

<s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header />
  <s:Body>
    <GetClientInformationResponse xmlns="http://tempuri.org/">
      <GetClientInformationResult xmlns:a="http://schemas.datacontract.org/2004/07/Name.Is.Changed.To.Protect.The.Innocent" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:ClientInformation>
          <a:ClientId>9</a:ClientId>
          <a:ClientName>Bad Bank Corp</a:ClientName>
          <a:IsActive>false</a:IsActive>
        </a:ClientInformation>
        <a:ClientInformation>
          <a:ClientId>10</a:ClientId>
          <a:ClientName>Good Bank Corp</a:ClientName>
          <a:IsActive>true</a:IsActive>
        </a:ClientInformation>
        <a:ClientInformation>
          <a:ClientId>11</a:ClientId>
          <a:ClientName>Berry Corp</a:ClientName>
          <a:IsActive>false</a:IsActive>
        </a:ClientInformation>
      </GetClientInformationResult>
    </GetClientInformationResponse>
  </s:Body>
</s:Envelope>

SoapCore code:

Startup:

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.TryAddSingleton<IClientInformationService, ClientInformationService>();
            services.AddMvc();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            var transportBinding = new HttpTransportBindingElement();
            var textEncodingBinding = new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, System.Text.Encoding.UTF8);
            var customBinding = new CustomBinding(transportBinding, textEncodingBinding);

            app.UseSoapEndpoint<IClientInformationService>("/ClientInformationService.svc", customBinding, SoapSerializer.DataContractSerializer);

            app.UseMvc();


            
        }
    }
IClientInformationService:

[ServiceContract]
    public interface IClientInformationService
    {
    
        [OperationContract]
        List<ClientInformation> GetClientInformation(System.Nullable<System.DateTime> lastSyncDataTime, System.DateTime currentSyncDateTime, string memberFirm, string domainAccountName, int pageNumber, int pageSize);
    }
[MessageContract]
    public partial class ClientInformation
    {
        [MessageHeader(MustUnderstand = true)]
        public string ClientId
        {
            get;
            set;
        }

        [MessageHeader(MustUnderstand = true)]
        public string ClientName
        {
            get;
            set;
        }

        [MessageHeader(MustUnderstand = true)]
        public bool IsActive
        {
            get;
            set;
        }
    }

ClientInformationService:

public class ClientInformationService : IClientInformationService
    {

        public List<ClientInformation> GetClientInformation(DateTime? lastSyncDataTime, DateTime currentSyncDateTime, string memberFirm,
            string domainAccountName, int pageNumber, int pageSize)
        {
            var clientInfo = ClientNames()
                                .Select((name, index) => new ClientInformation()
                                        {ClientId = index.ToString(), ClientName = $"{name} Corp", IsActive = index % 2 == 0})
                                .Skip(pageSize * pageNumber)
                                .Take(pageSize)
                                .ToList();

            


            return clientInfo;
        }

        private IEnumerable<string> ClientNames()
        {
            yield return "Acme";
            yield return "Banana";
            yield return "Apple";
            yield return "Cucumber";
            yield return "Pineapple";
            yield return "Bikers";
        }
    }

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:16 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
YaroslavKormushyncommented, Mar 22, 2019

I’m having a similar issue, but backwards. When sending an array of complex objects from the generated client the server deserializes them into an empty array. Root element code:

[DataContract]
public class NotificationRequest 
{
    [DataMember]
    public IEnumerable<Attachment> Attachments { get; set; }
}

Complex array type:

[DataContract]
public class Attachment 
{
    [IgnoreDataMember]
    public int Id { get; set; }

    [DataMember, Required]
    public string Name { get; set; }

    [DataMember, Required]
    public string Value { get; set; }

    [IgnoreDataMember]
    public int NotificationId { get; set; }
}

Root object is in NotificationService.Server.Service.ServiceContract namespace, the Attachment in NotificationService.Server.Data.Models. I think it might be related to that. Request xml looks like:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/INotificationService/Send</Action>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Send xmlns="http://tempuri.org/">
      <request>
        <Attachments xmlns="http://schemas.datacontract.org/2004/07/NotificationService.Server.Service.ServiceContract">
          <Attachment xmlns="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
            <Name xmlns="http://schemas.datacontract.org/2004/07/NotificationService.Server.Data.Models">as.jpg</Name>
            <Value xmlns="http://schemas.datacontract.org/2004/07/NotificationService.Server.Data.Models">123</Value>
          </Attachment>
        </Attachments>
      </request>
    </Send>
  </s:Body>
</s:Envelope>

Didn’t set any custom namespaces for the service contract.

0reactions
github-actions[bot]commented, Aug 11, 2021

This issue was closed because it has been inactive for 14 days since being marked as stale.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Deserialize a Complex JSON Object in C# .NET
In this article, we are gonig to learn how to deserialize a complex JSON object using C# as our language of choice.
Read more >
How do I deserialize a complex JSON object in C# .NET?
var jobject = JsonConvert.DeserializeObject<RootObject>(jsonstring);. You can paste the json string to here: http://json2csharp.com/ to check ...
Read more >
Deserializing The Complex JSON Object In C#
Json NuGet package in C#. In this blog, I'm going to explain how to deserialize complex object.
Read more >
Serialize and Deserialize complex JSON in Python
The conversion of data from JSON object string is known as Serialization and its opposite string JSON object is known as Deserialization. JSON ......
Read more >
Deserialize json which has a string and complex object
Hi, I am trying to deserialize a json string and write its content into a datatable. I have the following json string with...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found