Do you disable viewstate by default when developing asp.net webform? - asp.net

we know that view state is easily get abused, but asp.net webform are heavily depending on this feature.
I want to know whether you disable viewstate by default, and ONLY add it wehn it's needed. Or you take the visual studio default, which actually enables viewstate by default.

I tend to take the default of having it on when doing web.forms.
But when writing my own user controls I disable it until I need it, or I find something doesn't work. I also monitor the size of the view state and when/if it gets too big I look at what the page is doing and change what I'm doing on the page. I.e. bind to data objects containing only the data that is needed and no more... stuff like that.

As others have said, unless we are talking about a fairly static page, I tend to leave the ViewState on while developing, and begin selectively disabling it when the page works. That way, it's one less thing to worry about upfront.
You may find this interesting, in ASP.NET 4.0, we will have more efficient control over disabling the ViewState: http://www.asp.net/learn/whitepapers/aspnet40/#_Toc223325478

Personnaly, no. Eventually, to have it disabled will be the behaviour that you will want but most of the time, no. Also, I would do a manual ViewState optimization pass and disabled controls' ViewState that wouldn't need it if really necessary. It's better not to have the ViewState to worry about while you are in heavy development imo. I'm not saying here that you shouldn't care about the ViewState at all but to put EnableViewState aside until you feel the need to lighten the trips to the server.

Turn off the ViewState by default by using a <page> element in the web.config. Using EnableViewState="true" in the #Page directive will no longer work once you disable the ViewState in the web.config. If you decide later that you need the ViewState for a specific page, you can turn it back on for just that page using a <location> element.
<configuration>
<system.web>
<pages enableViewState="false" />
</system.web>
<location path="MyFolder/MyPage.aspx">
<system.web>
<pages enableViewState="true" />
</system.web>
</location>
<location path="Site.master">
<system.web>
<pages enableViewState="true" />
</system.web>
</location>
</configuration>
You need to do the same for any master pages that your ViewState enabled page uses.

I go one step further, I've created a class that inherits from the Page class and override 2 functions
protected override void SavePageStateToPersistenceMedium(object viewState)
{
}
protected override object LoadPageStateFromPersistenceMedium()
{
return null;
}
Then have my page that requires the viewstate to be disabled inherit from this.
Works very well.

Related

ASP.NET Page naming using master pages

I have two user types: Readers and Authors. And I'm using Reader.Master and Author.Master for authorization purposes.
Then, there are StoriesR.aspx inherited from Reader.Master and StoriesA.aspx inherited from Author.Master. (In StoriesR.aspx page, you able to read the stories and in StoriesA.aspx you able to write the story.) So,
Reader.Master --> StoriesR.aspx
Author.Master --> StoriesA.aspx
Now, the thing is I don't want my users to see StoriesR.aspx?s=3 or StoriesA.aspx?s=3 in their browsers. I only want them to see stories?s=3. (even without the .aspx part)
How can I achieve this?
you can do this using urlMappings from web.config file
add in web.confing
<system.web>
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<urlMappings enabled="true">
<add url="~/reader/stories" mappedUrl="~/reader/StoriesR.aspx"/>
<add url="~/author/stories" mappedUrl="~/author/StoriesA.aspx"/>
This will do url mapping.
You could have one aspx page and change the master page programmatically depending on what type of user they are, Author or Reader.
You can do this in the Page_PreInit event of your aspx page.
Check this c# example or this VB example

How to disable ViewState for a .aspx page?

I need to completely disable ViewState for a .aspx page inside my web application. I have gone through different blogs and what I understand is that we must set <%# Page EnableViewState="false" ...%>, but this is not working.
Is this enough to disable ViewState for all the controls inside the page? Or should I make any additional modifications? If so, please specify them. I don't want the ViewState enabled for even a single control inside the .aspx page
Disabling View State
Machine Level -
Disabling view state at machine level in machine.config, will disable ViewState of all the applications on the web server.
<Machine.config>
<system.web>
<pages enableViewState="false" />
</system.web>
</Machine.config>
Application Level -
You can disable ViewState for all pages in /web.config file.
<configuration>
<system.web>
<pages enableViewState="false" />
</system.web>
</configuration>
Page Level -
Disabling view state for a specific aspx file at the top.
<%# Page Language="C#" .. EnableViewState="false" .. %>
Control Level - You can disable ViewState for a specific control.
<asp:TextBox EnableViewState="false" ID="Name"
runat="server"></asp:TextBox>
I think the quotes should be:
EnableViewState="false"
Apart from that, if you are still seeing the hidden fields then they are used by ASP.Net. You may see:
Page.EnableViewState Property
Even if EnableViewState is false, the page might contain a hidden view
state field that is used by ASP.NET to detect a postback.
If you truly don't need postback, you can remove the form element from your page, this will remove the viewstate entirely.

