In the previous article "An OutputCache Bug with ASP. NET from 1.0 to 4.0", a browser cache Bug of ASP. NET OutputCache was revealed.
In this article, we will expose another Bug of ASP. NET OutputCache. This Bug was revealed once in May, but it was not thorough enough and the solution was not perfect. I will expose it again here.
Background
To solve the problem of non-telecom users accessing the blog Park's network speed (especially North China Netcom users), we plan to adopt CDN acceleration. To enable CDN acceleration to play a role, we need to establish an effective page cache mechanism (set OutputCache Location to "Any "). To solve this practical application problem, you must study ASP. NET OutputCache to expose its Bug.
Important
If you use OutputCache in ASP. NET Applications (non-ASP. net mvc), you must pay attention to this Bug and fix it first!
Symptom
If you have seen the above figure, you have met or met the Bug. (A casual meeting or reunion may just pass by. It may take a long time. Do not expect an accident, but do not ignore it .)
When we met it at the beginning, it was "suddenly invisible" (in rare cases), and people were "confused" (there was no way to deal with this problem ).
Why does the browser provide this window?
The reason is that the Web server and the browser say a sentence (Response Headers): "Content-Type: text/vnd. wap. wml; charset = UTF-8 ". Why? See the decomposition below.
Problem occurrence process
1) when you add OutputCache settings to an ASP. NET page, for example:
<%@ OutputCache Duration="300" VaryByParam="*"%>
2) then, when the cache is not established (or has expired), a mobile phone sends the first Request to this page in WAP mode through the browser (the Request headers contains "Accept: text/vnd. wap. wml ", such requests may be simulated by Code. For details, see here ).
3) Then ASP. NET caches the request response. This operation is performed in System. web. caching. outputCacheModule. in OnLeave, the cache content comes from System. web. httpResponse. getSnapshot () not only caches the Response body, but also caches the Response headers.
* [Key point] ASP. NET according to "C: \ Windows \ Microsoft. NET \ Framework \ v4.0.30319 \ Config \ Browsers \ Default. the configuration in browser is specially processed:
<defaultBrowser id="Wml" parentID="Default"><identification>
Because the Accept of the request is text/vnd. wap. wml, so the above exactly matches, and then ASP. NET according to the configuration here, change Content-Type in Response headers to "text/vnd. wap. wml; charset = UTF-8 "and cache it.
4) The next request in the cache cycle will be greeted by this cache (the operation is in the System. web. caching. outputCacheModule. onEnter, and finally the System. web. httpResponse. useSnapshot returns the cached content), as long as the request is not in WAP mode, the download file dialog box shown above will appear.
To solve this problem, we tried to capture this response, but we did not catch it through Firebug in FireFox, Developer tools in Chrome, and Fiddler. Then we tried Developer tools in IE9, I caught it (the first time I enjoyed the surprise brought by IE9 ). See:
The cause of the problem is that the correct Content-Type should be "text/html; charset = UTF-8", ASP. NET, but the WAP request is specially treated. The Content-Type is determined by Accept (is it "ass decides head "). This design may be required for WAP application scenarios, but the impact on OutputCache is not considered during the design.
(Note: We tested to change the client request's Accept to another type, such as text/plain)
From the process described above, we can know that to solve the problem, we should start with the Default. browser file mentioned in step 1.
Recommended Solution
Prerequisites: There is no WAP site on the current Web server.
Advantage: one change is effective for all websites on the current Web server.
Procedure:
- Go to C: \ Windows \ Microsoft. NET \ Framework \ v4.0.30319 \ Config \ Browsers
- Copy the Default. browser file to the desktop (copy another file to another folder for backup)
- Open the Default. browser file on the desktop with your favorite edits, find the <defaultBrowser id = "Wml" parentID = "Default"> section, comment out or delete the following configuration and save it:
<capabilities> <capability name="preferredRenderingMime" value="text/vnd.wap.wml"/> <capability name="preferredRenderingType" value="wml11"/></capabilities>
- Copy the modified Default. browser file to "C: \ Windows \ Microsoft. NET \ Framework \ v4.0.30319 \ Config \ Browsers" to overwrite the file with the same name.
- Run the command line as an administrator. Run cd to go to "C: \ Windows \ Microsoft. NET \ Framework \ v4.0.30319 \ Config \ Browsers" and run the command "\ aspnet_regbrowsers-I ":
- You can perform OutputCache as much as possible.
Note: This solution is based on ASP. in NET4, do not trust Request. browser. cookies are used for Form verification. If you do not write a blog at the time, it is not so easy to find this solution.
There are many solutions to this problem. Here we will only list the solutions we will adopt.
What about ASP. net mvc?
This Bug does not exist in ASP. net mvc. The "browser cache Bug" mentioned in the previous article does not exist in ASP. net mvc.
Summary
1) Why are ASP. NET bugs not found in ASP. net mvc?
I think one of the important reasons is ASP. NET, ASP. net mvc open (open-source)-with the source code, developers can find the real cause faster and then report it to Microsoft. Even if Microsoft cannot solve the problem immediately, at least I can modify the source code to solve the problem myself. With this condition, developers are willing to investigate the problem. Otherwise, even if you find the cause of the problem, because you cannot modify the source code, you can only look at the problem (for example, the Entity Framework problem I encountered earlier ). The openness of ASP. net mvc is the key to its success. Whether Entity Framework is successful depends on whether it is open.
2) Will ASP. NET WebForms coexist with ASP. net mvc?
I thought it would coexist in the past, but now Microsoft is too lazy to solve the ASP. NET WebForms Bug. Do you still believe it will coexist?
Author: dudu