viewstate is not loading/missing for default.aspx - asp.net

My default page isn't including the viewstate when doing the postback, i.e. the viewstate is missing, it's not being included in either the forms or params collections when I look at them during debugging. This also causes the IsPostBack property to show as False and the events associated with the postback to not be called.
My first thought was that somewhere viewstate was being turned off, but I have set it explicitly on the page and all of the controls (the page is extremely small, just 1 button and one list links). Still no luck. The funny thing is, this is only happening on the initial load of the page, if I follow one of the links out and then back to the default page, the viewstate is present.
Why would the viewstate not be created or generated? I'm not getting any validation errors. The first symptom I noticed was server events not being fired, but that made sense one I saw that the viewstate wasn't present, I just don't know why it is missing. I do have a form on the page, and the controls are within that form (and they all work when I come back to the page from elsewhere, just not on the initial landing).
Update: someone wanted some code, this is a minimum
<%# Page Language="vb" AutoEventWireup="false" Inherits="Mysite._default" Codebehind="default.aspx.vb" %>
<!DOCTYPE HTML>
<html>
<head>
<title>Title</title>
<link href="Includes/Style.css" type="text/css" rel="stylesheet">
</head>
<body>
<form id="Form1" method="post" runat="server">
<asp:Button CssClass="Button" Id="cmdDone" Text="Done" runat="server" />
</form>
</body>
</html>
Partial Class _default
Inherits Page
Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack andalso request.HttpMethod = "Post" andalso ViewState("test") is nothing Then
Throw new Exception("No, viewstate")
End If
ViewState("test") = true
End Sub
End Class

The problem is that when asp.net renders <form id="Form1" method="post" runat="server"> the resulting html is <form id="Form1" method="post" action="./"> and NOT <form id="Form1" method="post" action="./Default.aspx">.
This results in the post going to the index and not to the page itself, and getting filtered out sometime before the page is loaded.
The solution is simple, fill out the action so that it goes directly to the page, action="Default.aspx".

Related

First link to internal page works. Subsequent attempt causes Http 404 Error in ASP.net 2.0

I am using ASP.net 2.0 in VS 2008 with Framework 3.5, VB.net codebehind
I plan to build a website that would have a stationary menu on the left made with a TreeView in a fixed position div. A second div on the right would be for content. I have made a small test app to see if the concept works using Master / Content pages.
I want the menu to be hard coded in a single place. The Master page works well for that. The idea is to not have to edit the menu in separate pages as the site grows.
The test app has one Master page and one Contents page. That is how I would like to set up the actual website. The Contents page is the start up page. The Master page has the menu items. Each menu item links to Contents.aspx, but with a unique querystring or /keywords appended. The Contents page codebehind Load event reads the Request.Url.AbsoluteUri. Then, based on the appended querystring or /keywords, pulls the content data and pushes it to an empty Literal control on the Contents.aspx page. In this test app I just push plain text for simplicity.
This works well until I re-click a link. That causes an Http 404 error. I have tried using Response.TrySkipIisCustomErrors = True at the top of the Master and Content Load events and that did not help. I can click one menu link several times and the page will keep reloading. But going back and forth between the links causes the error.
When the error occurs it happens before the Contents.aspx Load event starts.
I would like to be able to fix this in a way that will work on an asp.net host site.
MasterPage.master:
<%# Master Language="VB" CodeFile="MasterPage.master.vb"
Inherits="MasterPage" %>
<!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>Untitled Page</title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div style="position:fixed; top:0px; left:0px; width:300px; height:100%;
background-color:#ddd; padding-top:10px; padding-left:10px" >
Home<br />
<a href="Contents.aspx?p=ABCD" >ABCD page</a><br />
<a href="Contents.aspx/?p=WXYZ" >WXYZ page</a><br />
</div>
<div style="position:absolute; top:0px; left:310px; width:40%;
height:100%; background-color:#eee; padding-top:10px; padding-left:10px" >
<asp:ContentPlaceHolder id="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
Contents.aspx
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Contents.aspx.vb"
Inherits="Contents" MasterPageFile ="~/MasterPage.master" title="Contents"%>
<asp:Content ID="Contents" ContentPlaceHolderID="MainContent" Runat="Server">
<asp:Literal ID="Contents_Main" runat="server">
</asp:Literal>
</asp:Content>
Contents.aspx.vb codebehind:
Partial Class Contents
Inherits System.Web.UI.Page
Public Sub Contents_Load(ByVal sender As Object, ByVal e As EventArgs)
Handles Me.Load
Try
Dim url As System.Uri = Request.Url
Select Case True
Case url.AbsoluteUri.EndsWith("?p=ABCD")
Me.Contents_Main.Text = "content for ABCD"
Case url.AbsoluteUri.EndsWith("?p=WXYZ")
Me.Contents_Main.Text = "content for WXYZ"
Case Else
Me.Contents_Main.Text = "Landing Page"
End Select
Catch ex As Exception
Me.Contents_Main.Text = ex.Message & ex.StackTrace
End Try
End Sub
End Class
I was able to solve this by using the same concept in a single aspx form, rather than Master/Content. The menu is now in that single form and the codebehind pulls the data for the content. I do not know what was causing the Http 404 error, but using the single aspx form resolved it. Also, the URL must include a querystring, in the form of www.example.com?s=values, not www.example.com/keyword1-keyword2. The latter syntax also threw the 404 error.

