Giter VIP home page Giter VIP logo

soapcore's Introduction

SoapCore

NuGet Version Stack Overflow

SOAP protocol middleware for ASP.NET Core

Based on Microsoft article: Custom ASP.NET Core Middleware Example.

Support ref\out params, exceptions. Works with legacy SOAP\WCF-clients.

Getting Started

Requirements

The following frameworks are supported:

  • .NET 5.0-7.0 (using ASP.NET Core 5.0-7.0)
  • .NET Core 3.1 (using ASP.NET Core 3.1)
  • .NET Standard 2.0-2.1 (using ASP.NET Core 2.1)

Installing

PM> Install-Package SoapCore

There are 2 different ways of adding SoapCore to your ASP.NET Core website. If you are using ASP.NET Core 3.1 or higher with endpoint routing enabled (the default):

In Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSoapCore();
    services.TryAddSingleton<ServiceContractImpl>();
    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseRouting();

    app.UseEndpoints(endpoints => {
        endpoints.UseSoapEndpoint<ServiceContractImpl>(opt =>
	{
		opt.Path = "/ServicePath.asmx",
		opt.SoapSerializer = SoapSerializer.DataContractSerializer
	});
    });
    
}

If you are using ASP.NET Core 2.1 (i.e., on .NET Framework, .NET Core 2.1, or another .NET Standard 2.0 compliant platform):

public void ConfigureServices(IServiceCollection services)
{
    services.AddSoapCore();
    services.TryAddSingleton<ServiceContractImpl>();
    services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSoapEndpoint<ServiceContractImpl>("/ServicePath.asmx", new SoapEncoderOptions());
}

Using with custom implementation of Serialization

There is an optional feature included where you can implment the ISoapCoreSerializer to built your own custom serializar for body.

In Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSoapCore();
    services.TryAddSingleton<ServiceContractImpl>();
    services.AddCustomSoapMessageSerializer<CustomeBodyMessageSerializerImpl>();  //Add Your Custom Implementation or Extend Default Serializer

    services.AddMvc();
    ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSoapEndpoint<ServiceContractImpl>(soapCoreOptions =>
    {
        soapCoreOptions.Path = "/ServicePath.asmx";
        soapCoreOptions.UseCustomSerializer<CustomeBodyMessageSerializerImpl>();  //Specify the Service to Use Service Soap Message Serializer
        soapCoreOptions.SoapSerializer = SoapSerializer.DataContractSerializer;
        ...
    });
}

Using with legacy WCF/WS

It is possible to use SoapCore with .NET legacy WCF and Web Services, both as client and service.

Primary point here is to use XmlSerializer and properly markup messages and operations with xml serialization attributes. You may use legacy pre-generated wrappers to obtain these contracts or implement them manually. Extended example is available under serialization tests project.

Using with external WSDL / XSD schemas

There is an optional feature included where you can instead of generating service description from code get the service description from files stored on the server.

To use it, add a setting like this to appsettings

"FileWSDL": {
  "UrlOverride": "",
  "SchemeOverride": "",
  "VirtualPath": "",
  "WebServiceWSDLMapping": {
    "Service.asmx": {
      "UrlOverride": "Management/Service.asmx",
      "WsdlFile": "snapshotpull.wsdl",
      "SchemaFolder": "Schemas",
      "WsdlFolder": "Schemas"
    }
  }
}
  • UrlOverride - can be used to override the URL in the service description. This can be useful if you are behind a firewall.
  • SchemeOverride - can be used to override the HTTP Scheme in the service description. This can be useful if you are behind a firewall and the firewall sets the X-Forwarded-Host header, but the internal HTTP scheme is not the same as the external.
  • VirualPath - can be used if you like to add a path between the base URL and service.
  • WebServiceWSDLMapping
    • UrlOverride - can be used to override the URL for a specific WSDL mapping. This can be useful if you want to host different services under different folder.
    • Service.asmx - is the endpoint of the service you expose. You can have more than one.
    • WsdlFile - is the name of the WSDL on disc.
    • SchemaFolder - if you import XSD from WSDL, this is the folder where the Schemas are stored on disc.
    • WsdlFolder - is the folder that the WSDL file is stored on disc.

To read the setting you can do the following

In Startup.cs:

var settings = Configuration.GetSection("FileWSDL").Get<WsdlFileOptions>();

// For case-insensitive mapping, if you are using "SoapCoreOptions.CaseInsensitivePath = true" - otherwise URLs with different casing won't be mapped correctly
//var settings = Configuration.GetSection("FileWSDL").Get<WsdlFileOptionsCaseInsensitive>();

settings.AppPath = env.ContentRootPath; // The hosting environment root path
...

app.UseSoapEndpoint<ServiceContractImpl>("/Service.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer, false, null, settings);

If the WsdFileOptions parameter is supplied then this feature is enabled / used.

References

Tips and Tricks

Extending the pipeline

In your ConfigureServices method, you can register some additional items to extend the pipeline:

  • services.AddSoapMessageInspector() - add a custom MessageInspector. This function is similar to the IDispatchMessageInspector in WCF. The newer IMessageInspector2 interface allows you to register multiple inspectors, and to know which service was being called.
  • services.AddSingleton() - add a custom OperationInvoker. Similar to WCF's IOperationInvoker this allows you to override the invoking of a service operation, commonly to add custom logging or exception handling logic around it.
  • services.AddSoapMessageProcessor() - add a custom SoapMessageProcessor. Similar to ASP.NET Cores middlewares, this allows you to inspect the message on the way in and out. You can also short-circuit the message processing and return your own custom message instead. Inspecting and modifying HttpContext is also possible

Using ISoapMessageProcessor()

//Add this to ConfigureServices in Startup.cs

services.AddSoapMessageProcessor(async (message, httpcontext, next) =>
{
	var bufferedMessage = message.CreateBufferedCopy(int.MaxValue);
	var msg = bufferedMessage.CreateMessage();
	var reader = msg.GetReaderAtBodyContents();
	var content = reader.ReadInnerXml();

	//now you can inspect and modify the content at will.
	//if you want to pass on the original message, use bufferedMessage.CreateMessage(); otherwise use one of the overloads of Message.CreateMessage() to create a new message
	var message = bufferedMessage.CreateMessage();

	//pass the modified message on to the rest of the pipe.
	var responseMessage = await next(message);

	//Inspect and modify the contents of returnMessage in the same way as the incoming message.
	//finish by returning the modified message.

	return responseMessage;
});

How to get custom HTTP header in SoapCore service

Use interface IServiceOperationTuner to tune each operation call.

Create class that implements IServiceOperationTuner. Parameters in Tune method:

  • httpContext - current HttpContext. Can be used to get http headers or body.
  • serviceInstance - instance of your service.
  • operation - information about called operation.
public class MyServiceOperationTuner : IServiceOperationTuner
{
    public void Tune(HttpContext httpContext, object serviceInstance, SoapCore.ServiceModel.OperationDescription operation)
    {
        if (operation.Name.Equals("SomeOperationName"))
        {
            MyService service = serviceInstance as MyService;
            string result = string.Empty;

            StringValues paramValue;
            if (httpContext.Request.Headers.TryGetValue("some_parameter", out paramValue))
            {
                result = paramValue[0];
            }

            service.SetParameterForSomeOperation(result);
        }
    }
}

Register MyServiceOperationTuner in Startup class:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // ...
        services.AddSoapServiceOperationTuner(new MyServiceOperationTuner());
        //...
    }
    // ...
}

