CoreWCF / CoreWCF

Main repository for the Core WCF project
MIT License
1.66k stars 292 forks source link

WSDL returns HTTP 400 if application is hosted on sub path in IIS #741

Open mus65 opened 2 years ago

mus65 commented 2 years ago

If the application is hosted on a sub path in IIS, any request to the WSDL returns HTTP 400.

I narrowed this down to the following code:

https://github.com/CoreWCF/CoreWCF/blob/c92ca1a923a5b2e9bc5931f593e022123bd526df/src/CoreWCF.Primitives/src/CoreWCF/Channels/MetadataMiddleware.cs#L176-L184

Due to the AbsolutePath!="/" check, metadataExtension.HttpGetUrl (which is only the URL to the application itself without the service path) is used instead of fallbackHttpEndpointAddress (which would actually be the correct URL including the path to the service).

This later causes the check here to fail and not handle the metadata request.

https://github.com/CoreWCF/CoreWCF/blob/c92ca1a923a5b2e9bc5931f593e022123bd526df/src/CoreWCF.Primitives/src/CoreWCF/Description/ServiceMetadataExtension.cs#L1065

I currently worked around this by setting dummy absolute URLs on the ServiceMetadataBehaviour, although I'm not sure which negative side effects this could have (the URLs in the WSDL and help page are still correct).

serviceMetadataBehavior.HttpGetUrl = new Uri("http://localhost/");
serviceMetadataBehavior.HttpsGetUrl = new Uri("https://localhost/");

This is with CoreWCF 1.1.0 .

mccreah commented 2 years ago

Can confirm this. Actually what is strange is that I have the service endpoint configured like this

      app.UseServiceModel(serviceBuilder =>
      {
        serviceBuilder.AddService<Service>();
        serviceBuilder.AddServiceEndpoint<Service, IService>(new BasicHttpBinding(BasicHttpSecurityMode.Transport), "/Service.svc");
        var serviceMetadataBehavior = app.ApplicationServices.GetRequiredService<ServiceMetadataBehavior>();
        serviceMetadataBehavior.HttpsGetEnabled = true;
      });

With this in launchSettings.json

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iis": {
      "applicationUrl": "https://localhost/CoreWCFService1",
      "sslPort": 0
    }
  },
  "profiles": {
    "CoreWCFService1": {
      "commandName": "Project",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "https://localhost:7081;http://localhost:5081"
    },
    "IIS": {
      "commandName": "IIS",
      "launchBrowser": true,
      "launchUrl": "Service.svc"
    }
  }
}

So I'm saying to host it https://localhost/CoreWCFService1/Service.svc but it produces 400 errors there BUT it actually works at https://localhost/CoreWCFService1, showing the well known blue page.

The WSDL is also made available at https://localhost/COREWCFSERVICE1?singleWsdl

ghost commented 2 years ago

I've been having what I'd suspect is the same issue with self-hosting - I'm working on drop-in replacement CoreWCF code to replace old WCF.

In WCF I can have an endpoint http://localhost:1234/Test which will serve the help page. With CoreWCF a base address of http://localhost:1234/Test and the endpoint address empty leads to service calls working but a 400 for the help page. If I add something as the endpoint address the help page then works, but of course the client URL has been changed.

Edit: I just tried something else and bingo - I had added a URL to serviceOptions.BaseAddresses as per the blog post on metadata, and once I removed this and set the endpoint address to /Test it worked as expected. Maybe that blog post needs a revision...?

rgroenewoudt commented 1 year ago

I'm also running into this issue.

janniksam commented 3 months ago

Having the same issue. Whats the workaround/solution here?

Havunen commented 2 months ago

I can confirm this issue and that following settings does work around the error:

serviceMetadataBehavior.HttpGetUrl = new Uri("http://localhost/");
serviceMetadataBehavior.HttpsGetUrl = new Uri("https://localhost/");