Why controls don't behave on postback as expected?

Please forgive me if this has been asked before or if I am not asking correctly. I am new to programming and working on a school assignment.
Assignment: Create a web application project with 2 textboxes and a button control
a) On changing the text in field one the text in field 2 should blank.
b) On pressing the button the text from field one should be put in field 2
c) All event should be handled on the server side, so no javascript. (Confirmed this with teacher, NO JAVASCRIPT)
Here is the problem:
The page loads with both blank text boxes. I enter text in textbox1, press ok, page reloads but there is nothing in textbox2 (its supposed to copy contents of textbox1). If I press the submit button again, the text copies to textbox 2 as it should.
If I change the text in textbox1, leave focus, page reloads and blanks box 2 as it should. If I press submit button, it copies the text as it should.
I simply cannot get it to work properly the first time the page is loaded.
Here is the code for default.aspx:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body style="height: 141px">
<form id="form1" runat="server">
<div>
</div>
<asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<p>
<asp:Button ID="Button1" runat="server" Text="Submit" />
</p>
</form>
</body>
</html>
And here is the code from default.aspx.vb:
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox2.Text = TextBox1.Text
End Sub
Protected Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
TextBox2.Text = ""
End Sub
End Class
I know that when I am entering text into textbox1 for the first time that it is triggering the event for textchanged, but it seems to be happening in the wrong order that I need.
What am I not doing right?
Please let me know if you need any other information.
Generally speaking, it is incorrect to say "NO JS" because Postback is JS-invoked event. With no JS at all it is not possible because you can't cause Postback by typing into textbox. And TextChange event happens on postback when Asp.Net determined that content of TB has changed.
So if you want to type with postback you need minimal JS as described here
You need to remove AutoPostBack from your TextBox1 because it causes postback when focus moves from textbox. This is the problem. Your button is never pressed on the first pass hence your TextBox2.Text = TextBox1.Text never runs on the first time. Second time you already pressing the button, therefore code works.

Caching a dynamically/programmatically added user control

