Laden...

Cache auf 3 Min setzen auf HttpWebRequest

Erstellt von w1z4rd2003 vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.640 Views
w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 13 Jahren
Cache auf 3 Min setzen auf HttpWebRequest

Hallo zusammen,

Ich muss ein Cache an einem HttpWebRequest setzen. Das ganze läuft noch unter .NET 1.1

Im moment ist kein Cache angegeben


req.Headers.Add("Cache-Control", "no-cache");

Wie kann ich diesen Cache auf 3 Minuten setzen?

Gruss
w1z4rd

183 Beiträge seit 2004
vor 13 Jahren

Hallo w1z4rd2003,
probier mal

req.Headers.Add("Cache-Control", String.Format("max-age={0}", TimeSpan.FromMinutes(3).TotalSeconds));

alternativ

req.Headers.Add("Cache-Control", "max-age=180");

siehe dazu auch www.w3.org

Grüße

So einfach wie möglich, aber nicht einfacher. [Albert Einstein]

take a look at
* baer-torsten.de
* codinghints

w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 13 Jahren

Hallo él toro,

Vielen Dank für dein Beitrag. Ich werde es mal so versuchen.

Gruss
w1z4rd

w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 13 Jahren

Hallo,

ich hab das gerade ausprobiert aber irgendwie scheint es nicht zu funktionieren.

das ist mein Code


				req = (HttpWebRequest) WebRequest.Create(weburl);
				req.KeepAlive = false;
				req.AllowWriteStreamBuffering = false;
				
				req.Headers.Add("Cache-Control", "max-age=180");
				
				req.Headers.Add("Cache-Control", "s-maxage=180");
				req.Headers.Add("Pragma", "max-age=180");
				//req.Headers.Add("Cache-Control", "max-age=0");
				req.Credentials = System.Net.CredentialCache.DefaultCredentials;
				res = (HttpWebResponse) req.GetResponse(); 

Wie kann ich ansonsten das ganze lokal bei mir Cachen lassen?

Gruss und danke für die Hilfe

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

es gibt ein HttpWebRequest.CachePolicy-Property. Versuch es doch mal damit!

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

B
95 Beiträge seit 2007
vor 13 Jahren

Edit: Hab da was falsch verstanden 😉

w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 13 Jahren

Hallo MarsStein,

Leider muss ich das in eine alte Applikation einbauen die noch unter .Net 1.1 läuft. Diese WebRequest.CachePolicy Eigenschaft wird nur in: 4, 3.5, 3.0, 2.0 supported.

An für sich muss ich nur diesen Header Cachen für ca. 3 minute. Oder ich könnte es auch lokal cachen sodass dsa ganze nicht neu geladen wird bis dieser Cache vorhanden ist.

Langsam weiss ich nicht mehr weiter. Ich dachte es würde funktionieren wenn ich am Header den Cache-Control mit dem Value max-age=180 und s-magage=180 übergebe. Aber anscheinend läuft dass so nicht.

Gruss
w1z4rd

B
95 Beiträge seit 2007
vor 13 Jahren

Ich verstehe noch nicht so ganz, was du genau erreichen willst. Einen Cache "setzen" tust du mit diesem Header ja nicht. Was meinst du denn mit "ich muss nur diesen Header Cachen"? Was willst du genau mit der Caching-Operation erreichen?

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

kannst Du mal den gesamten Request-Header, so wie er aus Deiner Anwendung abgesetzt wird, mitsniffen und hier posten?
Den Response-Header am besten gleich dazu...

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 13 Jahren

Hallo barzefutz,

Also ich hab eine Seite, auf dieser Seite hab ich ein Header zu oberst. Diesen Header ist aber nicht fix auf meiner Page drauf sondern wird durch eine URL geladen, der link führt zu einer Html Seite wo ich die ganze Struktur für die Navigation usw. habe.

Mein Problem ist jetzt folgender. In der Render Methode lade ich meine Navigation und hänge ein Cache auf 3 Minute, nur aber für mein Header.

Da diese Seite von vielen Leuten benutzt wird möchte ich nicht dass es Performance Probleme gibt wenn ich mal etwas in meiner Navigation ändere.
So kann ich sicherstellen dass die Navigation für 3 Minuten gecached wird und der Benutzer die änderungen erst in einem späteren Refresh sieht.