Change your service to get the possibility to store information from http headers:

public class MyService : IMyServiceService
{
    // Use ThreadLocal or some of thread synchronization stuff if service registered as singleton.
    private ThreadLocal<string> _paramValue = new ThreadLocal<string>() { Value = string.Empty };

    // ...

    public void SetParameterForSomeOperation(string paramValue)
    {
        _paramValue.Value = paramValue;
    }

    public string SomeOperationName()
    {
        return "Param value from http header: " + _paramValue.Value;
    }
}

Additional namespace declaration attributes in envelope

Adding additional namespaces to the SOAP Envelope can be done by populating SoapEncoderOptions.AdditionalEnvelopeXmlnsAttributes parameter.

....
endpoints.UseSoapEndpoint<IService>(opt =>
{
	opt.Path = "/ServiceWithAdditionalEnvelopeXmlnsAttributes.asmx";
	opt.AdditionalEnvelopeXmlnsAttributes = new Dictionary<string, string>()
	{
		{ "myNS", "http://schemas.someting.org" },
		{ "arr", "http://schemas.microsoft.com/2003/10/Serialization/Arrays" }
	};
});
...

This code will put xmlns:myNS="... and xmlns:arr="... attributes in Envelope and message will look like:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" ... xmlns:myNS="http://schemas.someting.org" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
...
    <myNS:StringList>
        <arr:string>Error: one</arr:string>
        <arr:string>Error: two</arr:string>
    </fin:StringList>
...

instead of:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" ... >
...
    <d3p1:StringList xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
        <d4p1:string>Error: one</arr:string>
        <d4p1:string>Error: two</arr:string>
    </d3p1:StringList>
...

Not implemented

WCF and legacy WebService supports many scenarios and lots of attributes. SoapCore only supports the most common patterns. Stuff that are not supported includes:

  • XmlIncludeAttribute/SoapIncludeAttribute
  • SoapDocumentMethodAttribute

Contributing

See Contributing guide

Contributors

Made with contributors-img.

soapcore's People

Contributors

agpreynolds avatar akshaybheda avatar aleksanderis avatar andersjonsson avatar ankitkmrpatel avatar artsiomkazlouski avatar cjspx avatar cubidobusinesssolutions avatar dmitrybryluk avatar eamonhetherton avatar itn3000 avatar itssimple avatar ivanleonenko avatar johnnyborov avatar jonas-jaderberg avatar kotovaleksandr avatar marcjonesuk avatar mhartmair-cubido avatar microknights avatar nikermrnd avatar oruchreis avatar petarpetrovt avatar richardgergely avatar shingoaoyama1 avatar simonsoanes avatar therealslouchy avatar tibel avatar tomheijmans avatar vidrenning avatar yozer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

soapcore's Issues

Running WCF Test Client not supported

I cloned the latest SoapCore repository; ran the Server project; and tied to connect to it with the WFC Test Client. I received the error: Failed to add the service. Does your solution not support the full Soap protocol? How hard would it be to implement code to connect with WCF Test Client and show the WSDL in the browser at the URL?

