Angular with OData batch request fails on IIS - asp.net-core

I am using Odata with .Net Core web api. For client side i am usin angular 13. OData batch request works fine in localhost. After published on iis with 'ng-build' i am getting a cors error from odata batch request. I already allow origins. What am i missing?

I am not sure but think it was really related with cors.
I only added this code block in to "Configure" method in startup.cs and problem solved.
app.Use((context, next) => {
context.Response.Headers["Access-Control-Allow-Origin"] = "*";
return next.Invoke();
});
But before the batch, i didn't need this code block i have added. All request works fine (except batch) without the code block i have added. I am trying to understand this part.

Related

PATCH request losing body on IIS but not on localhost

I have a web API, where I'm trying to support a PATCH request with a JSON Patch body to make changes to an object on the server.
I am using ASP Core with .Net 6, hosting using IIS on my web host.
This is the controller method:
public class BaseDataController<TEntity, TDetail, TNew> : ControllerBase
where TEntity : class, IIdentifiable
{
[HttpPatch("{id}")]
public virtual async Task<ActionResult<TDetail>> Patch(Guid id, [FromBody] JsonPatchDocument<TEntity> patch)
{
var item = await MainService.GetAsync(id);
if (item == null)
{
ControllerLogger.ItemNotFound();
return NotFound();
}
patch.ApplyTo(item, ModelState);
ValidationHelper.ValidatePatch(item, ModelState);
if (!ModelState.IsValid)
return BadRequest(ModelState);
await MainService.UpdateAsync(item);
return this.GuardResult(Mapper, item);
}
}
When I try to use this on my local machine, it works just fine. When I deploy to my web server, and make an identical request, I get a validation error and a 400 status code:
{"errors":{"":["A non-empty request body is required."],"patch":["The patch field is required."]}}
If I change HttpPatch to HttpPost and update the web request accordingly, it works fine.
Can anyone suggest what might be going wrong here? I'm assuming the server is baulking at the PATCH verb, but I can't work out how to make it happy. Googling is coming up with a load of WebDAV things, but the error codes don't match and ASP is clearly receiving the request (proven from the logs) when the description of the WebDAV issues suggests it wouldn't.
My working theory is that IIS is seeing the PATCH verb and doing something to the request body that ASP Core doesn't like, but I can't work out why or where to look to turn that sort of thing off.
When I try to use this on my local machine, it works just fine. When I
deploy to my web server, and make an identical request, I get a
validation error and a 400 status code: If I change HttpPatch to HttpPost and update the web request accordingly, it works fine
Well, your scenario is pretty obvious in context of IIS as you may know Http verb PATCH is not enabled as default accepted http verb on IIS Request Restrictions As you can see below:
Solution:
To resolve above incident, you outght to configure Request Restrictions on IIS and need to include ,PATCH so that it will allow http PATCH verb. On top of that, after that, please restart your application pool. You can follow below steps to implement that:
Step: 1
Select your app on IIS and then click on Handler Mappings Just as following
Step: 2
Select (Double click) ExtensionlessUrlHandler-Integrated-4.0
Step: 3
Click on Request Restrictions
Step: 4
Select VERB then include PATCH by comma seperated value as ,PATCH and click OK finally restart your application pool.
Note: For more details you can have a look on our official document here.

Unable to make HTTP post request to .NET Core MVC

I'm currently working on a project where I'm using ASP.NET Core MVC (views are running on another port using Vue). I have set up my models and controller set up and I've tested these using swagger. They work exactly as expected. I have tested the post method on swagger and it works, but requests from my view on another port running Vue and Postman return a 405 error. Inspecting the response headers on Postman, I can see "Allow : DELETE, GET, PUT". Because my view will be running on another port, I've already added CORS the following to my startup configure method (not currently concerned about security implications):
app.UseCors(builder => {
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
My controller features the following for the POST method:
[ResponseType(typeof (Review))]
[HttpPost]
public async Task Post(Review review)
{
db.Reviews.Add(review);
await db.SaveChangesAsync();
}
I am accessing the URL on Postman from https://localhost:44334/reviews/Post. Reviews being the controller and post is the method. I am not receiving any cross original control errors, just this 405. Why might it be doing this and how can I debug this?
I was trying to post to https://localhost:44334/reviews/Post but my router was not set up like this. Changing the URL to https://localhost:44334/reviews/ and setting the method to Post worked and returned a success 200 response.
It is very common issue. For requests coming from localhost AllowAnyOrigin() doesn't work. You need to allow the origin explicitly like:
services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
{
builder.WithOrigins("http://localhost:8080").AllowAnyMethod().AllowAnyHeader();
}));
In the configure method tell CORS to use the policy you just created:
app.UseCors("ApiCorsPolicy");
Requests from postman passes the CORS because they attach special headers.

How to debug the server (kestrel) of aspnet core

I ran my head against a issue where i have no idea how to continue.
In short my problem is that the request finishes the aspnet core pipeline as everything being okay. But the content never reach the browser.
Testing in postman where it it tells me there was an error connecting. But when debugger is enabled i can step all the way through the aspnet core pipeline and nothing is faulting. Their build in logger also tells me a 200 is returned.
Adding
app.Use(async (ctx, next) =>
{
ctx.Response.OnCompleted(c =>
{
return Task.CompletedTask;
},null);
also trigger the on completed, so all indicates that the aspnet pipeline runs that it works. All integration tests also work with the in mem test server.
When i invoke it from the browser, the loading spinner just keeps running and the request never comes up in the network tab, so nothing to help me figure out why this fails.
What can I do to find out why its not working. Can i get some debugger/logging on the kestrel server to see if it writes out exceptions?

XSRF-TOKEN not updated when using IISExpress and localhost

.Net Core api layer and .Net Core MVC w/ Angular2 front end. Locally, they are running in different website (localhost:xxx1 and localhost:xxx2) and published, the api is running in a sub directory of the frontend.
I've set up the .Net Core Antiforgery like so:
in the ConfigureServices section:
services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
});
in the Configure section:
app.Use(next => context =>
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
return next(context);
});
When i initially launch the sites and browse to the website in Chrome, I do get the 2 Antiforgery tokens (.AspNetCore.Antiforgery.xxxx and the XSRF-TOKEN) and when I make a get/post/etc call I see the x-xsrf-token header is added to the call.
The problem is on each call, the api returns a new XSRF-TOKEN cookie but locally my cookie is not updated, it always contains the original value. When published online, this doesn't happen, the cookie updates every time.
I've tried setting the sites up locally to use localhost.somedomain.com but that didn't work.
Any suggestions as to what I'm doing wrong or how to get it working locally?
The issue on my local machine was that I was running each app in its own IIS Express (localhost:xxx1 and localhost:xxx2).
I ended up setting IIS up to host .net core following this article (https://learn.microsoft.com/en-us/aspnet/core/publishing/iis) and i'm getting the expected result.

I am getting net error ERR_CONNECTION_RESET when calling an API method using ajax

We have a IIS 8 web server on which Web API is deployed. We have a front end application written in extJS. When the application accessed, it makes sever API calls to the server and many of these calls return success except one specific API call. Chrome says request status as cancelled (ERR_CONNECTION_RESET), and I am not able to figure out how to troubleshoot and fix this error. I have checked many places online but I could not get much help.
Please help.
Are you using Entity Framework Core? If so, you may have an object graph loop in your many-to-many relationships as EFCore does not support lazy loading at this time.
If so, you can configure your serializer to not follow graph loops.
In your Startup.cs file, replace the services.AddMvc() line with this:
services.AddMvc()
.AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);