Can not disable ViewState - c#

I have made a simple Web Form where I try to get rid of the ViewState. When I run it and press Go the label gets the value of whatever I put in the texbox. So far all good. But the textbox maintains the value I filled in. As far as I understand it this is done by the ViewState mechanism. What do I miss?
<%# Page Language="C#" AutoEventWireup="true" Inherits="SportsPlay.Sida1" ViewStateMode="Disabled" EnableViewState="false" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" enableviewstate="false">
<div>
<asp:TextBox runat="server" ID="txtTest" ></asp:TextBox>
<asp:Button runat="server" ID="btnGo" Text="Go" OnCommand="btnGo_Command" />
<asp:Label runat="server" ID="lblResult"></asp:Label>
</div>
</form>
</body>
</html>
<script runat="server" language="C#">
void btnGo_Command(object sender, CommandEventArgs e)
{
lblResult.Text =txtTest.Text ;
}
</script>

Aside from the previous answer you can explicitly clear it on click TextBox1.Text = ""; Or Redirect to the same page should clear everything out.

The ViewState manages the information of the current page. It is utilized by the HTML pages by ASP.NET applications to maintain the state of the web form controls. By this you can save a lot of coding by maintaining the ViewState of the objects in your Web Form.
You do not need ViewState in the following situations:
The control is repopulated on every postback. If you ignore old data, and if you repopulate the server control each time the page is refreshed then you do not need ViewState.
When you complete a web page, review the controls in the page and consider what information is being passed in the view state and whether you really need all that information to be maintained. To optimize web page size, consider disabling view state in these cases.
The control is an input control and it changes only from user actions.
The control never changes.
By default, ViewState is enabled for all server controls. ViewState can be enabled and disabled in any of the following ways:
Control Level
Page Level
Application Level
Machine Level
To disable ViewState
To disable ViewState for a single control on a page, set the EnableViewState property of the control to false, as in the following:
<asp:DropDownList ID="DropDownList1" runat="server" EnableViewState="false" />
To disable ViewState for a page
To disable ViewState for a single page, set the EnableViewState attribute in the # Page directive to false, as in the following:
<%# Page Language="C#" EnableViewState="false" AutoEventWireup="true" CodeFile="URLRouting.aspx.cs" Inherits="URL_Rewriting" %>
To disable a page's View State, add the code below in the Page class of the page.
public void DisableViewState()
{
this.Init += new EventHandler(Page_Init);
}
private void Page_Init(object sender, System.EventArgs e)
{
this.EnableViewState = false;
}
To disable ViewState for a specific application
To disable ViewState for a specific application, use the following element in the Web.config file of the application:
<configuration>
<system.web>
<pages enableViewState="false" />
</system.web>
</configuration>
To disable ViewState for all applications on a Web server
To disable ViewState for all applications on a Web server, configure the element in the Machine.config file as follows:
<Machine.config >
<system.web>
<pages enableViewState="true" />
</system.web>
</Machine.config>

Related

Page_Load of 2. user control never executes (website)