Error: Cannot obtain Metadata from http://localhost:5050/Service.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: http://localhost:5050/Service.svc Metadata contains a reference that cannot be resolved: 'http://localhost:5050/Service.svc'. The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: ' <title>Internal Server Error</title> <style> body { font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif; font-size: .813em; color: #222; background-color: #fff;}h1, h2, h3, h4, h5 { /font-family: 'Segoe UI',Tahoma,Arial,Helvetica,sans-serif;/ font-weight: 100;}h1 { color: #44525e; margin: 15px 0 15px 0;}h2 { margin: 10px 5px 0 0;}h3 { color: #363636; margin: 5px 5px 0 0;}code { font-family: Consolas, "Courier New", courier, monospace;}body .titleerror { padding: 3px 3px 6px 3px; display: block; font-size: 1.5em; font-weight: 100;}body .location { margin: 3px 0 10px 30px;}#header { font-size: 18px; padding: 15px 0; border-top: 1px #ddd solid; border-bottom: 1px #ddd solid; margin-bottom: 0;} #header li { display: inline; ma'. The remote server returned an error: (500) Internal Server Error.HTTP GET Error URI: http://localhost:5050/Service.svc There was an error downloading 'http://localhost:5050/Service.svc'. The request failed with the error message:-- <title>Internal Server Error</title> <style> body { font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif; font-size: .813em; color: #222; background-color: #fff;}h1, h2, h3, h4, h5 { /font-family: 'Segoe UI',Tahoma,Arial,Helvetica,sans-serif;/ font-weight: 100;}h1 { color: #44525e; margin: 15px 0 15px 0;}h2 { margin: 10px 5px 0 0;}h3 { color: #363636; margin: 5px 5px 0 0;}code { font-family: Consolas, "Courier New", courier, monospace;}body .titleerror { padding: 3px 3px 6px 3px; display: block; font-size: 1.5em; font-weight: 100;}body .location { margin: 3px 0 10px 30px;}#header { font-size: 18px; padding: 15px 0; border-top: 1px #ddd solid; border-bottom: 1px #ddd solid; margin-bottom: 0;} #header li { display: inline; margin: 5px; padding: 5px; color: #a0a0a0; cursor: pointer; } #header .selected { background: #44c5f2; color: #fff; }#stackpage ul { list-style: none; padding-left: 0; margin: 0; /border-bottom: 1px #ddd solid;/}#stackpage .details { font-size: 1.2em; padding: 3px; color: #000;}#stackpage .stackerror { padding: 5px; border-bottom: 1px #ddd solid;}#stackpage .frame { padding: 0; margin: 0 0 0 30px;} #stackpage .frame h3 { padding: 2px; margin: 0; }#stackpage .source { padding: 0 0 0 30px;} #stackpage .source ol li { font-family: Consolas, "Courier New", courier, monospace; white-space: pre; background-color: #fbfbfb; }#stackpage .frame .source .highlight li span { color: #FF0000;}#stackpage .source ol.collapsible li { color: #888;} #stackpage .source ol.collapsible li span { color: #606060; }.page table { border-collapse: separate; border-spacing: 0; margin: 0 0 20px;}.page th { vertical-align: bottom; padding: 10px 5px 5px 5px; font-weight: 400; color: #a0a0a0; text-align: left;}.page td { padding: 3px 10px;}.page th, .page td { border-right: 1px #ddd solid; border-bottom: 1px #ddd solid; border-left: 1px transparent solid; border-top: 1px transparent solid; box-sizing: border-box;} .page th:last-child, .page td:last-child { border-right: 1px transparent solid; }.page .length { text-align: right;}a { color: #1ba1e2; text-decoration: none;} a:hover { color: #13709e; text-decoration: underline; }.showRawException { cursor: pointer; color: #44c5f2; background-color: transparent; font-size: 1.2em; text-align: left; text-decoration: none; display: inline-block; border: 0; padding: 0;}.rawExceptionStackTrace { font-size: 1.2em;}.rawExceptionBlock { border-top: 1px #ddd solid; border-bottom: 1px #ddd solid;}.showRawExceptionContainer { margin-top: 10px; margin-bottom: 10px;}.expandCollapseButton { cursor: pointer; float: left; height: 16px; width: 16px; font-size: 10px; position: absolute; left: 10px; background-color: #eee; padding: 0; border: 0; margin: 0;} </style>

An unhandled exception occurred while processing the request.

XmlException: Unexpected end of file.

System.Xml.EncodingStreamWrapper.ReadBOMEncoding(bool notOutOfBand)

  • Stack
  • Query
  • Cookies
  • Headers
  • XmlException: Unexpected end of file.

    • System.Xml.EncodingStreamWrapper.ReadBOMEncoding(bool notOutOfBand)

    • System.Xml.EncodingStreamWrapper..ctor(Stream stream, Encoding encoding)

    • System.Xml.XmlUTF8TextReader.SetInput(Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose onClose)

    • System.ServiceModel.Channels.TextMessageEncoderFactory+TextMessageEncoder.ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)

    • SoapCore.SoapEndpointMiddleware+d__7.MoveNext() in SoapEndpointMiddleware.cs

      +
      1. private async Task ProcessOperation(HttpContext httpContext, IServiceProvider serviceProvider)
      2. {
      3. Message responseMessage;
      4. // Read request message
      1. var requestMessage = _messageEncoder.ReadMessage(httpContext.Request.Body, 0x10000, httpContext.Request.ContentType);
      1. var soapAction = httpContext.Request.Headers["SOAPAction"].ToString().Trim('"');
      2. if (!string.IsNullOrEmpty(soapAction))
      3. {
      4. requestMessage.Headers.Action = soapAction;
      5. }
    • System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

    • System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

    • System.Runtime.CompilerServices.TaskAwaiter.GetResult()

    • SoapCore.SoapEndpointMiddleware+d__5.MoveNext() in SoapEndpointMiddleware.cs

      +
      1. if (httpContext.Request.Query.ContainsKey("wsdl"))
      2. {
      3. responseMessage = ProcessMeta(httpContext, serviceProvider);
      4. }
      5. else
      6. {
      1. responseMessage = await ProcessOperation(httpContext, serviceProvider);
      1. }
      2. }
      3. else
      4. {
      5. await _next(httpContext);
      6. }
    • System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

    • System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

    • Microsoft.AspNetCore.SpaServices.Webpack.ConditionalProxyMiddleware+d__6.MoveNext()

    • System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

    • System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

    • Microsoft.AspNetCore.SpaServices.Webpack.ConditionalProxyMiddleware+d__6.MoveNext()

    • System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

    • System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

    • Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+d__7.MoveNext()


  • Show raw exception details
    System.Xml.XmlException: Unexpected end of file.   at System.Xml.EncodingStreamWrapper.ReadBOMEncoding(Boolean notOutOfBand)   at System.Xml.EncodingStreamWrapper..ctor(Stream stream, Encoding encoding)   at System.Xml.XmlUTF8TextReader.SetInput(Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose onClose)   at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.ReadMessage(Stream stream, Int32 maxSizeOfHeaders, String contentType)   at SoapCore.SoapEndpointMiddleware.d__7.MoveNext() in C:\git\CEA\SoapCore\SoapEndpointMiddleware.cs:line 73--- End of stack trace from previous location where exception was thrown ---   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()   at SoapCore.SoapEndpointMiddleware.d__5.MoveNext() in C:\git\CEA\SoapCore\SoapEndpointMiddleware.cs:line 42--- End of stack trace from previous location where exception was thrown ---   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)   at Microsoft.AspNetCore.SpaServices.Webpack.ConditionalProxyMiddleware.d__6.MoveNext()--- End of stack trace from previous location where exception was thrown ---   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)   at Microsoft.AspNetCore.SpaServices.Webpack.ConditionalProxyMiddleware.d__6.MoveNext()--- End of stack trace from previous location where exception was thrown ---   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()

No QueryString data.

No cookie data.

Variable Value
Connection Keep-Alive
Host localhost:35536
MS-ASPNETCORE-TOKEN 5448f21e-e110-4c41-91f1-5962096ad4be
User-Agent Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.8794)
X-Original-For 127.0.0.1:48602
X-Original-Proto http
<script> // </script> --.

