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

Could not load type 'System.ServiceModel.Channels.AsymmetricSecurityBindingElement' from assembly 'System.ServiceModel #3190

Closed it3ce closed 6 years ago

it3ce commented 6 years ago

I have a .Net Core 2 web api project in which I have some WCF services working fine, but I need to use a class library built for .Net Framework 4.5 which also connect to a web service. When I call the class library from a .Net Framework client it works fine, but when I try calling from my .Net Core 2 app, it throws the following error: Could not load type 'System.ServiceModel.Channels.AsymmetricSecurityBindingElement' from assembly 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. I've tried making a local reference to the ServiceModel dll library in my class library project, but it is not working. I've read about some shims or some packages not availables in the .Net Core version of this library. Why is that? Is there any workaround to make it work?

Lxiamail commented 6 years ago

@it3ce It is because that System.ServiceModel.Channels.AsymmetricSecurityBindingElement is not supported on WCF Core.

it3ce commented 6 years ago

Thanks for the response @Lxiamail For better understanding (and please forgive my ignorance), if I am calling a diferent project in which the version of the library is also different, shouldn't it dynamically pick the rigth version for the target patform which is supposed to be used by that other class library project? It seems to me like a backwards compatibility issue. Is there any way to be able to call my .net framework class library project, and this to call the right version of System.ServiceModel library?

Lxiamail commented 6 years ago

@it3ce When you run your app on .NET Core, the library built on .NET Framework will be redirected to System.private.servicemodel.dll via system.servicemodel.dll shim assembly. This is bydesign. We don't have a work around for using System.ServiceModel.Channels.AsymmetricSecurityBindingElement at this point.

StephenBonikowsky commented 6 years ago

@it3ce If you have any further questions let us know.

rafamartinsbr commented 4 years ago

Hi, just to double-check: is this still the case ? @Lxiamail

We don't have a work around for using System.ServiceModel.Channels.AsymmetricSecurityBindingElement at this point.

i have a similar situation (ie a host process running .net core that references a .netstandard lib that has a ref to a .netframework lib which consumes an api using WCF / System.ServiceModel 4.0.0).

When I call the class library from a .Net Framework client it works fine, but when I try calling from my .Net Core 2 app, it throws the following error [...]

Thanks in advance and have a nice day :)

StephenBonikowsky commented 4 years ago

@rafamartinsbr Yes, AsymmetricSecurityBindingElement is not yet supported in Core. @mconnew are there any plans to support this?

mconnew commented 4 years ago

@rafamartinsbr, AsymmetricSecurityBindingElement basically means full message security. Unfortunately we don't have some of the dependencies available to us to be able to implement this.

rafamartinsbr commented 4 years ago

ok, thanks a lot for your time @StephenBonikowsky & @mconnew .

after a closer look, in our case we might be able to port the host app to full .netframework - which should solve the issue.

have a nice day !

nhustak commented 4 years ago

This is becoming a serious issue. Does 'closed' mean it's not going to happen? I have a full blown CORE web site going and we just got broadsided by this not being available in WCF. Reverting to framework is not an option.

mconnew commented 4 years ago

'closed' means the issue that the specific problem that the original person who opened this issue had has been resolved. This issue is they were getting an exception saying "Could not load type 'System.ServiceModel.Channels.AsymmetricSecurityBindingElement' from assembly 'System.ServiceModel..." when running their application on .NET Core. The resolution for this is that this particular class is used for full message security and that is not currently supported so we don't have the implementation for this class in .NET Core. So the answer to this specific question is that the exception was caused by a feature which isn't currently supported. The answer to what is causing an exception saying "Could not load type '.....' from assembly 'System.ServiceModel..." will always be because that type isn't currently supported so there's nothing else to be discussed. We can't change the behavior of the CLR when the implementation isn't there. I don't see a need to keep an issue open where the resolution is explaining why they are getting the exception as the answer won't ever change.
If your issue isn't about understanding what this exception means and is instead about the message security feature, you might want to weigh in on issue #4 which is still open. It is clearly documented here that full message security isn't supported. Also running the api port tool would have flagged that AsymmetricSecurityBindingElement isn't available. It's described in this document explaining the steps to port from .NET Framework to .NET Core.
We can't bring full message security because of missing dependencies. We do have support for TransportWithMessageCredentials. MessageSecurity provides 2 different capabilities. First it provides secrecy and tamper detection by encrypting the message itself and signing it so that a third party can see the message transferred and still not know what it contains and can't change anything without a change being detected. Second it provides a mechanism to authenticate using security tokens passed in the SOAP headers. TransportWithMessageCredentials provides that second capability, but requires you use transport security to encrypt and detect tampering. This is usually using SSL/TLS. If you control the server side of your app, you could potentially add another endpoint using TransportWithMessageCredentials and use the same authentication mechanism. Anyway, any discussion about the feature should happen on issue #4 which is still open as we haven't ruled it out.

nhustak commented 4 years ago

Thank you for taking the time to explain this.

BZHGames commented 1 year ago

Hi,

I see that the subject has not evolved for more than 2 years. Today I am facing similar problems mentioned here. I developed ASMX and WCF Framework 4.5 web services as well as a central DLL, also in Framework 4.5, which consumes these web services. Then I have various Web applications, WinForm, Windows Services... also developed in Framewok 4.x which use this DLL. So far, no problem, everything works fine. To modernize the web applications, I wanted to switch to Framework 7.0 (Core + React). But there, when I refer to my DLL which is still in Framework 4.5, it is impossible to consume the web services. After installing the NuGet packages:

Each time the NuGet packages are installed, a new problem appears. And now I have the error: System.TypeLoadException: 'Could not load type 'System.ServiceModel.Configuration.ChannelEndpointElement' from assembly 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

But I can't get out of it. I've been searching the web for days for a solution, but I'm stuck. And from what I can read there doesn't seem to be a solution, but I hope I'm wrong. In 2020 the problem was already known, and today in 2023, I still can't find a solution. Could someone help me please? Hoping that the solution is not to redo all the web services in Json, I have about 1500 web services.

mconnew commented 1 year ago

@BZHGames, if you are able to modify the service side, you could add another endpoint on the same service which uses TransportWithMessageCredentials. The difference between SecurityMode.TransportWithMessageCredentials and SecurityMode.Message is that the former uses SSL (with HTTP based transports, this is just HTTPS) to provide encryption and integrity of the communication but still uses the exact same authentication mechanisms. The latter encrypts and signs the SOAP message itself. If you are technically able to use JSON, I would expect there shouldn't be any reason why you couldn't use TransportWithMessageCredentials as the capabilities that Message provides (eg encrypted when stored) over TransportWithMessageCredentials aren't available in JSON.

If this is a viable option, you can leave your existing endpoint there and just add a new endpoint with a different binding configuration and different relative address. WCF can expose the same service instance on multiple endpoints.

As for why you are getting that exception, it looks like you aren't recompiling your code and are trying to use the assembly compiled against .NET Framework as-is in .NET. Configuration support doesn't exist in .NET as we're missing the machine.config that is installed with .NET Framework and has many sections necessary for config to work. A Microsoft employee created a library which can help to bring configuration over. You can find it here: https://github.com/twsouthwick/ServiceModel.Configuration

BZHGames commented 1 year ago

@mconnew, thank you for your reply. I was on vacation, I only see your message now :) I will try to solve my problem using your explanations.