Change UserControl template at runtime

Is it possible to change the ascx file used by a usercontrol at runtime?
For example in my page i have
<ctl:SampleControl runat="server" />
in the web.config I have
<controls>
<add tagPrefix="ctl" tagName="SampleControl" src="~/UserControls/SampleControl.ascx" />
</controls>
At runtime I would like to be able to change the ascx to another path, it would still be inheriting from the same usercontrol codebehind, it would just be a different template.
Probably the best thing to do here is to not encode the filename of the "default" .ascx file in your web.config. It will make your life harder. Always do that determination at runtime, like this for instance:
In your .aspx file:
<asp:PlaceHolder runat="server" ID="samplePH" />
In the code-behind:
string file = "~/UserControls/SampleControl.ascx";
if (condition)
file = "~/UserControls/OtherControl.ascx";
UserControl uc = (UserControl)LoadControl(file); // from System.Web.UI.TemplateControl.
samplePH.Controls.Clear();
samplePH.Controls.Add(uc);
But, be aware that in order for post-backs to work correctly, you need to instantiate the same control that was loaded on the last request, early in the page lifecycle -- typically the Init stage. This will ensure that viewstate is correctly parsed. Then, further down in your event handler, PreRender, etc. lifecycle steps, you can use the above code to load the UserControl for the current request.
If you really do need to encode a default page setting in a configuration file (for cases where end-users may want to change it), consider doing it in an app.config rather than buried away in a <controls> section of a web.config.
Documentation for the TemplateControl.LoadControl(string) method:
http://msdn.microsoft.com/en-us/library/system.web.ui.templatecontrol.loadcontrol.aspx

HTML in an ASP.NET Dynamic Data MultilineText Control

I'm trying to enter a little bit of HTML into an ASP.NET Dynamic Data MultilineText_Edit control, just a couple of <br> tags to have line breaks when I output the value of the column on a web page.
However, when I try to click the "Update" link on the Dynamic Data edit page, nothing happens. I don't even get an error message, which I would expect if HTML input were not allowed via some rule the control has built in. As soon as I remove the tag, the update link works correctly. It's not a column size issue, I can add a bunch more characters to the input and everything works fine.
Is HTML input not allowed in these controls, or is there something else going on? If there is some kind of validation rule, can it be turned off? Or is there something in the database that I need to set? Should I use something other than the default multiline text template?
Input validation is a built in feature in ASP.NET 2.0 or later. I don't know why you are not getting an error, but check this out to see if it helps:
http://www.asp.net/learn/whitepapers/request-validation/
Check these settings, on the page:
<%# Page validateRequest="false" %>
or the web.config:
<configuration>
<system.web>
<pages validateRequest="false" />
</system.web>
</configuration>