Going to the URL /Server.svc in a browser I get the Error:
An unhandled exception occurred while processing the request.

XmlException: Unexpected end of file.
System.Xml.EncodingStreamWrapper.ReadBOMEncoding(bool notOutOfBand)

Stack Query Cookies Headers
XmlException: Unexpected end of file.
System.Xml.EncodingStreamWrapper.ReadBOMEncoding(bool notOutOfBand)
System.Xml.EncodingStreamWrapper..ctor(Stream stream, Encoding encoding)
System.Xml.XmlUTF8TextReader.SetInput(Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose onClose)
System.ServiceModel.Channels.TextMessageEncoderFactory+TextMessageEncoder.ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
SoapCore.SoapEndpointMiddleware+d__7.MoveNext() in SoapEndpointMiddleware.cs
+
var requestMessage = _messageEncoder.ReadMessage(httpContext.Request.Body, 0x10000, httpContext.Request.ContentType);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
SoapCore.SoapEndpointMiddleware+d__5.MoveNext() in SoapEndpointMiddleware.cs
+
responseMessage = await ProcessOperation(httpContext, serviceProvider);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.SpaServices.Webpack.ConditionalProxyMiddleware+d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.SpaServices.Webpack.ConditionalProxyMiddleware+d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+d__7.MoveNext()

Show raw exception details

Namespace Prefix

I'd need to generate a namespace prefix for the response object. The sample response object has the namespace as an attribute in the response object, however i need to use a prefix instead.

This is a sample of my object using a [ServiceContract(Namespace=@"http://freshfighter.net/text.xsd")] attribute.

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <testResponse xmlns="http://freshfighter.net/test.xsd">
            <message>Hello</message>
        </testResponse>
    </s:Body>
</s:Envelope>

The following is what I would like the response object to look like.

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://freshfighter.net/test.xsd">
    <s:Body>
        <ns1:testResponse>
            <ns1:message>Hello</ns1:message>
        </ns1:testResponse>
    </s:Body>
</s:Envelope>

I was able to make the SoapCore generate the about response object by adding the following code to the CustomMessage class.

protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer) {
  ...
  writer.WriteXmlnsAttribute("ns1", "http://freshfighter.net/test.xsd");
  ..
}

Obviously this is just a quick hack! I would like to be able to generate the above Response using an attribute on the service contract, but it doesn't appear to be away to specify a prefix or the ability to tell the serialiser to put the namespace at the Envelope level.

I was thinking that I could create a PR and provide a new Attribute that can be used along with ServiceContractAttribute and the code to use the attributes when serialising the message. Is this the best way to go about this? Would such a PR get accepted or be useful for anybody else?

Thanks

Brent

wsdl void

Hi,

please support void functions in wsdl generation. Currently, this throws an exception:

System.ArgumentException occurred
  HResult=0x80070057
  Message=.NET type Void cannot be resolved into XML schema type
  Source=cubido.Common.AspNetCore.Soap
  StackTrace:
   at SoapCore.MetaBodyWriter.ResolveType(String typeName) in MetaBodyWriter.cs:line 413

Best regards
Markus

Complex model with namespaces

Hi!
I have a issue on complex model deserialization, but when I remove namespaces it works! But originally I can't remove them because this XML is incoming

Here is the XML I'm using:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> </s:Header> <s:Body> <ns0:SomeRequest xmlns:ns0="http://www.SomeRequest.lv/SomeRequestService" xmlns:ns1="http://SomeRequest.lv/commonheader"> <ns0:Data> <ns0:AACreateSomeRequest xmlns:reqdt="http://aaa.lv" xmlns:memdt="http://bbbb.lv"> <memdt:Meow>Dirsa</memdt::Meow> </ns0:AACreateSomeRequest> </ns0:Data> </ns0:SomeRequest> </s:Body> </s:Envelope>
And these are the models:
[DataContract] public class Data { [DataMember] public AACreateSomeRequest AACreateSomeRequest { get; set; } }
[DataContract] public class AACreateSomeRequest { [DataMember] public string Meow { get; set; } }

Maybe I'm doing it wrong or maybe not bet for me this model complexity not working. :/
In UseSoapEndpoint I have SoapSerializer.XmlSerializer

WSDL reply

Hello. I have just moved my code from ASP .NET Forms to ASP .NET Core 2. To create XML web service I have used your component.

Now I am comparing reply from my old service.asmx?WSDL and new service.asmx and see several differences. The main difference is XML header. In old project all data was included in tag while in new reply this tag is missed.

As result I can not add link to this service from visual studio 2017 while I was able to to so in old asp .net forms project.

I dont shure the problem is in <?xml> tag. May be you can give me advice how to make new soap service (based on your component) to be linked to other .NET projects

How do you use SoapCore with a webservice?

Hi
came across this project in the search for something that I could call old webservices.

Now provided I have a webservice that I have no control over EG http://www.dneonline.com/calculator.asmx

how do I code soapcore from my webapi(vs2017) to call this webservice?
also in some of these old webservices there are out parameters .
Does it handle them?

thanks for your time

Support ValueKeyPair in wsdl generation

I'm using public List<KeyValuePair<string, string>> Properties { get; set; } for one of my properties, and when trying to generte the wsdl I'm getting this error:

