|
lly for feature-rich pages that make use of plenty of controls. This extra burden can cause serious overhead for the application as a whole. By default, the view state is enabled for all server controls, but this doesn''''t mean that you need it all the time. View state saves you a lot of coding and, more importantly, makes your job simpler. But if you find you''''re paying too much for this feature, drop view state altogether and reinitialize the state of the server controls at every postback. In this case, disabling view state saves processing time and speeds up the download process. You can disable the view state for an entire page by setting the EnableViewState attribute of the @Page directive to false: <% @Page EnableViewState="false" %>
While this is not usually recommended, you should definitely consider it for read-only pages that either don''''t post back or don''''t need state to be maintained. A better approach entails disabling the view state only for some of the server controls hosted in the page. To disable view state on a per-control basis, set the EnableViewState property of the control to false, as shown here: <asp:datagrid runat="server" EnableViewState="false">
•••
</asp:datagrid>
While developing the page, you can keep the size of the view state under control by enabling tracing on the page. Once you have set the @Page''''s trace attribute to true, look under the ViewState column of the control tree, as shown in Figure 3. The tracer doesn''''t show the total size of the view state for the page, but it gives you a precise idea of what each control does. In Figure 3, the page is made of a relatively simple DataGrid control. As you can see, the cells of the grid take up a large part of the view state. The TableCell control, in particular, saves complete user interface information in the view state, including text, column and row span, and style attributes. Contrary to what many developers think, the DataGrid server control doesn''''t store its data source in the view state. It caches almost all of its public properties, but the amount of space required is in no way related to the data source. However, the DataGrid uses child controls, like the TableCell, which store their text and style in view state, too. The text displayed in the cells is a subset of the DataGrid''''s data source.
 Figure 4 Retrieve ViewState String
In Figure 4, I''''ve reworked the page in Figure 3 to add a client-side button that retrieves the view state string and calculates its length. The JavaScript code for this is pretty simple: <script language="javascript">
function ShowViewStateSize()
{
var buf = document.forms[0]["__VIEWSTATE"].value;
alert("View state is " + buf.length + " bytes");
}
</script>
Programming Without View State As I''''ve discussed here, the view state represents the state of the page and its controls just before the page is rendered in HTML. When the page posts back, the view state is recovered from the hidden field, deserialized, and used to initialize the server controls in the page and the page itself. However, this is only half the story. After loading the view state, the page reads client-side information through the Request object and uses those values to override most of the settings for the server controls. In general, the two operations are neatly separated and take place independently. In particular, though, the second operation—reading from Request.Form—in many situations ends up just overriding the settings read out of the view state. In this particular case the view state is only an extra burden. Let''''s examine a typical case. Suppose you have a page with a textbox server control. You expect that, when the page posts back, the textbox server control is automatically assigned the value set on the client. To meet this rather common requirement, you don''''t need view state. Let''''s consider the page in Figure 5. In this case, the behavior of the page is state-aware even if view state is disabled. The reason is that you are using two server controls—TextBox and CheckBox—whose key properties are updated according to the values set by the user. These values will override any setting that view state may have set. In short, as long as you''''re simply interested in persisting properties such as Text or Checked you don''''t have any need for view state. All control properties declared as attributes in <asp:xxx> tags are automatically restored to their default values during the initialization of the control. As long as these extra properties are not expected to change during the session, you don''''t need view state. So when is view state really necessary? Suppose that your textbox is only editable if the user has certain privileges. You could declare the textbox as read-only to turn the attribute off the first time the page is loaded and after checking the user''''s credentials. The code would look like Figure 6. This programming style is inherently state-aware and works as expected as long as you have view state enabled. Try setting the EnableViewState attribute to false and then load the page again. In the OnInit page event, the textbox is instantiated as declared in the page layout—that is, with a ReadOnly property of true. The first time the page is processed (in this case, IsPostBack returns false), the attribute is programmatically turned on according to the user''''s role. So far, so good. The code in Figure 6 is state-aware because it assumes that after the first access to the page the runtime can remember all settings. This is no longer the case if you turn view state off. In this case, since IsPostBack now returns true, the Page_Load event won''''t have a chance to modify the textbox''''s ReadOnly property. By choosing an alternative programming style you can get the same functionality without the view state, thus saving 40 bytes of HTML for each instance of a TextBox control. Obviously, this sort of savings can add up. The code in Figure 7 shows the few changes needed to make the page work the same, but without view state. In some cases, you can disable view state and have the page still run unchanged. In other cases, some minor changes must be made to the code to make sure that all properties of all controls are correctly initialized. In general, you can do without view state whenever the state can be deduced either from the client or from the runtime environment (if the user has certain privileges, for example). By contrast, doing without view state is difficult whenever state information can''''t be dynamically inferred. For example, if you want to track the sort order of a pageable DataGrid you can cache it only in the view state. In my experience, any combination of default ASP.NET controls can be adapted to work in pages in which the view state has been disabled. The more you use custom controls—both yours and those from third-parties—the more disabling view state can be a problem. Keep this in mind if you''''re going to write custom ASP.NET controls, and don''''t overload the view state bag.
Keeping View State on the Server As I said, the view state is stored on the client in a hidden field. However, this is simply the default storage medium. Let''''s see how to save the view state in a file on the Web server instead. To design an alternative storage scheme for view state, you need the string that ASP.NET stores in the hidden field. You can then save it in a server-side file or a database table and read the view state whenever that page is being processed. Be aware that there are benefits and drawbacks to this alternative. The bad news is that the Base64 view state string is not publicly exposed to the code running in the page. The good news is that the class that the Microsoft® .NET Framework actually uses to serialize and deserialize the view state is configured as a public type (as opposed to an internal type) and as such can be called from user applications. This class, LosFormatter, is not yet fully documented. The LosFormatter class has quite a simple programming interface made of only two publicly callable methods—Serialize and Deserialize. The Serialize method writes the final Base64 representation of the view state to a Stream or a TextWriter object: public void Serialize(Stream stream, object viewState);
public void Serialize(TextWriter output, object viewState);
The Deserialize method builds a StateBag object out of a stream, a TextReader object, or a plain Base64 string, as shown here: public object Deserialize(Stream stream);
public object Deserialize(TextReader input);
public object Deserialize(string input);
The LosFormatter class is the entrypoint in the view state internal mechanism; by using it, everything should happen exactly as in the default case. The LosFormatter class also features a read/write property called EnableViewStateMac whose role is enabling encryption/decryption on the Base64 string. The variable cannot be accessed programmatically because it is marked as internal, meaning that only classes in the same assembly can work with it. However, since I''''m simply plugging my code into the ASP.NET view state pipeline, I can control the machine authentication check using the high-level tools I discussed earlier. Fortunately, the Page class can support alt上一页 [1] [2] [3] 下一页 [系统软件]The GRETA Regular Expression Template Archive [系统软件]OLE with the internet explorer [常用软件]Firefox: What’s the next step? [VB.NET程序]The UDPChat Source(VB.NET) [Delphi程序]The Delphi Object Model (PART III) [Delphi程序]The Delphi Object Model (PART II) [Delphi程序]The Delphi Object Model (PART I) [Delphi程序]Five of the best tools for Delphi [Delphi程序]2004.11.28.Tour of the IDE [Delphi程序]2004.11.30.Using the StarTeam Integration
|