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.

I’m writing a Soap Service to digest an XML payload that looks like this. In the header, I set SOAPAction to be http://tempuri.org/ActionOne which is also the name of the initial XML element in the payload. I’m using .NET Core 5 and the latest SoapCore NuGet package 1.1.0.29

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
    <soap:Body>
        <ActionOne xmlns="http://tempuri.org/">
            <oneString>sometext</oneString>
             <twoString>sometext</twoString>
        </ActionOne>
    </soap:Body>
</soap:Envelope>

As much as I tried looking at the sample code, the repo, and other contributors when my Service method starts the model is null. My payload is not serialized and does not bind properly it seems. Any suggestions would be appreciated.

Program.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace SoapCoreLab
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using SoapCore;
using SoapCoreLab.Services;
namespace SoapCoreLab
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSoapCore();
            services.AddScoped<ISoapService,SoapService>();
            services.AddMvc();
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseWhen(ctx => ctx.Request.Path.Value.Contains("asmx"), app2 =>
            {
                app2.UseRouting();

                app2.UseSoapEndpoint<ISoapService>("/Service.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
            });
        }
    }
}

ActionOne.cs

using System.ServiceModel;

namespace SoapCoreLab.Models
{
    [MessageContract]
    public class ActionOne
    {
        private string _oneString;
        private string _twoString;
        public ActionOne()
        {
        }
        
        [MessageBodyMember]
        public string oneString
        {
	      get
	      {
		      return _oneString;
	      }
	      set
	      {
		      _oneString = value;
	      }
        }

        [MessageBodyMember]
        public string twoString
	{
            get
            {
                return _twoString;
            }
            set
            {
		_twoString = value;
            }
        }
    }
}

ISoapService.cs

using System.ServiceModel;
using System.Threading.Tasks;

namespace SoapCoreLab.Services
{
    [ServiceContract(Namespace = "http://tempuri.org")]
    public interface ISoapService
    {
        [OperationContract]
        [XmlSerializerFormat(SupportFaults = true)]
        Task ActionOne(Models.ActionOne requestObject);
    }
}

SoapService.cs

using System.Threading.Tasks;
namespace SoapCoreLab.Services
{
    public class SoapService : ISoapService
    {
        public Task ActionOne(Models.ActionOne requestObject)
        {
           //requestObject is always null  :(
            var string1 = requestObject.oneString;
            var string2 = requestObject.twoString;
            return null;
        }
    }
}

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8

github_iconTop GitHub Comments

1reaction
lvargas99commented, May 23, 2022

Hi @andersjonsson, took your advice and cloned the code, and created a test with a payload similar to what I need. Turns out that to be able to deserialize a payload where there is one element with a number of child elements one needs to create one class for the parent element and another class for the children elements. Then the request object is basically an object that contains another object and that object’s properties contain the values of your payload. Here is the code so it can help someone else in the future. Thanks for the tips.

Payload: I sent it using Postman and added a header in postman : SOAPAction = http://tempuri.org/ActionOne

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"  >
    <soap:Body>
        <ActionOne xmlns="http://tempuri.org">
            <OneString>sometext</OneString>
            <TwoString>sometext</TwoString>
        </ActionOne>
    </soap:Body>
</soap:Envelope>

Program.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace SoapCoreLab
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using SoapCore;
using SoapCoreLab.Services;

namespace SoapCoreLab
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSoapCore();
            services.TryAddScoped<ISoapService,SoapService>();
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseSoapEndpoint<ISoapService>("/Service.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
        }
    }
}

ActionOneWrapper.cs This is the class needed for the main payload element.

using System.ServiceModel;

namespace SoapCoreLab.Models
{
    [MessageContract(IsWrapped = false)]
    public class ActionOneWrapper
    {
        [MessageBodyMember]
        public ActionOneDetails ActionOne { get; set; }	
    }
}

ActionOneDetails.cs This is the class for the interior elements in the XML

using System.Runtime.Serialization;

namespace SoapCoreLab.Models
{
    [DataContract]
    public class ActionOneDetails
    {
        [DataMember]
        public string OneString { get; set; }

        [DataMember]
        public string TwoString { get; set; }
    }
}

ActionOneResponse.cs Class for response values and validation

using System.ServiceModel;

namespace SoapCoreLab.Models
{
    public class ActionOneResponse
    {
        [MessageBodyMember]
        public string OneString { get; set; }

        [MessageBodyMember]
        public string TwoString { get; set; }
    }
}

ISoapService.cs Service interface

using SoapCoreLab.Models;
using System.ServiceModel;

namespace SoapCoreLab.Services
{
    [ServiceContract(Namespace = "http://tempuri.org")]
    public interface ISoapService
    {
        [OperationContract]
        [XmlSerializerFormat(SupportFaults = true)]
        ActionOneResponse ActionOne( ActionOneWrapper requestObject);
    }
}

SoapService.cs Service class

using SoapCoreLab.Models;
using System.ServiceModel;

namespace SoapCoreLab.Services
{
    [ServiceContract(Namespace = "http://tempuri.org")]
    public interface ISoapService
    {
        [OperationContract]
        [XmlSerializerFormat(SupportFaults = true)]
        ActionOneResponse ActionOne( ActionOneWrapper requestObject);
    }
}

0reactions
github-actions[bot]commented, Jul 7, 2022

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

Why is the view model null?
First, you need to set your logic to reach the database form your model. You could use ORM to achieve that. Then, pass...
Read more >
Null model
In mathematics, for example in the study of statistical properties of graphs, a null model is a type of random object that matches...
Read more >
Which models can handle null values?
Which models can handle null values? · decision-trees · machine-learning-model · gradient-descent.
Read more >
Model is always null on Razor page - Microsoft Q&A
hello All, I have the following code on my cshtml page: @if (Model!=null && Model.EmergencyInfos!=null && Model.EmergencyInfos.ToList().
Read more >
ASP.NET MVC Handling Null Models
If a property on a model is nullable, then it doesn't need to be bound and a blank string can be converted into...
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