System.ArgumentException: .NET type KeyValuePair`2 cannot be resolved into XML schema type

Any idea how can I create the wsdl and allow my customers to obtain the correct wsdl?

Thanks

Issue with Complex Objects

Hi

I have exposed a service using soap core in Net Core.
At Client Side my object is not getting populated in Class Object instead data is populated in Extended Data.

I have tried exposing the same code using .Net Framework WCF.
Things are working fine.

If there anything in Soap Core which I'm missing?

Thanks!!!

Using complex models as parameters for service methods

Hi guys,

is there a possibility to use complex models as parameters in service methods? I get some errors on deserialization. For example:

<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"> <soap:Header> </soap:Header> <soap:Body> <Reverse> <ComplexModel xmlns="http://tempuri.org/"> <Palindrome>kobyłamamałybok</Palindrome> </ComplexModel> </Reverse> </soap:Body> </soap:Envelope>

Content-Type: text/xml
SOAPAction: /IPingService/Reverse

With corresponding body model:
[DataContract] public class ComplexModel { [DataMember] public string Palindrome { get; set; } }

I get an error:
Exception thrown: 'System.Runtime.Serialization.SerializationException' in System.Runtime.Serialization.dll Additional information: Error in line 3 position 139. 'EndElement' 'ComplexModel' from namespace 'http://tempuri.org/' is not expected. Expecting element 'Palindrome'.

Don't wrap request in operation name

Hi,

I'm trying to use this middleware in a project. We're currently calling an existing SOAP Endpoint from an external source which means we are using existing message formats.

The problem is that the format requires us that the request is not wrapped in the operation tags.

Example:

What we want to use:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Header/>
   <soap:Body>
     <Message>A simple message</Message>
   </soap:Body>
</soap:Envelope>

But what we have to use to make the middleware work:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Header/>
   <soap:Body>
     <TestOperation>
         <Message>A simple message</Message>
     <TestOperation>
   </soap:Body>
</soap:Envelope>

Is it possible to define our Service Contract that way?

Best Regards
Julian

Using Sessions

Has anyone tried/managed to access HttpContext within a Service as described in

https://dotnetcoretutorials.com/2017/01/05/accessing-httpcontext-asp-net-core/ (see Inside Services)?

This is my Startup class:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.TryAddSingleton<SampleService>();

        services.AddDistributedMemoryCache(); // Adds a default in-memory implementation of IDistributedCache
        services.AddSession();

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();
        loggerFactory.AddDebug();

        app.UseSoapEndpoint<SampleService>("/Service", new BasicHttpBinding(), SoapSerializer.DataContractSerializer);
        app.UseSoapEndpoint<SampleService>("/Service.asmx", new BasicHttpBinding(), SoapSerializer.XmlSerializer);

        // IMPORTANT: This session call MUST go before UseMvc()
        app.UseSession();

        app.UseMvc();
    }
}

And the ServiceImpl:

public class SampleService : ISampleService
{
    private IHttpContextAccessor _accessor;
    public SampleService(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }

    public string Ping(string s)
    {
        string id = _accessor.HttpContext.Session.Id;
        Console.WriteLine("Exec ping method");
        return s;
    }
}

I get a
InvalidOperationException: Session has not been configured for this application or request

as described here:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?tabs=aspnetcore2x

Any ideas?
Thank you.

Object as parameter is not populated on service side

I have a simple object as a Input Parameter in service call but values from the client are not filled on the server side.
So all the properties have default values. The class has [DataContract] and each property has [DataMember] attribute.

Do I need anything special to make it work ?

List complex model as response

Hello,
I'm trying to create a soap service with a list complex model as response with:
List<string> ListAccounts(DateTime? CreatedOn);
The resulted xml schema is invalid
<xs:complexType name="List'1"> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" nillable="true" name="string" type="xs:string"/> </xs:sequence> </xs:complexType>
I see that the expected behavior should be:
if (toBuild.IsArray) { writer.WriteAttributeString("name", "ArrayOf" + toBuild.Name.Replace("[]", string.Empty)); }
May be there is a sample for list complex results?

How to implement a simple authentication?

Hello everyone.
I'm not good at WCF so maybe the question is something stupid, but I don't understand how to implement basic User-Password authentication stategy using SoapCore.
I have .Net Core app, have Soap endpoind provided via SoapCore. I figured out that I need to provide UserNamePasswordValidator for my binding. But since it's Net Core app and there is no web.config, I can't attach custom UserNamePasswordValidator to my binding using .config. It there any way to solve this?
Thanks.

SoapExceptionTransformer not usable since v0.9.5 (related to #23)

When I use an exception transformer like this :

services.AddSoapExceptionTransformer(ex => ex.Message);

I receive an exception of type NullReferenceException for exceptions without InnerException

SoapEndpointMiddleware.WriteErrorResponseMessage() lines 260 to 264

var errorText = exception.InnerException != null ? exception.InnerException.Message : exception.Message;

var transformer = serviceProvider.GetService<ExceptionTransformer>();
if (transformer != null)
	errorText = transformer.Transform(exception.InnerException);

How to Remove extra response tag from my Soap Response

I have below code for my service :

    [XmlType(Namespace="http://djm.eu/services/sample/v1")]
    [XmlRoot("MyResponse", Namespace="http://djm.eu/services/sample/v1", IsNullable=false)]
    public class MyResponseType
    {
        public int Code { get; set; }
        public string Description { get; set; }
    }


    [ServiceContract(Namespace = @"http://djm.eu/services/sample/v1")]
    public interface IMyService
    {
        [OperationContract]
        [return:MessageParameter(Name = "MyResponse")]
        MyResponseType Foo();
    }

    public class MyService : IMyService
    {
        public MyResponseType Foo()
        {
            return new MyResponseType
            {
                Code = 200,
                Description = "Ok"
            };
        }
    }

and this is the result :

<s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <FooResponse xmlns="http://djm.eu/services/sample/v1">
         <MyResponse>
            <Code>200</Code>
            <Description>Ok</Description>
         </MyResponse>
      </FooResponse>
   </s:Body>
</s:Envelope>

The problem is I dont want that extra <FooResponse> tag created automatically. I want it completely remove (SoapParameterStyle.Bare).

Expected result:

<s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <MyResponse xmlns="http://djm.eu/services/sample/v1">
          <Code>200</Code>
          <Description>Ok</Description>
      </MyResponse>
   </s:Body>
</s:Envelope>

Thanks.

Custom response body

Hello.

When I use POSTMAN, I receive a responce message with "default" body

<s:Body xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <GetSomeResponse xmlns="http://localhost/Service/">
            <GetSomeResult xmlns:a="http://schemas.datacontract.org/2004/07/Namespace._1s.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <a:Items>
                    <a:ActualItem>
                        <a:DailyRate>4</a:DailyRate>
                        <a:DateOf>2017-12-12T15:59:55.4105151+03:00</a:DateOf>
                        <a:Description>testDescr</a:Description>
                    </a:ActualItem>
                    <a:ActualItem>
                        <a:DailyRate>423</a:DailyRate>
                        <a:DateOf>2017-12-12T15:59:55.4113276+03:00</a:DateOf>
                        <a:Description>testDescr</a:Description>
                    </a:ActualItem>
                </a:Items>
                <a:RequestTime>2017-12-12T15:59:55.409831+03:00</a:RequestTime>
                <a:Response>
                    <a:Message>test GetSome </a:Message>
                    <a:Success>true</a:Success>
                </a:Response>
            </GetSomeResult>
        </GetSomeResponse>
    </s:Body>

But how can I remove <a:> tag or write for example <soap:Body>...</soap:Body> or remove Namespace._1s.Entities?

I think my respone creates on this string

responseMessage = Message.CreateMessage(_messageEncoder.MessageVersion, null, bodyWriter);

How can I influence this? Thanks!

Exclude members from wsdl

I get an exception when trying to call service in order to get wsdl:

System.ArgumentException: .NET type ObjectId cannot be resolved into XML schema type
   at SoapCore.MetaBodyWriter.ResolveType(Type type)
   at SoapCore.MetaBodyWriter.AddSchemaType(XmlDictionaryWriter writer, Type type, String name, Boolean isArray, String namespace)
   at SoapCore.MetaBodyWriter.AddTypes(XmlDictionaryWriter writer)
   at SoapCore.MetaBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.OnWriteBodyContentsAsync(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.OnWriteMessageAsync(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.WriteMessageAsync(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessageAsync(Message message, Stream stream)
   at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessageAsyncInternal(Message message, Stream stream)
   at System.Runtime.TaskHelpers.WaitForCompletionNoSpin(Task task)
   at SoapCore.SoapEndpointMiddleware.ProcessMeta(HttpContext httpContext)
   at SoapCore.SoapEndpointMiddleware.ProcessOperation(HttpContext httpContext, IServiceProvider serviceProvider)
   at SoapCore.SoapEndpointMiddleware.Invoke(HttpContext httpContext, IServiceProvider serviceProvider)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

I tried to apply [IgnoreDataMember] and [XmlIgnore], but they seem to be ignored. Any advice is appriciated.

Memory Leak Issue

I just have added the below line of code in StartUp.cs
app.UseSoapEndpoint ("/Service.svc", new BasicHttpBinding(), SoapSerializer.DataContractSerializer);

And in the actual service implementation, it returns null at the moment.

So when I do a load test with around 100 requests/minute, the memory increases to 1GB from 100MB (using Diagnostics tool). Is there a memory leak issue?

The envelope version of the incoming message (Soap12 (http://www.w3.org/2003/05/soap-envelope)) does not match that of the encoder (Soap11 (http://schemas.xmlsoap.org/soap/envelope/))

Hi All,

Thanks for your efforts in putting this together. Trying it on a sample project have have run into the above error message. From my searching it appears that "BasicHttpBinding" is related to Soap 1.1 and wsBasicHttpBinding is for SOAP 1.2. By the looks of it, using System.ServiceModel does not support the ws binding.

The error happens at:
var requestMessage = _messageEncoder.ReadMessage(httpContext.Request.Body, 0x10000, httpContext.Request.ContentType);
in SoapEndpointMiddleware.cs

Starting point for automation

Hi,

what is a good starting point to get into automation with a contract first approach.
I've 1 wsdl and 2 xsd's and I'm looking for a good way to generate the parameter classes and the interface.

any idea is appreciated

Include out parameters in wsdl

Hi,

out parameters are missing in created wsdl. See sample SampleService.VoidMethod(out var stringValue). For testing, I created a .NET Framework 4.6.1 client project using ServiceReference to create a client from wsdl. There, the out parameter is missing, see
Client461.zip.

Best regards,
Markus

An unhandled exception occurred while processing the request.

Hi,

I have an issue, i created a Web API Project in .Net Core


   public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(new SoapService());
            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)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSoapEndpoint<SoapService>("SoapRoutes", new BasicHttpBinding());
            app.UseMvc();

When i launch my app i got this exception :
image

Fault message details

Hi!

Is there an example or possibility to fill Fault message details tag from service if there was exception or something similar?
Thanks!

Complex object always null

I downloaded the sample code and consumed the PingComplexModel method. Both properties always come null values. This is the request I have sent:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:PingComplexModel>
         <!--Optional:-->
         <tem:inputModel>
            <!--Optional:-->
            <tem:StringProperty>aa</tem:StringProperty>
            <tem:IntProperty>123123</tem:IntProperty>
         </tem:inputModel>
      </tem:PingComplexModel>
   </soapenv:Body>
</soapenv:Envelope>

Thanks.

Support DateTimeOffset in wsdl generation

Currently, when using DateTimeOffset as type an error is thrown indicating that the type is not supported.

.NET type DateTimeOffset cannot be resolved into XML schema type

Instead something similar to here should be constructed.

<xs:schema targetNamespace="http://schemas.datacontract.org/2004/07/System">  
   <xs:complexType name="DateTimeOffset">  
      <xs:sequence minOccurs="1" maxOccurs="1">  
         <xs:element name="DateTime" type="xs:dateTime"  
         minOccurs="1" maxOccurs="1" />  
         <xs:elementname="OffsetMinutes" type="xs:short"  
         minOccurs="1" maxOccurs="1" />  
      </xs:sequence>  
   </xs:complexType>  
</xs:schema>

Unexpected End of File

When I hit my hosted service via a web browser, I get this exception:

System.Xml.XmlException: Unexpected end of file.
   at System.Xml.EncodingStreamWrapper.ReadBOMEncoding(Boolean notOutOfBand)
   at System.Xml.EncodingStreamWrapper..ctor(Stream stream, Encoding encoding)
   at System.Xml.XmlUTF8TextReader.SetInput(Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose onClose)
   at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.TakeStreamedReader(Stream stream, Encoding enc)
   at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.ReadMessage(Stream stream, Int32 maxSizeOfHeaders, String contentType)
   at SoapCore.SoapEndpointMiddleware.<ProcessOperation>d__7.MoveNext()

It also happens when I use svcutil to extract metadata.

The service is unusable. What do I do?

Strong name signing

Hello,
may I ask if there are any plans to strong-name the assemblies in the nuget package?
Thanks, Sebastian

how to handle Header, soap SecurityHeader, in SoapCore? supported?

I need my webservice to handle SecurityHeader like this:
<soap:Header> <SecurityHeader xmlns="http://mydomain.com/myService/"> <Username>string</Username> <Password>string</Password>
Very many old client installations we have in our company deliver soap messages with this header in place. I can't see how to make a service wth SoapCore to handle this. Or is there a way?

Have anybody managed to use this SoapCore towards webservices made with dotnet *.asmx files?
Edit: I have managed to create a webservice with SoapCore doing what old *asmx files are doing. Old dotnet clients are communicating ok on simple parameters. But securityheader is not used, so it's unsafe. Also, passing custom objects went well, but not when they have custom sub objects. All is null on those parameters...

Complex model input from SoapUI is always null

I am trying to make a Soap service with SoapCore. I am using SoapUI to test this service. However I cannot get complex types to post any data. The properties always come in as null. Even when I use your sample application.

This is the request that SoapUI creates:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
soapenv:Header/
soapenv:Body
tem:PingComplexModel

tem:inputModel

tem:StringPropertysdfwwef</tem:StringProperty>
tem:IntProperty1</tem:IntProperty>
</tem:inputModel>
</tem:PingComplexModel>
</soapenv:Body>
</soapenv:Envelope>

Sample on README.md contains error in path

This sample on README.md contains a small error, see https://github.com/DigDes/SoapCore/blame/master/README.md#L24

If you run this, you get an error:

An unhandled exception occurred while processing the request.
ArgumentException: The path in 'value' must start with '/'.
Parameter name: value

"ServicePath.asmx" must be "/ServicePath.asmx"

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSoapEndpoint<ServiceContractImpl>("/ServicePath.asmx", new BasicHttpBinding());
}

Missing SoapSerializer in 0.9.5

I'm missing this new feature in the DLL. Some how is it not implemented in the 0.9.5 NuGet release. It is in the repo, but I can't find anything in the relase version. Is there a mistake, or do I miss something?

Support parametered constructors again

Hi,

recently, in the latest version a bug has been introduced: my asp .net controller doesn't permit a parameterless constructor, because I need some things via dependency injection.

Example controller

[Route("api/[controller]")]
public class MyController : Controller, IMyService
{
    private ILogger Log { get; }
    public DuBttController(ILogger<MyController> logger)
    {
        Log = logger;
    }

    // IMyService.SomeMethod
    public int SomeMethod(int arg) => arg;
}

The exception when calling via Soap is

System.MissingMethodException occurred
  HResult=0x80131513
  Message=No parameterless constructor defined for this object.
  Source=mscorlib
  StackTrace:
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at SoapCore1.SoapEndpointMiddleware.<ProcessOperation>d__7.MoveNext() in SoapEndpointMiddleware.cs:line 97

Best regards
Markus

Https (samples)

I am looking to implement https with SoapCore, but so far I'm not having any luck. I've noticed that if I enter an HttpsBinding when using app.UseSoapEndPoint that nothing is done with that other than:
element = binding.CreateBindingElements().Find<MessageEncodingBindingElement>();.
So I am assuming that my transport mode and everything are not used from that binding.

When creating service instance listeners I am using the following kestrel options:
.UseKestrel(options => { int port = serviceContext.CodePackageActivationContext.GetEndpoint("ServiceEndpointHttps").Port; options.Listen(IPAddress.Any, port, listenOptions => { listenOptions.UseHttps(pfxCert); listenOptions.NoDelay = true; }); })

However my test requests are being answered with: > The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was ''.

How can I force https with certificate while using SoapCore?

Is possible to add a SOAP header?

I would like to expose a call like these from my ASP.net core api

<binding name="SMSDeliveryNotificationPortBinding" type="tns:SMSDeliveryNotification"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="notifySMSDelivery"> <soap:operation soapAction=""/> <input> <soap:body use="literal" parts="parameters"/> <soap:header message="tns:notifySMSDelivery" part="gdspHeader" use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding>

is possible to add the header? I used a custom messageInspector but the svc doesn't expose the header to me (only body)

Support null arguments

Hi,

please support arguments of type class passed null thus not present in soap message.

Best regards,
Markus Hartmair

Code example:
Server (ASP.NET Core 2)

[ServiceContract(Name = "MyService.asmx")]
public interface IMyService
{
    int SomeMethod(int arg1, MyModel arg2, int arg3);
}

Client (WebService Reference)

using (var client = new MySoapService.MyService())
    client.SomeMethod(42, null, 42);

Server Exception:

System.Xml.XmlException: Start element 'arg2' from namespace '...' expected. Found element 'arg3' from namespace '...'. Line 1, position 246.
     at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
     at System.Xml.XmlDictionaryReader.MoveToStartElement(String localName, String namespaceUri)
     at SoapCore.SoapEndpointMiddleware.GetRequestArguments(Message requestMessage, OperationDescription operation, Dictionary`2& outArgs)
     at SoapCore.SoapEndpointMiddleware.<ProcessOperation>d__7.MoveNext()