I am in the process of making a website that displays information in boxes.
There will be different pages with different combinations of boxes. They will have a lot of boxes in common.
Therefor, I am making the boxes as user controls to then put on the different pages. The different pages will also share a master page.
However, when starting development of the 2. box, I ran into a problem:
The Page_Load (or the whole code behind) of the 1. box runs fine, but the Page_Load og the 2. box gets ignored. This results in a lot of null values that makes the aspx file crash.
My CT1.aspx contains this to use the two user controls:
<%# Page Title="CustType1" Language="C#" MasterPageFile="~/MTCustomer/Master.master" AutoEventWireup="true" CodeFile="CT1.aspx.cs" Inherits="MTCustomer.CT1" %>
// Some HTML
<td ID="column1" style="width: 400px;">
<Box:CustomerInfoBoxAx runat="server" />
<Box:CustomerInfoBoxMt runat="server" />
</td>
// Some HTML
My Web.config contains this for the user controls to be usable:
<pages>
<controls>
<add tagPrefix="Box" tagName="InfoBoxA" src="~/Controls/InfoBoxA.ascx" />
<add tagPrefix="Box" tagName="InfoBoxB" src="~/Controls/InfoBoxB.ascx" />
</controls>
</pages>
My user control A looks lige this:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="InfoBoxA.ascx.cs" Inherits="Controls.InfoBoxA" %>
<% if (IsVisible("InfoBoxA") && Customer != null)
{ %>
<div>
<%-- Markup --%>
</div>
<% } %>
And box B looks like this:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="InfoBoxB.ascx.cs" Inherits="Controls.InfoBoxB" %>
<link rel="stylesheet" type="text/css" href="<%=VirtualPathUtility.ToAbsolute("~/Styles/InfoBoxStyle.css")%>">
<% if (IsVisible("InfoBoxB") && Customer != null)
{ %>
<div>
<%-- Markup --%>
</div>
<% } %>
I have tried to swap the order of the two user controls in the page.aspx, this also changed witch one had its Page_Load (or the whole code behind) ignored. Based on that, it looks like only the first code behind is executed, and the rest is ignored.
EDIT:
After following the exceptions that comes after the initial null reference exception, I can see that the Page.DataBind() in the first user control is still executing. This must mean that this is what causes the aspx file of both box one and two run. But how do I get around this?
Problem solved.
I removed Page.DataBind() from all user controls, and in the CT1.aspx.cs (the page code behind) i moved it from Page_Load() to OnLoadComplete().
By doing this, Page_Load() in all files have been executed before the Page.DataBind() is executed.

How to change the form action in C# .NET through code?

I am working on a project in C# .NET that allows me only one form in the .aspx file.
<form id="form1" runat="server" action="#1">
How can I change the form action through the C# code in a method?
I have tried this:
protected void Button1_Click(object sender, EventArgs e)
{
form1.Action = "#2";
}
but it didn't work. Thanks in advance...
Based on the comments to you question. asp:Panel Controls could help you out.
A very rough example
ASPX:
<form id="form1" runat="server">
<asp:Panel id="Form1" runat="server">
<!-- Form 1 Stuff -- >
<asp:Button ID="Button1" runat="server" Text="Submit"
OnClick="Button1_Click" />
</panel>
<asp:Panel id="Form2" runat="server" Visible="false">
<!-- Form 2 Stuff -- >
<asp:Button ID="Button2" runat="server" Text="Submit"
OnClick="Button2_Click" />
</panel>
</form>
C#
protected void Button1_Click(object sender, EventArgs e)
{
//HIde "Form"1
Form1.Visible = false;
//Show "Form"2
Form2.Visible = true;
//Do other stuff
}
protected void Button2_Click(object sender, EventArgs e)
{
//Do Final Processig
}
Also look at the DefaultButton property of the Panel
(Moving this to the top because it's an answer to the newly understood question. It's not how to change the form action, but how to have multiple forms.)
If you want a server form on a page that already has a server form then perhaps that second "form" should be a User Control. That way it sits inside the host page's server form but doesn't require its own form. And it's self-contained, able to contain whatever logic it needs when handling a postback.
Here's an example of a simple User Control. You can create one from Add > New Item > Web > Web Forms User Control.
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="OtherForm.ascx.cs" Inherits="WebApplication1.OtherForm" %>
<label for="<% = OtherFormTextInput.ClientID %>">
This is some other form on the same page
</label>
<asp:TextBox runat="server" ID="OtherFormTextInput"></asp:TextBox>
<asp:Button runat="server" ID="Submit" Text="Submit this other form"/>
It looks like an .aspx page but it has no form. It can still have its own code behind which can interact with with the other server controls it contains, just like an .aspx page would.
Then you add that control to your "main" page:
<%# Page Language="C#" AutoEventWireup="true"
CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!-- Register the user control -->
<%# Register TagPrefix="uc" TagName="other" Src="~/OtherForm.ascx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<!-- This form has its own stuff, but also contains the "other" form. -->
<uc:other runat="server" ID="TheOtherForm"></uc:other>
</form>
</body>
</html>
I recommend this over using panels (which still works) because if you're putting two forms on one page, it's likely that you might at some point want to move the secondary form to another page or re-use it. This approach keeps it completely self-contained. Its code-behind isn't in the same file as the the .aspx page. You can place this on as many pages as you want.
Original "literal" answer which addresses the question as originally understood.
The runat="server" form exists entirely for the purpose of allowing ASP.NET to interact with the page and its server controls during postbacks. It's central to the way webforms works. If you change the action then technically what you have isn't a webforms page any more.
That's fine (I don't even like webforms) but it can lead to some weird behavior. If you have controls that trigger postbacks then normally they'd be handled on the same page and your user would just see a (hopefully) fast refresh. Now they might get sent to another page.
What if you just removed that form entirely and added your own form instead? Then your .aspx page will just behave more like an .html page.
Having added all the disclaimers about why not to do it, you can change the action using JavaScript. Here's a sample:
<%# Page Language="C#" AutoEventWireup="true"
CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" ClientIDMode="Static">
<asp:Button runat="server" text="Causes postback"/>
<asp:CheckBox runat="server" AutoPostBack="True"/>
</form>
<script>
document.getElementById("form1").action = "http://stackoverflow.com";
</script>
</body>
</html>
Some browsers might not allow changing the form's action.
I put the checkbox there just for fun (I must be really bored) to show the odd side effects it could have, that you might click on a checkbox and get redirected to a different page.
You can write a response.write() in your Asp.net side that print some javascript or jQuery code! As #Scott Hannen wrote some javascript like this :
Response.Write("<script>document.getElementById('YOURFORMID').action = 'YOUR URL';</script>");
or with jQuery
Response.Write("<script>$('#YOUR FORM ID').attr('action', 'YOUR URL');</script>");
btw if you have access to .html or .js files u can directly put this jQuery code without any C# code!

