I have an issue in async WCF service using SoapCore in .Net 6 using a cancellation token and XmlSerializer serializer.
The detailed WCF application is as follows:
SoapCore
NuGet package using SoapSerializer.XmlSerializer
serializer[OperationContract]
attribute with a CancellationToken
parameterhttps://localhost:7026/Services.svc?WSDL
and it fails because of the CancellationToken
with the exception ArgumentException: .NET type CancellationToken cannot be resolved into XML schema type
(CancellationToken
has namespace starting with System
(System.Threading.CancellationToken
), is a structure (value type), and is categorized by SoapCore
code as very similar to bool
, int
, long
, ... and tries to generate an XML for it and it fails)[XmlIgnore]
attribute to the parameter CancellationToken
of the method having the [OperationContract]
attribute and it doesn't work[MessageContract(IsWrapped = false)]
cannot be added to parameters of methodsNote: This works with SoapCore
with SoapSerializer.DataContractSerializer
serializer, but the generated WSDL is bigger enumerating many basic types that I don't use and I want to use SoapSerializer.XmlSerializer
if possible.
Program.cs code:
using Microsoft.Extensions.DependencyInjection.Extensions;
using SoapCore;
namespace TestSoapCore;
public static class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSoapCore();
builder.Services.TryAddSingleton<MyService>();
builder.Services.AddMvc();
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.UseSoapEndpoint<MyService>(
"/Services.svc",
new SoapEncoderOptions(),
SoapSerializer.XmlSerializer
// This works with SoapSerializer.DataContractSerializer but I prefer SoapSerializer.XmlSerializer if possible
);
});
app.Run();
}
}
Contract.cs code:
using System.Runtime.Serialization;
namespace TestSoapCore;
[DataContract]
public class Contract {
[DataMember]
public string? TestProperty { get; set; }
}
MyService.cs code:
using System.ServiceModel;
using System.Xml.Serialization;
namespace TestSoapCore;
[ServiceContract]
public class MyService
{
[OperationContract]
public async Task<string> Test(
Contract contract,
// [MessageContract(IsWrapped = false)] cannot be added to parameters
[XmlIgnore] // This doesn't work
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
return contract?.TestProperty + "2";
}
}
Full exception while getting the WSDL at https://localhost:7026/Services.svc?WSDL
when SoapSerializer.XmlSerializer
serializer is used:
How the WSDL works with SoapSerializer.XmlSerializer
serializer without any CancellationToken
(but I want the CancellationToken
for async methods, it is better to have it):
How the WSDL is bloated and has many basic types I don't use when SoapSerializer.DataContractSerializer
serializer is used (that's why I still prefer SoapSerializer.XmlSerializer
if possible):
Because the CancellationToken
is not working very well with WCF using SoapCore (SoapSerializer.XmlSerializer
serializer doesn't generate the WSDL because of CancellationToken
and SoapSerializer.DataContractSerializer
serializer puts the CancellationToken
as an object that needs to be sent with many properties and their types) I ended up removing the CancellationToken
entirely and I used the SoapSerializer.XmlSerializer
to have less data (WSDL not bloated with all the unused types, many pages of useless data).
PS: This is how the CancellationToken
looks with SoapCore and SoapSerializer.DataContractSerializer
serializer (not very nice..):