Das ist meine Render Methode vielleicht hilft dir das ein wenig weiter


		/// <summary> 
		/// Render this control to the output parameter specified.
		/// </summary>
		/// <param name="output"> The HTML writer to write out to </param>
		protected override void Render(HtmlTextWriter output)
		{
			string lang;
			int lagId = toolUsers.CurrentLanguageID;
			lang = toolLanguages.Convert(lagId);
//			
//			BuilTable(lang);

			// Header von Meiner Navigation laden

			string weburl = System.Configuration.ConfigurationSettings.AppSettings[toolConstants.CONFIG_HTTP_HEADER]; // hier ist die Url wo ich meine Navigationsseite habe

			NavigationTools navTools = new NavigationTools();
			string pageLanguages = "";

			if(!(navTools.StringProperty(navTools.MainMandantChannel,"lang-de").ToLower() == "false"))
			{
				pageLanguages += "de,";
			}
			if(!(navTools.StringProperty(navTools.MainMandantChannel,"lang-fr").ToLower() == "false"))
			{
				pageLanguages += "fr,";
			}
			if(!(navTools.StringProperty(navTools.MainMandantChannel,"lang-it").ToLower() == "false"))
			{
				pageLanguages += "it,";
			}
			if(!(navTools.StringProperty(navTools.MainMandantChannel,"lang-en").ToLower() == "false"))
			{
				pageLanguages += "en,";
			}

			if(pageLanguages.EndsWith(","))
			{
				pageLanguages = pageLanguages.Substring(0, pageLanguages.Length - 1);
			}

			string activeTab = "ghq";

			Microsoft.ContentManagement.Publishing.Channel appChannel = toolChannels.GetAppChannel();
			if(toolChannels.CustomPropertyValue(appChannel, ACTIVE_CHANNEL_PROPERTY_NAME) != string.Empty)
			{
				activeTab = toolChannels.CustomPropertyValue(appChannel, ACTIVE_CHANNEL_PROPERTY_NAME);
			}

			weburl = string.Format(weburl, activeTab, lang, pageLanguages);
			
			HttpWebRequest req = null;
			HttpWebResponse res = null;;
			StreamReader sr = null;

			try
			{
			
				req = (HttpWebRequest) WebRequest.Create(weburl);
				req.KeepAlive = false;
				req.AllowWriteStreamBuffering = false;
				
				//req.Headers.Add("Cache-Control", "no-cache");
				req.Headers.Add("Cache-Control", "max-age=180");
				
				req.Headers.Add("Cache-Control", "s-maxage=180");

				//req.Headers.Add("Pragma", "no-cache");
				//req.Headers.Add("Cache-Control", "max-age=0");
				req.Credentials = System.Net.CredentialCache.DefaultCredentials;

				res = (HttpWebResponse) req.GetResponse(); 
				
				sr = new StreamReader(res.GetResponseStream(), Encoding.GetEncoding("iso-8859-1"));
				output.Write(sr.ReadToEnd());
			}
			catch(Exception ex)
			{
				output.Write(ex.Message);
				//throw new InvalidOperationException("ImageWorlds definitions can't be loaded: " + ex.Message, ex);
			}
			finally
			{
				if (res != null) {res.Close();}
				if (sr != null) {sr.Close();}
			}

			// ENDE Meine Header Navigation laden

			output.Write("<!--stopindex-->");
			base.Render(output);
			output.Write("<!--startindex-->");

		}

B
95 Beiträge seit 2007
vor 13 Jahren

Also ich würde es so machen:

  • Lass den Server die Navigationsseite schicken, Zusammen mit einem Expires-Header, der 3 Minuten in der Zukunft liegt, und einem Last-Modified-Header, der angibt, wann die Navigationsseite das letzte Mal geändert wurde
  • Innerhalb dieser 3 Minuten holt der Client die Navigationsseite immer aus dem Cache
  • Nach den 3 Minuten fragt er erneut den Server und schickt dabei den If-Modified-Since header mit, wenn dieser ungleich dem letzten Änderungsdatum auf dem Server ist, schickst du die aktualisierte Seite, wenn er gleich ist, schickst du einen Not Modified-Header.

So würde ich es machen, wenn der Client ein richtiger Webbrowser wäre. Das Problem an der Sache wird nur sein, dass du ja das WebRequest-Objekt als Client benutzt. Leider habe ich da gar keine Erfahrung mit, wie man damit das Clientseitige Caching umsetzen kann, also den zweiten Schritt ... hm

Du könntest den Cache ja außerhalb des WebRequest-Objektes simulieren, beispielsweise mit der HttpContext.Current.Cache-Collection, und dort deine Seite für 3 Minuten zwischenspeichern. Ich weiss natürlich nicht, ob das in Asp.NET 1.1 verfügbar ist. Ansonsten vielleicht im Application State?!

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

ich verstehe jetzt das eigentliche Problem nicht...
Wenn Du im Request eine Zeitmarke für den Cache setzt, bedeutet das ja nur soviel wie "Schick mir keine Daten die älter als 3 Minuten sind", nicht aber "schick mir frühestens in 3 Minuten neue Daten".
Wenn Du letzteres erreichen willst, solltest Du die Antwort selbst cachen und einfach 3 Minuten lang keinen Request stellen.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

w1z4rd2003 Themenstarter:in
624 Beiträge seit 2006
vor 13 Jahren

Hallo zusammen.

Vielen Dank für Eure Antworten, langsam komme ich der Sache nächer.
Könnt ihr mir vielleicht ein Beispiel Code posten wie das ungefähr gemacht werden soll?

Das wäre sehr nett!!!

Vielen Dank für Eure Hilfe

B
95 Beiträge seit 2007
vor 13 Jahren

Ich würde eine Proxy-Klasse erstellen, die das Cachen transparent macht und abstrahiert, die könnte z.b. NavigationPageProxy heissen und eine einzige Methode enthalten, GetPage. Die Klasse hat als Cache ein statisches Feld, welches den Inhalt der Navigationsseite enthält. Wenn der Cache null ist, holst du die Seite ab, speicherst sie im Cache und gibst sie zurück. Wenn nicht, überprüfst du, ob 3 Minuten verstrichen sind. Wenn nicht, gibst du die gecachte Seite zurück, wenn ja, holst du wie am Anfang die Seite neu vom Server.