dotnet / wcf

This repo contains the client-oriented WCF libraries that enable applications built on .NET Core to communicate with WCF services.
MIT License
1.72k stars 558 forks source link

Webservice SOAP ASMX downt work in iOS .net MAUI 8.0 #5617

Open herickfaro opened 4 months ago

herickfaro commented 4 months ago

Describe the bug I try to consume a SOAP WebService at App MAUI .net 8.0 on an iOS app the error is "dynamic code generation is not supported on this platform", even with AOT enabled. It works normally on Windows Machine connect to webservice.

Error at line 19 from MauiSoapConsumer/MainPage.xaml.cs Repro project: https://github.com/markos-jr/MauiSoapConsumer

To Reproduce Steps to reproduce the behavior: For iOS:

Create a new .NET MAUI App.
Choose the "iPhone 15 SE iOS 17.4" simulator from the list iOS Simulators targets.
Enable AOT Compilation
Debug the app.
Observe the app launch in the simulator, but the debugger detach and report "dynamic code generation is not supported on this platform"

` image

hwsmo commented 4 months ago

Hello, we can also reproduce the error in our iOS app. Our SOAP service no longer works.

mconnew commented 3 months ago

Was your app working in earlier versions of .NET MAUI, ie .NET 6, or is this a new app? Line 19 of MauiSoapConsumer/MainPage.xaml.cs isn't where I would have expected an exception like that to appear. We have a couple of places where historically (as in .NET Framework) WCF has used dynamic code generation, but I wouldn't have expected either of those to be hit at that line. The first one we use DispatchProxy to create a class which implements your service interface. I had presumed that had been implemented for aot but it looks like it hasn't been. I think this works for Android as I believe they can support Ref.Emit. The issue tracking this is https://github.com/dotnet/runtime/issues/73136.

The second place is when you use a callback contract. The code which invokes the callback method used to use Ref.Emit on .NET Framework. We've replaced it with 2 implementations. When dynamic code generation is enabled, we use Expression to call it. When it isn't supported, we invoke it using MethodInfo.Invoke.

But you're hitting the aot DispatchProxy lack of support problem. There's not much we can do about that. Xamarin had an interesting approach (it had its own implementation of WCF pulled from mono) where they addressed this in the "Add Service Reference" tooling. They generated a client derived from ClientBase<TChannel> and in the emitted methods, they called another method they created on a WCF type (I forget which one, might have been ServiceChannelProxy) which was passed a string with the method name and an array of parameters. I couldn't find an immediately obvious way to do the same thing in this code base, but I have a couple of potential ideas to try. It's difficult to try things as I don't have a Mac to compile an app on, and I don't have an iPhone to try running it so I might suggest some things to try which may or may not work.

If I don't come back to this within a week, feel free to mention me to give me a nudge.