Creating form tag programmatically not working

I have a simple web page that contains a Literal, now I want to create a form tag in code behind.
This is an example:
if (IsPostBack)
{
Literal1.Text = "form submit";
}
else
{
Literal1.Text = "<form id='myFrom' runat='server' action='default.aspx'
method='POST'><input type='submit' value='click here'/></form>";
}
This code create the form, but when I click the submit button, it doesn't go through IsPostBack path. Why?
Note that I need it to be created and sent as an string, because I want to use it in ajax for example.
IsPostBack is only enabled when the POST request originates from ASP.NET's __doPostBack() function. See How to use __doPostBack() for how to create an async postback request with JavaScript.
An ASP.NET web form is already an HTML form and encompasses all of your controls. You are nesting a form within a form which is not legal HTML.
I'd suggest you replace your nested form with a simple button. In the click handler for the button, redirect to default.aspx.
As indicated by John Wu, you don't want to implement your code this way. Nested forms -- while browsers forgive them -- are just not the way to go, especially with ASP.Net WebForms. Sure, I was able to get your code to work, BUT if you need to ajaxify your page so that it works with the WebForms postback model, then it would be much better to use the UpdatePanel control (in conjunction with the ScriptManager control).
ASP.Net WebForms is predicated on only having a single Form element used on a page, as it relates to its postback model, so you'll want to work within that constraint.
Here's some code to demonstrate the use of the UpdatePanel to ajaxify a WebForm (and take advantage of PostBack):
...the .ASPX page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="NestedForm_Question.aspx.cs" Inherits="StackOverflowAspNetQuestionAnswers.NestedForm_Question" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Literal ID="Literal1" runat="server" />
<asp:Button ID="SubmitButton" Text="Submit" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
...the associated code-behind class:
public partial class NestedForm_Question : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SubmitButton.Click += SubmitButton_Click;
}
void SubmitButton_Click(object sender, EventArgs e)
{
Literal1.Text = "form submit";
}
}
You can see that in the code-behind class, the code that would need to be written to set the value of the literal control after the Button is clicked is the same whether the page is ajaxified or not.
I've changed my code to this:
if (Context.Request.Form.HasKeys()) // instead of if(IsPostBack)
{
Literal1.Text = "isPostBack";
}
else
{
Literal1.Text = "<form id='myFrom' runat='server' action='default.aspx' method='POST'><input type='submit' name='submitbtn' value='click here'/></form>";
}
Using different examples, I didn't find any exception to this. and it works well.
Any idea about this solution?
Note that in this way at least one of our elements in the form should have the name property.

ASP.NET issue when removing Control on Page Load

