Soap Endpoints with ASP.NET Core 6 - c#

Currently I have only worked with REST and setting my endpoints directly in the Controller.
For example:
[HttpGet("someEndpoint")]
Now I have to work with SOAP and I'm trying to set the endpoint in my Program.cs (see screenshot). I'm always getting an error for the BasicHttpBinding().
My question: do I have to set the endpoints in the controller? The same way I'm doing it with my normal REST API? I didn't find an answer for this on the Internet. Thank you very much in advance.
(My native language is German, sorry for my English :) )
EDIT: the code:
using SoapCore;
using System.ServiceModel;
using WebAPI_2023.Models;
using WebAPI_2023.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddSoapCore();
builder.Services.AddScoped<CalculatorService>();
builder.Services.AddSingleton<ISampleService, SampleService>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSoapEndpoint<ISampleService>("/Service.asmx", new
BasicHttpBinding(), SoapSerializer.XmlSerializer);
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
EDIT 2 : I found my error.Now it works perfectly :)
app.UseEndpoints(endpoints =>
{
endpoints.UseSoapEndpoint<ISampleService>("/Service.asmx", new
SoapEncoderOptions(), SoapSerializer.XmlSerializer);
});

Do I have to set the Endpoints in the Controller? The same way im
doing it with my normal REST APIĀ“s? I didnt find an answer for this on
the Internet
Well, for Web Service integration within the asp.net core project regardless of version there are two prerequisite:
Prerequisite:
Either your web service must be running and URL should available for calling
Or must have Valid WSDL file in local machine.
Common Implementation For Both:
Following steps would be same for both asmx and wsdl integration.
In addition, please be sure that, I have used Microsoft Visual Studio Community 2022
Version 17.3.6 while preparing this answer.
Step:1
Step:2
Step:3
Implementation Using asmx URL:
Note: If your Web Service up and running it will start adding the reference without any issue.
Implementation Using WSDL file:
Note: You should select path for your valid wsdl file here. Ignore my files here, you outght to choose your wsdl file instead.
Use Your Service Inside Your Web API/MVC Controller
Now, In your Web API project, you could use a service reference added earlier. Like below
Please note that, you should call the method according to the WCF service's method.
var serviceReference1 = new ServiceReference1.Service1Client();
var result = await serviceReference1.GetDataAsync(1) ;
If you still encounter any further issue for integration you could refer to our official document for more details here

Related

Do I really need CORS here with Swagger?

I developed an API to give public access to some company data, which is of no value to hackers. It's public data that can be sourced from other websites.
I developed the project using default Visual Studio ASP.Net Core API templates. One thing I noticed it's using CORS and I don't know how it got in here to be honest.
However, the default Policy is set as any domain, any method and any header:
builder.Services.AddCors(p =>
p.AddPolicy("corsapp", builder =>
{
builder.WithOrigins("*").AllowAnyMethod().AllowAnyHeader();
}));
Do I even need CORS, if I am only allowing the API to run from a single origin, which already has HTTPS?
What benefit, when the API works as is?
Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//do I really need this!?!
builder.Services.AddCors(p => p.AddPolicy("corsapp", builder =>
{
builder.WithOrigins("*").AllowAnyMethod().AllowAnyHeader();
}));
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
startup.Configure(app);
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
//why!?!
app.UseCors("corsapp");
app.UseAuthorization();
app.MapControllers();
app.Run();
UPDATE
I've re-worded my OP based on Rahul's excellent video about CORS from Chen's answer below. However, I am still confused if I should configure CORS here to give a specific single origin as I am more worried someone after me may not configure this Policy correctly if the API is required in more than two places.
Thanks
You would need to know if your program provides API responses to client applications loaded from other domains to determine if you need to enable CORS.
For example, there are two cases where no action is needed for CORS support:
Swagger UI is hosted on the same server as the application itself (same host and port).
The application is located behind a proxy that enables the required CORS headers. This may already be covered within your organization.
You can get a better understanding and use of CORS through this link and this official documentation.

Consume third party API with Blazor WebAssembly [duplicate]