Possible fix working for me:
SoapEndpointMiddleware.cs:GetRequestArguments:160

xmlReader.MoveToStartElement(/* no parameters */);
if (xmlReader.IsStartElement(parameterName, operation.Contract.Namespace))
{
    ...
}
else /* handle parameter not present */
{
    arguments.Add(null);
}

InvalidOperationException: Sequence contains no elements

Hi,

I'm trying to use SoapCore, but i did not succeeded and get the following error when accessing my endpoint :
InvalidOperationException: Sequence contains no elements

Here is what i'm doing :

  • File > New > Project > .Net Core > ASP.NET Core Web Application > API (Core 2.1)
  • Install nuget package > SoapCore
  • Create new class with following content :
    public class ServicePing
    {
        public string Ping(string msg)
        {
            return string.Join(string.Empty, msg.Reverse());
        }
    }
  • Edit Startup.cs as following :
    • Add services.AddSingleton(new ServicePing()); in public void ConfigureServices(IServiceCollection services)
    • Add app.UseSoapEndpoint<ServicePing>(path: "/PingService.svc", binding: new BasicHttpBinding()); in public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  • Debug the program and try accessing https://localhost:1337/PingService.svc
  • Following error is displayed :
InvalidOperationException: Sequence contains no elements
System.Linq.Enumerable.First<TSource>(IEnumerable<TSource> source)