I have following Index.aspx web form:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ProblematicWebApplication.Index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<asp:Label ID="dummyLabel" runat="server" Text="This is dummy label." />
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="intDropDownList" runat="server"/>
<br />
<asp:Button Text="Submit" OnClick="OnSubmitClicked" runat="server"/>
<br />
Selected value: <asp:Label ID="selectedValueLabel" runat="server" />
</div>
</form>
</body>
</html>
And following code behind Index.aspx.cs file:
using System;
using System.Linq;
namespace ProblematicWebApplication
{
public partial class Index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.intDropDownList.DataSource = Enumerable.Range(0, 11).ToArray();
this.intDropDownList.DataBind();
}
if (this.Request["remove-dummy"] != null)
this.Controls.Remove(this.dummyLabel);
}
protected void OnSubmitClicked(object sender, EventArgs e)
{
this.selectedValueLabel.Text = this.intDropDownList.SelectedValue;
}
}
}
When I run my application with no remove-dummy parameter in query string and select some value from intDropDownList and click Submit button, selected value is accordingly presented in selectedValueLabel.
But if I run my application with remove-dummy=1 parameter in query string, dummyLabel gets removed. Now when I select some value from intDropDownList and click Submit button, selected value is not correctly written to selectedValueLabel and all items from intDropDownList are removed.
Can someone explain it to me why this is happening?
Why removing unrelated dummyLabel control has influence on intDropDownList control?
Hmm, seems odd. I got it to work by moving your code that removes the control into the Page's PreInit event:
protected void Page_PreInit(object sender, EventArgs e)
{
if (this.Request["remove-dummy"] != null)
{
this.Controls.Remove(this.dummyLabel);
}
}
It seems that ViewState loading fails in postback after dummyLabel is removed in previous page load.
Details:
first study following articles:
TRULY Understanding ViewState - Infinities Loop
ASP.NET Page Life Cycle Overview
Following image shows important ASP.NET page events and where in between ViewState handling takes place.
So what happens when declarative Control dummyLabel is removed? Here is a process:
Page is requested for the first time with query string parameter remove-dummy=1.
In Page_Load event declarative Control dummyLabel is removed.
Before SaveStateComplete event, ViewState is saved. There is no control dummyLabel in control tree, so its ViewState won't be saved.
Submit button is clicked.
Between InitComplete and PreLoad events, ViewState gets loaded. This is where it breaks because control tree now contains dummyLabel (dummyLabel gets removed after, in Load event) and ASP.NET fails in recursively loading ViewState into Page control tree. My assumption is that ViewState and Page control tree are tightly coupled and recursive ViewState loading fails as a consequence of this tight coupling.
One more situation that backs-up this theory: if you place dummyLabel at the very end of the page, issue doesn't happen anymore, because all other controls in Page control tree that come before dummyLabel already picked correct values from ViewState (ViewState structure and Page control tree are tightly coupled). If there were more controls after dummyLabel, their ViewState loading would fail.
To resolve this issue, all declarative Controls (defined in ASPX file) that should be removed, must be removed before ViewState loading takes place - in InitComplete event or any other event before it.

A potentially dangerous Request.Form value was detected from the client

