C# MVC RouteBase routing too many redirects - c#

I have this custom routing system where i will get the paths, controllers, views and areas from my DB and set them according to the requested path.
My problem right now is that when i try to access one page it gives me the too many redirects response.
What happens in this area is:
User access page and fill a form;
Form is posted using AJAX and then a redirect is made from jquery;
User makes an appointment or generate a voucher;
If the user tries to return to the previous page by typing it on the browser( i don't have any button to that link ) he gets the too many redirects problem.
Since the code is kind of big i'm going to post it here: http://pastebin.com/yTdWKMp4
I only left out my DB logic.
What could be doing this ? I only could see the problem in this area but i don't know for sure it isn't happening in other areas.
EDIT
These are the headers from the requests
HTTP/1.1 302 Found
Cache-Control: private, no-store, max-age=1
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: Wed, 25 Nov 2015 19:01:23 GMT
Last-Modified: Wed, 25 Nov 2015 19:01:22 GMT
Etag: ""
Location: /teste-lp
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-UA-Compatible: IE=Edge,chrome=1
Date: Wed, 25 Nov 2015 19:01:22 GMT
Content-Length: 115
HTTP/1.1 200 OK
Cache-Control: private, no-store, max-age=1
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: Wed, 25 Nov 2015 19:02:10 GMT
Last-Modified: Wed, 25 Nov 2015 19:02:09 GMT
Etag: ""
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-UA-Compatible: IE=Edge,chrome=1
Date: Wed, 25 Nov 2015 19:02:12 GMT
Content-Length: 6852
EDIT 2
After much debugging and logging i found the beginning of the problem, it's related to a redirect i have when a certain session is null:
if (TempData["LeadID"] == null || Session["UnidadeCE"] == null)
{
Response.Redirect( HelperMethods.CreateLink( Request.RawUrl.TrimStart( '/' ).Split( '/' )[0] ) );
Response.End();
return null;
}
I have this verification at the appointment and voucher, if he tries to reload the page he is redirected to the form page. Now what is weird is, when he changes URL the RouteBase executes and tries to fetch the PageInfo( VirtualPath, Controller and View ) for that new URL and at the moment of my search for some reason i'm getting the page of appointment instead of the form one so i get back at the same page and the looping starts.
I have updated my pastebin with the filtering and DB Search, there are no repeated records in my DB. It looks like some sort of freaking cache but the var is local and there's no sharing.
EDIT 3
After some var watching ( i have nearly 6k routes ) i found that the problem lies between my route checking on the pastebin file on line 128, that pageList parameter is my list of all routes from the cache, i do a url search based and then i take the route that i need, on line 167 is where my problem is located. At that moment i have copied the content of the route i want into my freakingPage var (not so cool, i know) and then i change the values of Action and Controller but what also happens is the value changes on the pageList var and also at the Cache, line 203.
What could be causing this ?

After some research I found that my problem was related to the fact that I wasn't using Clone on the values that were coming from the cache. Since the .NET cache keeps a reference value when you get its value, it's necessary to implement ICloneable on the object you are getting from it.
Since I was only "putting" the value on another var and later editing this var I was in fact changing the original value on the cache... and with that I was getting a wrong return when I would hit the cache again.
In my case I was getting a redirect because of some Session verification that I was doing on my Controller, on the first time (freshly made cache) I would hit the correct page. But after I would try to re-enter the same page, I would get a different value from it.
To correct it I implemented ICloneable on my Model. I have also changed my example with the new approach if anyone also have this problem.
http://pastebin.com/yTdWKMp4

Related

Is it possible to change the order of the Headers in a HttpWebResponseMessage using the ApiController?

I have a legacy project which uses .NET Framework 4.5.2 and NancyModule.
When I get the result of a GET-request, then the Headers have the following order:
Key
Value
Content-Length
206
Content-Type
application/json; charset=utf-8
Vary
Accept
Server
Microsoft-HTTPAPI/2.0
Link
</Servicename.xml>; rel="application/xml"
x-powered-by
...
Date
Tue, 31 Jan 2023 13:25:07 GMT
I transfer this project to .net 6 and Microsoft.AspNetCore.Mvc.
When I get the result of a GET-request, then the keys of the Headers are arranged alphabetically.
This leads me to the following question:
Is it possible to change the order of the headers?
I tried to remove and add several values of the dictionary in HttpContext.Response.Headers but it has no entries. When I added a custom header then it was also in alphabetical order.
If you are using Kestrel (the default web server in ASP.NET Core) you might want to remove the Server header in order to try to have the Date header last.
But that would be very fragile, you can't really control the order of the headers, see the source code of how it's done!
For simple HTTP responses that don't set any special headers, this might work and you might end up with something like that. Note the many conditionals used in the previous sentences. 😉
HTTP/1.1 200 OK
Content-Length: 4536
Content-Type: text/plain
Date: Tue, 31 Jan 2023 14:58:31 GMT
And here's how to disable the Server header for Kestrel:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions => serverOptions.AddServerHeader = false);
If you need to use HTTP.sys instead of Kestrel then you'll be out of luck since the Content-Length header is added after the Date header and there's nothing you can do about it.
HTTP/1.1 200 OK
Content-Type: text/plain
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 31 Jan 2023 15:11:23 GMT
Content-Length: 4536

Is Dot Net HttpClient Unexpectedly Caching Responses?

I'm attempting to write a curl-like tool that demonstrates the effect of various HTTP caching headers on dot net's HttpClient class.
In my initial attempt I'm pointing the tool at one of my internal web services that does not specify any caching information in the response and examining the header of the response.
I expect to see that the request is re-sent each time and executed on the server, returning a new but identical set of content each time (for the purpose of this test, the content is static on the server). But, instead, each request after the first returns much more quickly than the first and includes a new header Age that was not present in the very first response. This indicates to me that the HttpClient in my command-line tool is returning the response from cache, not placing a new request.
Here is the first request with the response headers:
HTTP:>GET http://myserver:8058/path1/path2
Status 200 OK (OK in 00:00:00.3235905):
Date = Sat, 08 Jul 2017 15:55:22 GMT
Server = Microsoft-HTTPAPI/2.0
Content-Length = 150867
Content-Type = application/json; charset=utf-8
and here is the request from the same session of my curl tool, a little while later:
HTTP:>GET http://myserver:8058/path1/path2
Status 200 OK (OK in 00:00:00.0188433):
Date = Sat, 08 Jul 2017 15:55:22 GMT
Server = Microsoft-HTTPAPI/2.0
Age = 312
Content-Length = 150867
Content-Type = application/json; charset=utf-8
and finally, after I stop and start my program, here's another request from the new instance:
HTTP:>GET http://myserver:8058/path1/path2
Status 200 OK (OK in 00:00:00.0517271):
Date = Sat, 08 Jul 2017 15:55:22 GMT
Server = Microsoft-HTTPAPI/2.0
Age = 528
Content-Length = 150867
Content-Type = application/json; charset=utf-8
The last one I find even more difficult to understand as I was under the impression (from reading this: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/) that caching is maintained per instance of HttpClient.
This seems to continue forever with Age increasing each request. The only way to get back to the original response is to use Internet Explorer and delete temporary internet files.
[Additional Info] After leaving my command line application open for a couple of hours I repeated the request and received a response identical to the original, without the Age header. So it appears that, if HttpClient was caching the response, that cache expired after a couple of hours.
Can anyone tell me if I'm correct that HttpClient is performing internal caching in this case, and if so, why it's doing so in the absence of any caching-related response headers and what policy it's using?

Why when I do redirect in Web API it sends EXPIRES HEADER with value -1 in the response?

I think this is not the correct behavior, based on the RFC 2616.
The format is an absolute date and time as defined by HTTP-date in section 3.3.1; it MUST be in RFC 1123 date format:
Expires = "Expires" ":" HTTP-date
An example of its use is
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Note: if a response includes a Cache-Control field with the max-
age directive (see section 14.9.3), that directive overrides the
Expires field.
For example:
public class ValuesController : ApiController
{
public IHttpActionResult Get()
{
return this.Redirect("http://localhost:60650/");
}
}
Then, I do call via Fiddler:
Then, I have two responses, the first one is the redirect (HTTP 302):
HTTP/1.1 302 Found
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Location: localhost:60650
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcaWdvci5jYW1wb3NcZG9jdW1lbnRzXHZpc3VhbCBzdHVkaW8gMjAxNVxQcm9qZWN0c1xSZWRpcmVjdFRlc3RcUmVkaXJlY3RUZXN0XGFwaVx2YWx1ZXM=?=
X-Powered-By: ASP.NET
Date: Mon, 09 May 2016 20:35:37 GMT
Content-Length: 0
Why ASP.NET sends the "Expires" HEADER with value -1 in this redirect?
From section 14.21 of the RFC you linked:
HTTP/1.1 clients and caches MUST treat other invalid date formats,
especially including the value "0", as in the past (i.e., "already
expired").
In other words, don't cache the fact that hitting this URL results in a redirect.
If you want it cached (and a permanent redirect result to the browser), use:
public IHttpActionResult Get()
{
return this.RedirectPermanent("http://localhost:60650/");
}

(Instagram API) Trouble Reaching Tag Endpoints

I'm trying to gather a list of recent posts that contain a certain hashtag. The API Documentation states that I should be using the following GET call:
https://api.instagram.com/v1/tags/{tag-name}/media/recent?access_token=ACCESS-TOKEN
When I load the page where I want this information displayed, I perform the following:
using(HttpClient Client = new HttpClient())
{
var uri = "https://api.instagram.com/v1/tags/" + tagToLookFor + "/media/recent?access_token=" + Session["instagramaccesstoken"].ToString();
var results = Client.GetAsync(uri).Result;
// Result handling below here.
}
For reference, tagToLookFor is a constant string defined at the top of the class (eg. foo), and I store the Access Token returned from the OAuth process in the Session object with a key of 'instagramaccesstoken'.
While debugging this, I checked to make sure the URI was being formed correctly, and it does contain both the tag name and the just-created access_token. Using Apigee with the same URI (Save for a different access_token) returns the valid results I would expect. However, attempting to GET using the URI on my webstie returns:
{
StatusCode: 400,
ReasonPhrase: 'BAD REQUEST',
Version: 1.1,
Content: System.Net.Http.StreamContent,
Headers:{
X-Ratelimit-Remaining: 499
Vary: Cookie
Vary: Accept-Language
X-Ratelimit-Limit: 500
Pragma: no-cache
Connection: keep-alive
Cache-Control: no-store, must-revalidate, no-cache, private
Date: Fri, 27 Nov 2015 21:39:56 GMT
Set-Cookie: csrftoken=97cc443e4aaf11dbc44b6c1fb9113378; expires=Fri, 25-Nov-2016 21:39:56 GMT; Max-Age=31449600; Path=/
Content-Length: 283
Content-Language: en
Content-Type: application/json; charset=utf-8
Expires: Sat, 01 Jan 2000 00:00:00 GMT
}
}
I'm trying to determine what the difference between the two could be; the only thing that I can think of is that access_token is somehow being invalidated when I switch between pages. The last thing I do on the Login/Auth page is store the access_token using Session.Add, then call Server.Transfer to move to the page that I'm calling this on.
Any Ideas on what the issue could be? Thanks.
Attach the token to the header when making the request.
Client.DefaultRequestHeaders.Add("access_token", "Bearer " + token);
The problem ended up being one regarding Sandbox Mode. I had registered an app after the switch, and I was the only user in my sandbox. As a result, it had no problem finding my posts/info, but Sandbox Mode acts as if the Sandbox users are the only users on Instagram, so naturally it would not find anything else.
It turns out there was an existing registered application in my organization (made before the switch date) that does not have any such limitations, so I have been testing using that AppID/secret.
tl;dr: If you're the only user in your app's sandbox, work on getting users into your sandbox. See their article about it for more info.

Extract cookies info from response headers C#

I have some information that is available in a response header. One way would be to come up with a regex for it...Is there another way to work around this?
This is the header info:
Headers = {Cneonction: close
Content-Length: 87
Content-Type: application/json;charset=utf-8
Date: Mon, 11 Feb 2013 05:51:37 GMT
Expires: Thu, 01-Jan-1970 00:00:00 GMT
Set-Cookie: FUTWebPhishing-123456789=123456aavbc12334564856;Path=/;Domain=.ea.com;Expires=Wed, 1...
I want the value of FUTWebPhishing..Any ideas?
You can string.Split(';') the value of the Set-Cookie header and then find the element that contains "FUTWebPhishing".
There is a discussion on SO regarding this issue
Check it out:
GetCookie extract information to a String

Categories

Resources