Here is the detailed StackTrace :

System.InvalidOperationException: Sequence contains no elements
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at SoapCore.MetaMessage.OnWriteStartEnvelope(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.WriteMessagePreamble(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.OnWriteMessageAsync(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.WriteMessageAsync(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessageAsync(Message message, Stream stream)
   at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessageAsyncInternal(Message message, Stream stream)
   at System.Runtime.TaskHelpers.WaitForCompletionNoSpin(Task task)
   at SoapCore.SoapEndpointMiddleware.ProcessMeta(HttpContext httpContext)
   at SoapCore.SoapEndpointMiddleware.ProcessOperation(HttpContext httpContext, IServiceProvider serviceProvider)
   at SoapCore.SoapEndpointMiddleware.Invoke(HttpContext httpContext, IServiceProvider serviceProvider)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Do you have any idea of what is the problem?

Improve error handling

Hi,

please improve error messages. Currently, some errors are not handled properly causing an unhandled exception!

Best regards,
Markus Hartmair

Code

[ServiceContract(Name = "MyService.asmx")]
public interface IMyService
{
    int SomeMethod(int arg1, out MyModel arg2);
}

public class MyModel
{
    public string MyProperty { get; internal set; } /* Should be public setter */
}

(expected) Exception:

System.InvalidOperationException occurred
  HResult=0x80131509
  Message=Cannot deserialize type 'MyModel' because it contains property 'MyProperty' which has no public setter.
  Source=System.Xml
  StackTrace:
   at System.Xml.Serialization.TypeScope.GetSettableMembers(StructMapping mapping, ArrayList list)
   at System.Xml.Serialization.TypeScope.GetSettableMembers(StructMapping structMapping)
   at System.Xml.Serialization.TypeScope.GetSettableMembers(StructMapping mapping, Dictionary`2 memberInfos)
   at System.Xml.Serialization.XmlSerializationReaderILGen.WriteLiteralStructMethod(StructMapping structMapping)
   at System.Xml.Serialization.XmlSerializationReaderILGen.GenerateMethod(TypeMapping mapping)
   at System.Xml.Serialization.XmlSerializationILGen.GenerateReferencedMethods()
   at System.Xml.Serialization.XmlSerializationReaderILGen.GenerateEnd(String[] methods, XmlMapping[] xmlMappings, Type[] types)
   at System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence)
   at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
   at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type)
   at SoapCore1.ServiceBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer) in ServiceBodyWriter.cs:line 52

Unhandled server exception!

System.NullReferenceException occurred
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=cubido.Common.AspNetCore.Soap
  StackTrace:
   at SoapCore1.SoapEndpointMiddleware.<ProcessOperation>d__7.MoveNext() in SoapEndpointMiddleware.cs:line 129

Possible fix working for me:
SoapEndpointMiddleware:ProcessOperation:126

catch (Exception exception)
{
    // Create response message
    /* InnerstException */
    while (exception.InnerException != null)
        exception = exception.InnerException;
    var errorText = exception/*.InnerException*/.Message;
    var transformer = serviceProvider.GetService<ExceptionTransformer>();
    if (transformer != null)
        errorText = transformer.Transform(exception/*.InnerException*/);
    var bodyWriter = new FaultBodyWriter(new Fault { FaultString = errorText });
    ...
}

Connecting BasicHttpsBinding

Hi,

I'm trying to implement a wcf with a BasicHttpsBinding and a https uri.
I am able to watch the contracts at the browser but I'm not able to add the server reference in a project from visual studio

This is the code im using when i create the endpoint:

` BasicHttpsBinding binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
Api.Configuration.Configure(
app,
host => host
.UseIf(env.IsDevelopment(), appBuilder => appBuilder.UseDeveloperExceptionPage())
.UseHttpsRedirection()
.UseStaticFiles()
.UseSession(new SessionOptions()
{
IdleTimeout = TimeSpan.FromMinutes(120)
})
.UseSoapEndpoint("/wsga.svc", binding, SoapSerializer.XmlSerializer)

        );`

I receive this error :
Error: Cannot obtain Metadata from https://localhost:5050/Service.svc

I couldn´t find any documentation about it,

Thanks in advance.

List<T> and IEnumerable<T> handling

I have an operation that returns List<JobSummary>.
I also have several properties that are a List of objects, such as List<Destination> on type JobSummary
When generating the WSDL, two issues arise from using List.

  1. The element in the WSDL for anything with a List type shows as List`1. When I try to create a project in SoapUI using that WSDL, it gives me an error on that type.
    I've tried programmatically removing the `1 in MetaBodyWriter.AddSchemaType(), so it was just type="tns:List" but then ran into other issues with List...

  2. The ComplexType for List in the WSDL gets generated as

<xs:complexType name="List">
  <xs:sequence>
    <xs:element minOccurs="0" maxOccurs="unbounded" nillable="true" name="JobSummary" type="tns:JobSummary"/>
  </xs:sequence>
</xs:complexType>

which is not right. If I try to Create a project in SoapUI any property that is a List will have a JobSummary object in place of wherever the list should be.

Changing all of my Lists to arrays isn't going to be easy, and I'm not even sure if that is what is needed. There's a much larger codebase that's using IEnumerable and List a lot in the models.

Am I doing something incorrectly?

ASP.NET Core 2.1 Compatibility Issues with Azure Web Services

When running locally, everything worked great. When I deployed to Azure as ASP.NET Core 2.1 application, I would receive:

System.IO.FileNotFoundException: Could not load file or assembly 'System.Private.ServiceModel, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
File name: 'System.Private.ServiceModel, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

This issue describes the problem: dotnet/wcf#2349

The System.ServiceModel.Http 4.4.0 dependency of SoapCore has a dependency on System.Private.ServiceModel 4.4.0, and that NuGet package does not support the Azure win-x86 or win-x64 runtimes. The result is that the DLL would not be included by Azure when publishing your app.

By updating to System.ServiceModel.Http 4.5.0, this also updates to System.Private.ServiceModel 4.5.0 where the runtime has been changed to "win" (which supports win-x86 and win-x64 runtimes).

wsdl Nullable types

Hi,

please support Nullable in wsdl generation. Currently, this throws an exception:

System.ArgumentException occurred
  HResult=0x80070057
  Message=.NET type Nullable`1 cannot be resolved into XML schema type
  Source=cubido.Common.AspNetCore.Soap
  StackTrace:
   at SoapCore1.MetaBodyWriter.ResolveType(String typeName) in MetaBodyWriter.cs:line 413

Best regards
Markus

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.