I have web API and Angular app for him.
I enabled cors policy on web api side:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", b =>
{
b.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
}
);
});
app.UseCors("CorsPolicy");
I send get request from Angular like this:
this._httpClient.get(`WebApi link`);
but catch error:
Error during WebSocket handshake: Unexpected response code 400
What am I doing wrong?
This link perfect work in PostMan and I'm getting the result.
Web API uses win auth.
UPD
Web API side has this setting in Startup.cs:
public class Startup
{
private readonly ILoggerFactory _loggerFactory;
public Startup(IHostingEnvironment env, ILoggerFactory loggerFactory)
{
AutomapperConfig.Init();
_loggerFactory = loggerFactory;
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.AddMvc();
services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);
services.AddAuthorization(options =>
{
foreach (var action in Action.All)
options.AddPolicy(action.Name, policy =>
policy.Requirements.Add(new AssemblyStorageRequirement(action)));
});
services.AddSingleton<IAuthorizationHandler, AssemblyStorageRequirementHandler>();
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", b =>
{
b.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
}
);
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
services.AddOptions();
services.AddSingleton(Configuration); // IConfigurationRoot
services.AddSingleton<IConfiguration>(Configuration); // IConfiguration explicitly
return services.AddDiConfig(Configuration);
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
/// <param name="loggerFactory"></param>
/// <param name="appLifetime"></param>
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
loggerFactory.AddLog4Net();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
app.UseAuthentication();
app.UseResponseCompression();
app.UseCors("CorsPolicy");
app.UseMvc();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
appLifetime.ApplicationStopped.Register(DiConfig.DisposeContainer);
}
}
The Angular side has this setting in Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", b =>
{
b.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
}
);
});
}
// 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();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseCors("CorsPolicy");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
}
Request Headers: GET wss://localhost:44391/sockjs-node/616/kjiu00aa/websocket HTTP/1.1 Host: localhost:44391 Connection: Upgrade Pragma: no-cache Cache-Control: no-cache Upgrade: websocket Origin: https://localhost:44391 Sec-WebSocket-Version: 13 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36 Accept-Encoding: gzip, deflate, br Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7 Sec-WebSocket-Key: Ia0VO1G8+d52FJG74UvsQw== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Response Headers:
HTTP/1.1 400 Bad Request Transfer-Encoding: chunked Vary: Origin Server: Kestrel Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: https://localhost:44391 X-SourceFiles: =?UTF-8?B?RTpcUHJvamVjdHNcVEZTXE9jdG9wdXNTZXJ2aWNlc1xBc3NlbWJseVN0b3JhZ2VcQXNzZW1ibHlTdG9yYWdlV2ViU2l0ZVxBc3NlbWJseVN0b3JhZ2VXZWJTaXRlXHNvY2tqcy1ub2RlXDYxNlxraml1MDBhYVx3ZWJzb2NrZXQ=?= X-Powered-By: ASP.NET Date: Fri, 15 Mar 2019 08:03:32 GMT
General:
Request URL: wss://localhost:44391/sockjs-node/616/kjiu00aa/websocket Request Method: GET Status Code: 400 Bad Request
UPD
If I comment out the only place in the code where HttpClient is used, then the error still show...
So the problem is not in WebApi
wss://localhost:44391/sockjs-node/...
is a web-socket connection back to the SPA server being hosted via the Angular CLI, so at this stage this is difficult to diagnose. The next step would be to look at the server logs and see what exactly is happening when processing that request. - Kirk Larkin