i have this code for receiving data from server:
try
{
var data = _model.GetAll().ToList();
if (data.Count > 100)
return SendMessage($"Too much results", HttpStatusCode.Forbidden);
var result = JsonConvert.SerializeObject(data,
new JsonSerializerSettings { Converters = new JsonConverter[] { new StringEnumConverter() } });
return SendMessage(new{ results = result });
}catch (Exception ex)
{
return SendMessage("Server error.", HttpStatusCode.InternalServerError);
}
SendMessage method:
protected JsonResult SendMessage(string message, object data, HttpStatusCode code = HttpStatusCode.OK)
{
Response.StatusCode = (int)code;
return Json(new { message, data }, JsonRequestBehavior.AllowGet);
}
When method return 403 http code, i localhost is everything ok. Method send data in content-type application/json. But when I deploy my code to web server (IIS 7) method send content-type text/html and data is empty.
Where is problem? How i must configure IIS server?
Thanks for advices
Here is solution for my problem: https://forums.iis.net/t/1213176.aspx.
Open your IIS > click web site > Error Pages > here under "Alerts" section click on "Edit Features Settings..." it will show following three option :
1] Custom error pages
2] Detail errors
3] Detailed errors for local requests and custom error pages for remote requestes.
select 2nd option Detail errors click Ok.
Related
I'm facing a behavior in Minimal API that I can't understand.Consider the following simple Minimal API:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseExceptionHandler((exceptionApp) =>
{
exceptionApp.Run(async context =>
{
context.Response.ContentType = MediaTypeNames.Text.Plain;
var feature = context.Features.Get<IExceptionHandlerPathFeature>();
if (feature?.Error is BadHttpRequestException ex)
{
context.Response.StatusCode = 400;
var message =
(ex.InnerException is JsonException)
? "The request body is an invalid JSON"
: "Bad Request";
await context.Response.WriteAsync(message);
}
else
{
context.Response.StatusCode = 500;
await context.Response.WriteAsync("There is a problem occured");
}
});
});
app.MapPost("/models", (Model model) => Results.Created(string.Empty, model));
app.Run();
public record Model(int Value, string Title);
When I run the application in the Development environment, and pass an invalid JSON like
{
"value": 1,
"Title": Model #1
}
the custom exception handler is called and I have to control the behavior of the API. But whenever
I run the application in the Production environment, the framework automatically returns a
"bad request" response without letting me control the response.
Could anyone explain this behavior to me? I really need my exception handler to handle invalid input
JSON exceptions.
Thanks
After digging into ASP.Net Core source code for a while, I found that the following line resolves the issue.
builder.Services.Configure<RouteHandlerOptions>(o => o.ThrowOnBadRequest = true);
I'm learning Blazor.
I have created a Blazor WASM App with the "ASP.NET Core Hosted" option.
So I have 3 projects in the solution: Client, Server and Shared.
The following code is in the Client project and works perfectly when the endpoint is correct (obviously). But at some point I made a mistake and messed up the request URI, and then I noticed that the API returned an HTML page with code 200 OK (as you can see in the Postman screenshot below the code).
I expected one of my try-catches to get this, but the debugger jumps to the last line (return null) without throwing an exception.
My first question is why?
My second question is how can I catch this?
I know fixing the endpoint fixes everything, but would be nice to have a catch that alerts me when I have mistyped an URI.
Thanks.
private readonly HttpClient _httpClient;
public async Task<List<Collaborator>> GetCollaborators()
{
string requestUri = "api/non-existent-endpoint";
try
{
var response = await _httpClient.GetFromJsonAsync<CollaboratorsResponse>(requestUri);
if (response == null)
{
// It never enters here. Jumps to the last line of code.
}
return response.Collaborators;
}
catch (HttpRequestException)
{
Console.WriteLine("An error occurred.");
}
catch (NotSupportedException)
{
Console.WriteLine("The content type is not supported.");
}
catch (JsonException)
{
Console.WriteLine("Invalid JSON.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return null;
}
it is a never good idea to use GetFromJsonAsync, You are not the first who are asking about the strange behavior. Try to use GetAsync. at least you will now what is going on.
var response = await client.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<CollaboratorsResponse>(stringData);
... your code
}
else
{
var statusCode = response.StatusCode.ToString(); // HERE is your error status code, when you have an error
}
Angular service.ts:
getExcel() {
let link: string = (this.url);
return link;
}
component.ts:
public getExcel() {
//checks if string is empty, undefined or not null
if (this.langCode) {
return window.open(this.avrs.getExcel());
}
}
Java rest.java
#GET
#Path("/excel")
#Produces("application/vnd.ms-excel")
public Response getTransportCostsExcel(
#Context HttpServletRequest request,
) {
byte[] excelInBytes = excelGen.getExcel();
if(excelInBytes == null){
return Response.status(Response.Status.NOT_FOUND).entity("No data").build();
}
//Header details
String contentType = "application/vnd.ms-excel";
Response.ResponseBuilder responseBuilder = javax.ws.rs.core.Response.ok((Object) excelInBytes);
responseBuilder.type(contentType);
responseBuilder.header("Content-Disposition", "attachment; filename=" + fileName);
//Returns Excel
return responseBuilder.build();
}
When I try calling my api from postman i get "No data" and status is 401 not found. So the rest method works fine.
I get my excel file if data is found. But I can't seem to handle the 401 response. Angular opens a new window and says
site not avaliable: ERR_INVALID_RESPONSE
As you can see im not using http.get cause I want the user to start downloading the excel if the file is found.
I try to use swagger ui for rest api documentation. Rest API created with WCF service. I solved cors issue, service accepts OPTIONS method. But request has a header parameter which name is SessionUUID, this parameter doesn't send to service. When i debug the service side, this parameter does not come. This problem is only in Chrome. Chrome blocks to header params in cors request.
Cors problem's solving on WCF Service like this;
I added new behavior and header params are defined
public class EnableCorsEndpointBehavior : BehaviorExtensionElement, IEndpointBehavior
{
...
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
var requiredHeaders = new Dictionary<string, string>();
requiredHeaders.Add("Access-Control-Allow-Origin", "*");
requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
requiredHeaders.Add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept, Accept-Language, SessionUUID, Origin, X-Custom-Header, sessionuuid");
requiredHeaders.Add("Access-Control-Allow-Credentials", "true");
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new ServiceInspector(requiredHeaders));
}
...
}
I added response headers in inspector. Header parameter which named as SessionUUID is checked in AfterReceiveRequest but it is null, because of this problem.
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
try
{
WebHeaderCollection headers = WebOperationContext.Current.IncomingRequest.Headers;
string requestTo = request.Headers.To.ToString();
if (!requestTo.Contains("login") && request.GetType().Name != "InternalByteStreamMessage")
{
if (headers["SessionUUID"] == null)
{
throw new RestAppException("401", "Oturum bilgisi bulunamadı.");
}
else
{
DateTime requestDate = DateTime.Now;
string sessionUUID = headers["SessionUUID"] != null ? headers["SessionUUID"].AsString() : headers["sessionuuid"].AsString();
sessionManager.CheckSessionByUUID(sessionUUID, requestDate);
sessionManager.UpdateExpireDate(sessionUUID, requestDate);
sessionManager.SetSessionByUUID(sessionUUID);
}
}
}
catch (RestAppException ex)
{
ex.Message = "İşlem Başarısız";
throw ex;
}
catch (Exception ex)
{
throw ex;
}
return null;
}
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
foreach (var item in requiredHeaders)
{
httpHeader.Headers.Add(item.Key, item.Value);
}
}
How can i solve this chrome issue?
You will have to add a Chrome extension to allow custom headers.
Here are some that you could use:
WebRequestAPI
Mod Header
In case you want to try out Mozilla Firefox, use its extension modify-headers.
I had a similar problem . It may be related to the url.
My problem was solved when I entered with "www".
If already you entered with "www", delete this and try again.
I have an action which returns an error with JSON:
public JsonResult Error()
{
this.Response.StatusCode = (int)HttpStatusCode.BadRequest;
return this.Json(new { error = "some error" }, JsonRequestBehavior.AllowGet);
}
When I test this locally, the body of the response is:
{"error":"some error"}
as expected but when published to Azure, the response body is
Bad Request
Why would there be a different behavior and how can I make Azure respond with the JSON?
Try telling IIS to not use it's error pages by using Response.TrySkipIisCustomErrors.
Resulting code would look like:
public JsonResult Error()
{
this.Response.StatusCode = (int)HttpStatusCode.BadRequest;
this.Response.TrySkipIisCustomErrors = true;
return this.Json(new { error = "some error" }, JsonRequestBehavior.AllowGet);
}
Simply put
<system.webServer>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
in the web.config file.
I found the solution through this blog post.