I have this issue. I have tried everything. ValidateRequest="false".. and decoding and encoding html.. etc. etc..
What I need is a popup box (so im using ModalPopupExtender) to present to a user where people can type in xml settings and click ok/cancel button to close the popup and save.
However i keep on getting this error "A potentially dangerous Request.Form value was detected from the client"..
Here is my test code below (quick example of my scenario and error)..
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1"
ValidateRequest="false" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:Panel ID="Popup" runat="server" Width="800px" Style="display: none;">
<asp:LinkButton ID="Display" runat="server" Style="display: none;" OnClick="Display_Click" />
<cc1:ModalPopupExtender ID="ModalPopupExtender" runat="server" TargetControlID="Display"
PopupControlID="Popup" DropShadow="false" Y="10" />
<div id="Item">
<div class="Item">
<table width="100%">
<tr>
<td>
<textarea id="txtAreaValue" cols="35" rows="6" style="resize: none;" runat="server" />
</td>
</tr>
<tr>
<td>
<asp:Button ID="btnOk" Text="Ok" SkinID="default" Width="50px" runat="server" />
<asp:Button ID="btnCancel" Text="Cancel" SkinID="default" Width="50px" OnClick="BtnCancel_Click"
runat="server" />
</td>
</tr>
</table>
</div>
</div>
</asp:Panel>
</div>
</form>
</body>
</html>
Code Behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ModalPopupExtender.Show();
string str = "<?xml version=\"1.0\" encoding=\"utf-8\"?><XmlConfig xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"> <XmlConfig Type=\"TEST\" DefiningXpath=\"/PERSON/NAME\"><Index Name=\"Name\" XPath=\"/PERSON/NAME/VALUE\" Type=\"String\" /><Index Name=\"Id\" XPath=\"/PERSON/NAME/ID\" Type=\"String\" /> </XmlConfig></XmlConfig>";
txtAreaValue.InnerText = str;
}
protected void Display_Click(object sender, EventArgs e)
{
//Shows the Item detail Edit box
ModalPopupExtender.Show();
}
protected void BtnCancel_Click(object sender, EventArgs e)
{
ModalPopupExtender.Hide();
}
}
}
To run the code.. Add ref to AjaxControltoolkit.dll and then run and you will see the textarea being populated with xml. Click on the cancel button and this causes the error. Please can anyone help me?
Use
<httpRuntime requestValidationMode="2.0" />
in your web.config (keeping any attributes you already have on that element, if it's already there). ASP.NET4.0 ignores ValidateRequest otherwise.
And, of course, do make sure that you take necessary measures to protect against genuinely dangerous requests, now that it's not being done for you.
Edit: A great way of doing this is to create your own class derived from RequestValidator, and using the 4.0 behaviour, but with that as the class that does the checking.
Here are possible solution which may help you.
Make server side configuration setting for this.
If you want to allow HTML element as input from selected pages in your project than you set this page attribute.
<%# Page ValidateRequest="false" %>
This ValidateRequest="false" on each page.
If you want in all pages in you project than make changes in Web.Config file.
Add this tag In section.
If you are using .Net 4.0 than you have to make one more change in Web.Config file.
Add this tag In section.
<httpRuntime requestValidationMode="2.0" />
Here are configuration for do not validate request for all pages in .Net 4.0
<configuration>
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
<pages validateRequest="false">
</pages>
</configuration>
Here is full example on this. Click Here...
Well, people are talking about Asp.net 4.0 only... I guess we need to address other versions too. Today, I had the same problem when I replaced my AjaxToolkit editor with TinyMCE and with the postback I found the same issue.
"A potentially dangerous Request.Form value was detected from the client"..
So I used this line inside my webconfig and it worked for me.
<system.web>
<pages validateRequest="false" />
</system.web>
It should work across Asp.net 2.0 to 3.5.
UPDATE: Even works upto .net 4.5
UPDATE: You can also try to validate the request on page level rather whole website. Just wanted to let the readers to choose the best way. Thanks DVD for pointing this out.
I created a table article with columns articleId and article_content. I also used html editor for article_content column. When I tried to save I got the same error. It was resolved by adding [AllowHtml] to the article_content property in the class.
[AllowHtml]
[Required]
public string article_content { get; set; }
Don’t forget to include the namespace using System.Web.Mvc. For more details: http://www.infinetsoft.com/Post/A-potentially-dangerous-Request-Form-value-was-detected-from-the-client/1246
You can use JavaScript to encode the values before sending to the server, if that suits your needs
see this answer
"A potentially dangerous Request.Form value was detected from the client"..
1) set httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters="<,>,\" in web.config file
2) set validateRequest="false" in side pages tag in web.config file
<system.web>
<httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters="<,>,\"/>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" validateRequest="false"/>
<system.web>
I faced this same problem while sending some email templates from aspx page to code behind....
So I tried to solve this by adding
<httpRuntime requestValidationMode="2.0" />
in my web config under enter code here` but that did not helped me unless I putted
ValidateRequest="false"
attrribute in the page directive of the aspx page.
There are 3 options to remove this error.
Set validateRequest="false" in page directives.
Set validateRequest="false" in web.config file.
Set requestValidationMode="2.0" in web.config if you are using DotNet 4.0
Checkout this link for more info.

Categories