Dot Net Core Web API Return Response From Endpoint - api

I'm busy trying to create a very simple Dot Net Core Web API (Dot Net 5) and I've run into a strange issue where I cannot get the endpoint to return a response.
I've tried to use
await context.Response.WriteAsync("Hello World!");
as per the documentation but I'm getting the error
'HttpResponse' does not contain a definition for 'WriteAsync'
This is the full Startup.cs code
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services) { }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
app.UseRouting();
app.UseEndpoints(endpoints => {
endpoints.MapGet("/test", async context => {
//Console.WriteLine("Exec Test");
await context.Response.WriteAsync("Hello World!");
});
});
}
}
I'm sure there's something I'm missing

Add the dependency for Microsoft.AspNetCore.Http.Abstractions.dll which contains the WriteAsync method you are looking for based on the HttpResponse.
Please refer to the following documentation:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.httpresponsewritingextensions.writeasync?view=aspnetcore-5.0
https://www.carlrippon.com/asp-net-5-hello-world/

Related

http post action not reached in ASP.NET Core 3.1 web API controller

I have this controller
[ApiController]
[Route("api/[controller]")]
public class PlanningController: ControllerBase
{
public async Task<IActionResult> SaveTest([FromBody] TestData data)
{
return Ok(data);
}
public class TestData
{
public int Id { get; set; }
public string Name { get; set; }
}
This in Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors("default");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.Run(context => context.Response.WriteAsync("Planificador API iniciada"));
}
I put a break point in the return but when I post this in postman
nothing happens in my controller the break point is not reached.
I don't understand the response received in postman
In VS 2022 I see this
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request
starting HTTP/1.1 POST
http://localhost:5001/api/planning/saveTest application/json 34
Microsoft.AspNetCore.Hosting.Diagnostics[1]
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 8.3968ms 200
Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 8.3968ms 200
Any idea, please?
Thanks
Nothing happens in my controller the break point is not reached.I
don't understand the response received in postman
Well, because of using [Route("planning")] before your PlanningController it is certainly overriding your application standard routing. So, your controller route has been changed. Thus, you shouldn't manipulate this routing [Route("api/[controller]")]
Correct Way:
[Route("api/[controller]")]
[ApiController]
public class PlanningController : ControllerBase
{
[HttpPost]
[Route("saveTest")]
public async Task<IActionResult> SaveTest([FromBody] TestData data)
{
return Ok(data);
}
}
Update:
Stratup.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.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "TestWebAPIProject", Version = "v1" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TestWebAPIProject v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Output:
Note: I would highly recommend you to have a look on our official document for Custom route constraints
Solved...
The problem was tha in my controller I was injected IFileProvider wrong
Unable to resolve service for type 'Microsoft.Extensions.FileProviders.IFileProvider' while attempting to activate my controller

.net core not showing HTML static file changes

I made some changes to the static file index.html but running via .net-core and inspecting elements these changes do not apply however when I open the static file via live server extension of vscode I can see the changes.
I am very new to .net core, I looked up a few threads but couldn't find what the problem is or a similar one.
My Startup class looks as so:
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.AddControllers();
services.AddMvc().ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[404].Link =
"https://httpstatuses.com/404";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
also, the project repository is here
Thanks to everyone who takes their time to help.

ASP.NET Core Odata Service Post not working

I implemented a ODATA Service in my ASP.NET Core application. The GET function is working fine, but I have some problems with the POST function.
If I excecute a POST the programm is excecuting the right method but I don't receive any data.
Is there anything missing in my code?
Controller:
[EnableCors]
[ODataRoutePrefix("documents")]
public class DocumentController : ODataController
{
[ODataRoute]
[EnableQuery]
public Document PushDocument([FromBody]Document doc)
{
System.Diagnostics.Debug.WriteLine("DomentID: " + doc.Id);
System.Diagnostics.Debug.WriteLine("Dokument: " + doc.RawDocument);
return doc;
}
}
Since you use [FromBody], you need to send data as Content-Type: application/json,in postman:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddOData();
services.AddMvc(options =>
{
options.EnableEndpointRouting = false;
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// 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
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc(b =>
{
b.MapODataServiceRoute("odata", "odata", GetEdmModel());
});
}
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Document>("Documents");
builder.EntitySet<Press>("Presses");
return builder.GetEdmModel();
}

.Net Core 2.x Redirect to Error Page

I have a simple ASP.Net Core 2.0 web application and I have enabled Windows Authentication in project property by enabling Windows Authentication and disabled Anonymous Authentication.
For Authorization at Application/Site level filtering by AD security group, I have the following code 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();
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireRole("Application - Administrator")
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
}
// 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.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
//app.UseStatusCodePagesWithRedirects("/Home/Error/{0}");
//app.UseStatusCodePagesWithReExecute("/Home/Error", "?statusCode={0}");
app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
To handle Http 403 status code when a un-authorized user tries to access the application, it will be redirect to a custom error page. So I tried the following 3 approaches in Configure method within Startup.cs:
app.UseStatusCodePagesWithRedirects("/Home/Error/{0}");
app.UseStatusCodePagesWithReExecute("/Home/Error", "?statusCode={0}");
app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
In the HomeController, I tried both the default Error method
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
and customized one to handle specific status code:
public IActionResult Error(string errCode)
{
if (errCode == "500" || errCode == "404" || errCode == "403")
{
return View($"~/Views/Error/{errCode}.cshtml");
}
return View("~/Views/Shared/Error.cshtml");
}
And I have a simple error page 403.cshtml under /Views/Error/ folder.
But none of them works, all display this page:
I am wondering if something I missed or forgot to implement for display a formatted error page?
Thanks in advance.
I am not 100% sure but there should be 2 variations of windows authentications:
The host only allows authenticated users
When you enable Windows Authentication and disable Anonymous Users
[Authorize] and [AllowAnonymous] no effect, because unauthenticated requests never reach your application
Hence you can't / don't need to set up global filter. You might have to setup the friendly error pages on the server?
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/home/error");
}
app.UseStaticFiles();
app.UseMvcWithDefaultRoutes();
}
}
The host allows both anonymous and authenticated users
When you enable both Windows Authentication and Anonymous Users
[Authorize] requires additional setup on Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireRole("Application - Administrator")
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseStatusCodePagesWithReExecute("/error", "?code={0}");
app.UseAuthentication();
app.UseMvcWithDefaultRoutes();
}
You need to use [AllowAnonymous] on the error controller to override the [Authorize] global filter to allow anonymous requests.
[AllowAnonymous]
public class ErrorController : Controller
{
public IActionResult Index(int? code)
{
...
}
}
The problem is at the Error method, it missed the AllowAnonymous attribute to allow anonymous access to the error method when the user failed authorization.
Credit to #Calc
Try app.UseStatusCodePagesWithRedirects("/Home/Error/{0}"); in startup.configure(IApplicationBuilder app, IHostingEnvironment env)
Works on ASP.NET CORE2.0 web app
It will handle any kind of HTTP error

asp.net core CORS not working as I would expect

I've got a node app that is hosted at localhost:9000 running (React with Express). I'm making an axios REST POST to my ASP.NET Core 2.0 web project with as follows:
http://localhost:50494/rest/sessions
GET works but POST does not. In My Startup.cs files I believe I've set all origins and methods to be allowed on my asp.net core end points but still I'm getting what I think is a CORS not setup error.
http://localhost:50494/rest/sessions/6184: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.
Here is my setup on the asp.net side:
Program.cs
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
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.AddCors();
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles();
app.UseCors(builder =>
builder.AllowAnyOrigin().AllowAnyMethod());
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
Why am I getting this error?