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:
- WCF service in C# .Net Core 6 using
SoapCore
NuGet package usingSoapSerializer.XmlSerializer
serializer - I created an async method that has the
[OperationContract]
attribute with aCancellationToken
parameter - I try to get the WSDL using the URL
https://localhost:7026/Services.svc?WSDL
and it fails because of theCancellationToken
with the exceptionArgumentException: .NET type CancellationToken cannot be resolved into XML schema type
(CancellationToken
has namespace starting withSystem
(System.Threading.CancellationToken
), is a structure (value type), and is categorized bySoapCore
code as very similar tobool
,int
,long
, ... and tries to generate an XML for it and it fails) - I tried adding the
[XmlIgnore]
attribute to the parameterCancellationToken
of the method having the[OperationContract]
attribute and it doesn't work [MessageContract(IsWrapped = false)]
cannot be added to parameters of methods
Note: 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):
CodePudding user response:
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..):