I have a blazor web assembly which fetches from an external API built on ASP.NET Core which I do not have access to. I can perform get requests, but cannot perform post requests. I get the following error when I do.
Access to fetch at 'http://external:9000/User/Create' from origin 'http://localhost:56138' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The author of the api confirms he enabled cors to allow any header in his startup and also suggested I do the same but this did not fix the issue. I confirmed from the debugger I am sending the right data format the endpoint requires and I am also running on http scheme same as the web service.
This is the client configuration in program.cs
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://external:9000/") });
builder.Services.AddCors(policy =>
{
policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
This is how I post
var dataJson = JsonConvert.SerializeObject(application);
var stringContent = new StringContent(dataJson, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"User/Create", stringContent);
I have read this is a common problem with blazor assembly, I'm not entirely sure of what I read. I am currently trying to move the project to blazor server to see if it would work, but I would prefer it on web assembly.
builder.Services.AddCors(policy =>
{
policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
This configuration should be done on a Server, and not yours but the server of the external API. You do nothing in that regard, except call end points on that Web Api.
The author of the api confirms they enabled cors to allow any header in his startup
If so, ask them for the code for confirmation...
and also suggested I do the same but this did not fix the issue.
You do nothing of the sort.
Workaround solution:
AS CORS is a security feature of JavaScript enforced by the browser, you can circumvent it by calling your Server code from which you perform the call to this Web Api end point, and then returns it back to your WebAssembly front-end. Use asynchronous code as much as you can.
Update as per comment
Are you saying I should have two projects, the server and the client under one solution? The server calls the calls the external api, then passes it to the client. Is this what your last suggestion is?
If you're using WebAssembly Blazor App hosted wherein the hosting server contains Web Api controllers, then you should expose end points that can be called from your WebAssembly front-end. The code in these end points should perform the HTTP calls to the external Web Api, and pass back to the WebAssembly calling methods the data received from the external Web Api.
Note: If you don't have such controllers ( they are created by default by Visual Studio), you may add them yourself to the server project.
If you already have created a Web Api project instead of those controllers, then expose the necessary end points from your Web Api project. Note that it makes no difference whether your Web Api project resides in the same solution of the WebAssembly front-end, as long as you provide the correct Url.
If you're using WebAssembly Blazor App stand alone; that is, the default installation does not create a Server project, you'll need to create a Web Api project and use it, unless you've already created one.
You are working with localhost so you should use this configuration to your Server:
builder.Services.AddCors(policy =>
{
policy.AddPolicy("_myAllowSpecificOrigins", builder =>
builder.WithOrigins("http://localhost:56138/")
.SetIsOriginAllowed((host) => true) // this for using localhost address
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
//
app.UseCors("_myAllowSpecificOrigins");

WebApi Swagger (Swashbuckle) - can't access Swagger UI when connecting through proxy

I have a swagger (Swashbuckle) enabled on one of my API controllers.
Server sits on http://192.168.7.119:1001 and Swagger UI is accessed through http://192.168.7.119:1001/swagger.
When connecting locally, everything is fine and I can access Swagger UI on port 1001 as expected.
But when trying connect throug proxy on port 1000 (which redirects 1000 to 1001), I get a well known error:
"Can't read from server. It may not have the appropriate access-control-origin settings".
I have read this:
Unable to access swagger despite cors enabled Asp.NET WebAPI
and tried to set the RootUrl manually in Startup file, within Swagger like this:
.EnableSwagger(c =>
{
c.RootUrl(req => #"http://192.168.7.119:1001";
...
});
CORS settings are set as:
appBuilder.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
Any hints what am I doing wrong here?
Putting together this two pages from github repos of Swashbuckle the easy way to do what you're asking is:
From Github Make sure that your proxy is sending the X-Forwarded-* headers (Apache does it out of the box while Nginx doesn't seems so. You have to do some changes on the nginx conf.
From Github. Create this HttpRequestMessageExtensions static class with the ComputeHostAsSeenByOriginalClient method and then
.EnableSwagger(c =>
{
c.RootUrl(req => req.ComputeHostAsSeenByOriginalClient());
...
});

CORS error in dev environment; works OK locally

I am trying to make an api call from a vue application to a .net core web api. Locally this works, when we then run it on our first dev environment we get this when it trys to make the request
Access to XMLHttpRequest at
'https://bla-api/api/foc?page=1&pageSize=10&sortBy=&sortDirection=ASC'
from origin 'https://bla-api' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I have added the following to the C#' Startup file in the ConfigureServices method. To just get it working I wanted to provide the *(wildcard), so let anyone call this. So presume that the named policy AllowAnyOrigin would do this!?
readonly string _SpecificOrigins = "AllowSpecificOrigins";
services.AddCors(options =>
{
options.AddPolicy(_SpecificOrigins,
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
})
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
then also added this in the Configure method
app.UseCors(_SpecificOrigins);
app.UseMvc();
What am I missing? I also try and make a fiddler request to the api and it breaks.
Any help would be greatly appreciated
This was a red herring, the web api was not even deployed correctly, it was being deployued as a kestrel exe but was deployed as an azure web app. Adding a web.config pointing to the main api project resolved the issue. I did not write the deployment so that no needs looking at next. Presume the above question is fine then, cheers for the help

How to add a signalr pipeline module in Azure mobile service

I want to add a signalr pipeline module as described here.
The article says to add code to startup.cs file but I don't have such a class in my mobile service. Also, the code uses GlobalHost which from my (limited) experience does not really work inside a mobile service.
I tried adding this line in WebApiConfig class but it doesn't work:
GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule());
I couldn't find the answer anywhere so I dug in the mobile services signalr assembly and found the solution.
To add your own module, add the following code to WebApiConfig:
var hubPipeline = config.DependencyResolver.GetSignalRDependencyResolver().Resolve<IHubPipeline>();
hubPipeline.AddModule(new MyModule());

Categories