I'm trying to learn about caching, and in particular, partial caching using controls.
My website is running slow on certain pages, so caching as much as possible will be helpful.
Having run a number of experiments from code I have found on SO and various other Google results, I am running into an issue with dynamically added controls.
I have set up a simple page, containing this code:
<%# Page Language="VB" Debug="true" %>
<%# Register TagPrefix="controls" TagName="control" Src="~/test/control.ascx" %>
<script runat="server">
Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Label2.Text = "Present Time: "
Label2.Text += DateTime.Now.ToString()
End Sub
</script>
<html>
<body>
<form id="form1" runat="server">
<div>
<h2 style="color:Red">Output Caching</h2>
<asp:Label ID="Label2" runat="server"></asp:Label>
<controls:control ID='control1' runat='server' />
'------------------------------------------
<hr />
<div id='dyn2' runat='server' />
</div>
</form>
</body>
</html>
The control control.ascx looks like this:
<%# Control Language="VB" ClassName="control" %>
<%# OutputCache Duration="60" VaryByParam="r" %>
<script runat="server">
Sub Page_Load() Handles Me.Load
controlContent.InnerHtml = "Control time: " & DateTime.Now.ToString()
End Sub
</script>
<div id="controlContent" runat="server"></div>
This works well, and gives me a "live" time in the page, whilst the cached control shows me a time which is only updated after 60 seconds has passed, as per the OutputCache declaration.
I can see how I can use this for any application when I need to cache a part of a page and that part is explicitly entered into the page with a <controls> tag. The varyByParam option is useful to me too. (I've yet to investigate varyByCustom!)
However, in some cases I am loading a control into a page, programmatically based on specific needs.
In this case, I use code like this:
Dim theResult As test_control2 = CType(LoadControl("~\test\control2.ascx"), test_control2)
dyn2.Controls.Add(theResult)
This is programmatically adding my second test control, imaginatively entitled control2.ascx into the div with id "dyn2".
With no cache directive header in the control, or it's code-behind,l everything works fine, but I can't cache it (unless I cache the entire page).
However, if I add the cache header as per the control code above, I get this error:
Unable to cast object of type 'System.Web.UI.PartialCachingControl' to type 'test_control2'.
Googling doesn't seem to help me much with this, and investigating the PartialCachingControl types has lead me into further problems!
Can someone tell me what should be doing to enable me to cache these controls?
If it matters, I am coding in VB.net and also using .NET 2.0, so any advice on limitations on this platform would be appreciated too, if applicable.
Ah ha! Finally found another question on SO that helped
How to LoadControl a control that uses VaryByControl OutputCache, specifying values for properties
Basically, I was using the wrong Type when loading the control changin:
Dim theResult As test_control2 = CType(LoadControl("~\test\control2.ascx"), test_control2)
dyn2.Controls.Add(theResult)
to
Dim theResult As PartialCachingControl = DirectCast(LoadControl("~\test\control2.ascx"), PartialCachingControl)
dyn2.Controls.Add(theResult)
Sorted it!

Title on Master Page on ASP.Net MVC

To manage page title on page's,I have a master page where i am taking ContentPlaceHolder.
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /> </title>
and on every page i write
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">Some Title Here
</asp:Content>
Now my client ask me for remove title on all page's and keep it on master page but not remove content place holder code on all page's and master page so that in future if any requirement then we can insert data in to them.
So my problem is without removing them on master page and pages i am not able to put title on master page.So how can i handle this situation?
Thanks Guys.. I got solution
if you want to set part of the title from within the master page. For example, you might want the title of every page to end with a suffix, “ – MySite”.
If you try this (notice the – MySite tacked on):
<%# Master ... %>
<html>
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="titleContent" runat="server" /> - MySite
</title>
</head>
And run the page, you’ll find that the – MySite is not rendered. This appears to be a quirk of the HtmlHead control. This is because the title tag within the HtmlHead control is now itself a control.
The fix is pretty simple. Add your text to a LiteralControl like so.
<%# Master ... %>
<html>
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="titleContent" runat="server" />
<asp:Literalrunat="server" Text=" - MySite" />
</title>
</head>
If you want a good solution to overriding the page title:
Create a class of your own that inherits from the System.Web.Mvc.ViewPage.
Have your view pages inherit from that class:
Write a Page_Load handler in your new class that does something like this:
Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Me.Title = "Company Name | " + Page.Title
End Sub
You also don't need a content place holder to change the title. The <head> tag is already a runat server control. Setting the Page.Title in the page load (or earlier event) work just fine.
You could also put a runat server script tag in your master page to accomplish this task too.
Easiest way:
Move the current ContentPlaceHolder somewhere to your HTML, and wrap it in a <asp:PlaceHolder runat="server" visible="false"/>. When you'll be needing it later on, just move the ContentPlaceHolder back again.
Use the OnPreRender event on the master page to set the title, overriding what has been set on each page.
why not add attribute Visible=false to ContentPlaceHolder of Master Page
I think this is the easiest way to handle your situation.
Happy coding.

Proper use of MasterPages

I've been looking into different methods of implementing masterpages.
Use the masterpage only for layout, include common controls on every page
Include controls on the masterpage, use a masterpage abstract base class and override it's properties in the masterpage class. This caused the masterpage events to no longer wire up. I could probably fix this, but it's a long way to go just for a single textbox value.
use good 'ol Page.Master.FindControl()
I've read that findcontrol should be avoided (uses magic "label1" strings, supposedly uses too many resources) and masterpages are only for layout. If masterpages are only for layout, do I copy and paste common controls across 100's of pages?
What's the best practice that deals with displaying and accessing common site controls (like a search)? Considering the alternatives, using findcontrol to get a masterpage control doesn't seem that bad.
MasterPages are classes just like a normal Page object. That means you can expose internal controls through public properties to allow child Pages to access without having to resort to Master.FindControl(). To do this you just need to set the MasterType property in the page (I think it may work even without setting this but with this you get intellisense support and avoid having to do casts).
Here's a basic example (sorry it's in VB - this is copying and pasting from an old project):
Master page (.master):
<%# Master Language="VB" CodeFile="default.master.vb" Inherits="DefaultMaster" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form runat="server">
<ASP:TextBox ID="Search" RunAt="Server"/>
<ASP:ContentPlaceHolder ID="Content" RunAt="Server"/>
</form>
</body>
</html>
Master code-behind (.master.vb):
Partial Class DefaultMaster : Inherits MasterPage
Public ReadOnly Property SearchBox() As TextBox
Get
Return Search
End Get
End Property
End Class
Accessing page (.aspx):
<%# Page Language="VB" MasterPageFile="default.master" CodeFile="page.aspx.vb" Inherits="ExamplePage" %>
<%# MasterType TypeName="DefaultMaster" %>
<ASP:Content ContentPlaceHolderID="Content" RunAt="Server">
<p>This is some content on the page.</p>
</ASP:Content>
Accessing page code-behind (.aspx.vb):
Partial Class ExamplePage : Inherits Page
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles MyBase.Load
Master.SearchBox.Text = "This page now has access to the master's search box."
End Sub
End Class
Agreeing that master pages are only for layout, would a sensible approach not to farm out the common controls to usercontrols and include them in the master page this way.

Resources