Hidden Features of ASP.NET [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
This question exists because it has
historical significance, but it is not
considered a good, on-topic question
for this site, so please do not use it
as evidence that you can ask similar
questions here.
More info: https://stackoverflow.com/faq
There are always features that would be useful in fringe scenarios, but for that very reason most people don't know them. I am asking for features that are not typically taught by the text books.
What are the ones that you know?
While testing, you can have emails sent to a folder on your computer instead of an SMTP server. Put this in your web.config:
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="c:\Temp\" />
</smtp>
</mailSettings>
</system.net>
If you place a file named app_offline.htm
in the root of a web application directory, ASP.NET 2.0+ will shut-down the application and stop normal processing any new incoming requests for that application, showing only the contents of the app_offline.htm file for all new requests.
This is the quickest and easiest way to display your "Site Temporarily Unavailable" notice while re-deploying (or rolling back) changes to a Production server.
Also, as pointed out by marxidad, make sure you have at least 512 bytes of content within the file so IE6 will render it correctly.
throw new HttpException(404, "Article not found");
This will be caught by ASP.NET which will return the customErrors page. Learned about this one in a recent .NET Tip of the Day Post
Here's the best one. Add this to your web.config for MUCH faster compilation. This is post 3.5SP1 via this QFE.
<compilation optimizeCompilations="true">
Quick summary: we are introducing a
new optimizeCompilations switch in
ASP.NET that can greatly improve the
compilation speed in some scenarios.
There are some catches, so read on for
more details. This switch is
currently available as a QFE for
3.5SP1, and will be part of VS 2010.
The ASP.NET compilation system takes a
very conservative approach which
causes it to wipe out any previous
work that it has done any time a ‘top
level’ file changes. ‘Top level’ files
include anything in bin and App_Code,
as well as global.asax. While this
works fine for small apps, it becomes
nearly unusable for very large apps.
E.g. a customer was running into a
case where it was taking 10 minutes to
refresh a page after making any change
to a ‘bin’ assembly.
To ease the pain, we added an
‘optimized’ compilation mode which
takes a much less conservative
approach to recompilation.
Via here:
HttpContext.Current will always give you access to the current context's Request/Response/etc., even when you don't have access to the Page's properties (e.g., from a loosely-coupled helper class).
You can continue executing code on the same page after redirecting the user to another one by calling Response.Redirect(url, false )
You don't need .ASPX files if all you want is a compiled Page (or any IHttpHandler). Just set the path and HTTP methods to point to the class in the <httpHandlers> element in the web.config file.
A Page object can be retrieved from an .ASPX file programmatically by calling PageParser.GetCompiledPageInstance(virtualPath,aspxFileName,Context)
Retail mode at the machine.config level:
<configuration>
<system.web>
<deployment retail="true"/>
</system.web>
</configuration>
Overrides the web.config settings to enforce debug to false, turns custom errors on and disables tracing. No more forgetting to change attributes before publishing - just leave them all configured for development or test environments and update the production retail setting.
Enabling intellisense for MasterPages in the content pages
I am sure this is a very little known hack
Most of the time you have to use the findcontrol method and cast the controls in master page from the content pages when you want to use them, the MasterType directive will enable intellisense in visual studio once you to this
just add one more directive to the page
<%# MasterType VirtualPath="~/Masters/MyMainMasterPage.master" %>
If you do not want to use the Virtual Path and use the class name instead then
<%# MasterType TypeName="MyMainMasterPage" %>
Get the full article here
HttpContext.Items as a request-level caching tool
Two things stand out in my head:
1) You can turn Trace on and off from the code:
#ifdef DEBUG
if (Context.Request.QueryString["DoTrace"] == "true")
{
Trace.IsEnabled = true;
Trace.Write("Application:TraceStarted");
}
#endif
2) You can build multiple .aspx pages using only one shared "code-behind" file.
Build one class .cs file :
public class Class1:System.Web.UI.Page
{
public TextBox tbLogin;
protected void Page_Load(object sender, EventArgs e)
{
if (tbLogin!=null)
tbLogin.Text = "Hello World";
}
}
and then you can have any number of .aspx pages (after you delete .designer.cs and .cs code-behind that VS has generated) :
<%# Page Language="C#" AutoEventWireup="true" Inherits="Namespace.Class1" %>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="tbLogin" runat="server"></asp: TextBox >
</div>
</form>
You can have controls in the ASPX that do not appear in Class1, and vice-versa, but you need to remeber to check your controls for nulls.
You can use:
Request.Params[Control.UniqueId]
To get the value of a control BEFORE viewstate is initialized (Control.Text etc will be empty at this point).
This is useful for code in Init.
WebMethods.
You can using ASP.NET AJAX callbacks to web methods placed in ASPX pages. You can decorate a static method with the [WebMethod()] and [ScriptMethod()] attributes. For example:
[System.Web.Services.WebMethod()]
[System.Web.Script.Services.ScriptMethod()]
public static List<string> GetFruitBeginingWith(string letter)
{
List<string> products = new List<string>()
{
"Apple", "Banana", "Blackberry", "Blueberries", "Orange", "Mango", "Melon", "Peach"
};
return products.Where(p => p.StartsWith(letter)).ToList();
}
Now, in your ASPX page you can do this:
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
<input type="button" value="Get Fruit" onclick="GetFruit('B')" />
</div>
</form>
And call your server side method via JavaScript using:
<script type="text/javascript">
function GetFruit(l)
{
PageMethods.GetFruitBeginingWith(l, OnGetFruitComplete);
}
function OnGetFruitComplete(result)
{
alert("You got fruit: " + result);
}
</script>
Check to see if the client is still connected, before starting a long-running task:
if (this.Response.IsClientConnected)
{
// long-running task
}
One little known and rarely used feature of ASP.NET is:
Tag Mapping
It's rarely used because there's only a specific situation where you'd need it, but when you need it, it's so handy.
Some articles about this little know feature:
Tag Mapping in ASP.NET
Using Tag Mapping in ASP.NET 2.0
and from that last article:
Tag mapping allows you to swap
compatible controls at compile time on
every page in your web application. A
useful example is if you have a stock
ASP.NET control, such as a
DropDownList, and you want to replace
it with a customized control that is
derived from DropDownList. This could
be a control that has been customized
to provide more optimized caching of
lookup data. Instead of editing every
web form and replacing the built in
DropDownLists with your custom
version, you can have ASP.NET in
effect do it for you by modifying
web.config:
<pages>
<tagMapping>
<clear />
<add tagType="System.Web.UI.WebControls.DropDownList"
mappedTagType="SmartDropDown"/>
</tagMapping>
</pages>
HttpModules. The architecture is crazy elegant. Maybe not a hidden feature, but cool none the less.
You can use ASP.NET Comments within an .aspx page to comment out full parts of a page including server controls. And the contents that is commented out will never be sent to the client.
<%--
<div>
<asp:Button runat="server" id="btnOne"/>
</div>
--%>
The Code Expression Builder
Sample markup:
Text = '<%$ Code: GetText() %>'
Text = '<%$ Code: MyStaticClass.MyStaticProperty %>'
Text = '<%$ Code: DateTime.Now.ToShortDateString() %>'
MaxLenth = '<%$ Code: 30 + 40 %>'
The real beauty of the code expression builder is that you can use databinding like expressions in non-databinding situations. You can also create other Expression Builders that perform other functions.
web.config:
<system.web>
<compilation debug="true">
<expressionBuilders>
<add expressionPrefix="Code" type="CodeExpressionBuilder" />
The cs class that makes it all happen:
[ExpressionPrefix("Code")]
public class CodeExpressionBuilder : ExpressionBuilder
{
public override CodeExpression GetCodeExpression(
BoundPropertyEntry entry,
object parsedData,
ExpressionBuilderContext context)
{
return new CodeSnippetExpression(entry.Expression);
}
}
Usage of the ASHX file type:
If you want to just output some basic html or xml without going through the page event handlers then you can implement the HttpModule in a simple fashion
Name the page as SomeHandlerPage.ashx and just put the below code (just one line) in it
<%# webhandler language="C#" class="MyNamespace.MyHandler" %>
Then the code file
using System;
using System.IO;
using System.Web;
namespace MyNamespace
{
public class MyHandler: IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "text/xml";
string myString = SomeLibrary.SomeClass.SomeMethod();
context.Response.Write(myString);
}
public bool IsReusable
{
get { return true; }
}
}
}
Setting Server Control Properties Based on Target Browser and more.
<asp:Label runat="server" ID="labelText"
ie:Text="This is IE text"
mozilla:Text="This is Firefox text"
Text="This is general text"
/>
That one kinda took me by surprise.
System.Web.VirtualPathUtility
I worked on a asp.net application which went through a security audit by a leading security company and I learned this easy trick to preventing a lesser known but important security vulnerability.
The below explanation is from:
http://www.guidanceshare.com/wiki/ASP.NET_2.0_Security_Guidelines_-_Parameter_Manipulation#Consider_Using_Page.ViewStateUserKey_to_Counter_One-Click_Attacks
Consider using Page.ViewStateUserKey to counter one-click attacks. If you authenticate your callers and use ViewState, set the Page.ViewStateUserKey property in the Page_Init event handler to prevent one-click attacks.
void Page_Init (object sender, EventArgs e) {
ViewStateUserKey = Session.SessionID;
}
Set the property to a value you know is unique to each user, such as a session ID, user name, or user identifier.
A one-click attack occurs when an attacker creates a Web page (.htm or .aspx) that contains a hidden form field named __VIEWSTATE that is already filled with ViewState data. The ViewState can be generated from a page that the attacker had previously created, such as a shopping cart page with 100 items. The attacker lures an unsuspecting user into browsing to the page, and then the attacker causes the page to be sent to the server where the ViewState is valid. The server has no way of knowing that the ViewState originated from the attacker. ViewState validation and HMACs do not counter this attack because the ViewState is valid and the page is executed under the security context of the user.
By setting the ViewStateUserKey property, when the attacker browses to a page to create the ViewState, the property is initialized to his or her name. When the legitimate user submits the page to the server, it is initialized with the attacker's name. As a result, the ViewState HMAC check fails and an exception is generated.
HttpContext.Current.IsDebuggingEnabled
This is great for determining which scripts to output (min or full versions) or anything else you might want in dev, but not live.
Included in ASP.NET 3.5 SP1:
customErrors now supports "redirectMode" attribute with a value of "ResponseRewrite". Shows error page without changing URL.
The form tag now recognizes the action attribute. Great for when you're using URL rewriting
DefaultButton property in Panels.
It sets default button for a particular panel.
ScottGu has a bunch of tricks at http://weblogs.asp.net/scottgu/archive/2006/04/03/441787.aspx
Using configSource to split configuration files.
You can use the configSource attribute in a web.config file to push configuration elements to other .config files, for example,
instead of:
<appSettings>
<add key="webServiceURL" value="https://some/ws.url" />
<!-- some more keys -->
</appSettings>
...you can have the entire appSettings section stored in another configuration file. Here's the new web.config :
<appSettings configSource="myAppSettings.config" />
The myAppSettings.config file :
<appSettings>
<add key="webServiceURL" value="https://some/ws.url" />
<!-- some more keys -->
</appSettings>
This is quite useful for scenarios where you deploy an application to a customer and you don't want them interfering with the web.config file itself and just want them to be able to change just a few settings.
ref: http://weblogs.asp.net/fmarguerie/archive/2007/04/26/using-configsource-to-split-configuration-files.aspx
MaintainScrollPositionOnPostback attribute in Page directive. It is used to maintain scroll position of aspx page across postbacks.
HttpContext.IsCustomErrorEnabled is a cool feature.I've found it useful more than once. Here is a short post about it.
By default, any content between tags for a custom control is added as a child control. This can be intercepted in an AddParsedSubObject() override for filtering or additional parsing (e.g., of text content in LiteralControls):
protected override void AddParsedSubObject(object obj)
{ var literal = obj as LiteralControl;
if (literal != null) Controls.Add(parseControl(literal.Text));
else base.AddParsedSubObject(obj);
}
...
<uc:MyControl runat='server'>
...this text is parsed as a LiteralControl...
</uc:MyControl>
If you have ASP.NET generating an RSS feed, it will sometimes put an extra line at the top of the page. This won't validate with common RSS validators. You can work around it by putting the page directive <#Page> at the bottom of the page.
Before ASP.NET v3.5 added routes you could create your own friendly URLs simply by writing an HTTPModule to and rewrite the request early in the page pipeline (like the BeginRequest event).
Urls like http://servername/page/Param1/SomeParams1/Param2/SomeParams2 would get mapped to another page like below (often using regular expressions).
HttpContext.RewritePath("PageHandler.aspx?Param1=SomeParms1&Param2=SomeParams2");
DotNetNuke has a really good HttpModule that does this for their friendly urls. Is still useful for machines where you can't deploy .NET v3.5.

Resources