Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > ASP .Net > Extending/Inheriting classes to produce valid XHTML from ASP.NETv1.1

Reply
Thread Tools

Extending/Inheriting classes to produce valid XHTML from ASP.NETv1.1

 
 
Anthony Williams
Guest
Posts: n/a
 
      02-17-2004
Morning all,

I'm having a wee problem with a project I'm working on at the moment.
I'm leading my company into producing a website, based upon Web
Standards, which will be created using XHTML and CSS, and powered by
ASP.NET.

My first problem, which I'm near to solving, was that ASP.NET doesn't
produce valid XHTML output. We don't want to spend money on third-party
components, and we can't wait for ASP.NET 2.0, so we needed to find a
way to use what we have to produce what we're after.

I've taken to extending the System.Web.UI.Page and
System.Web.UI.HtmlControls.HtmlForm controls (using Liquid Internet's
methods, but converted to VB.NET, from
http://www.liquid-internet.co.uk/con...1article1.aspx)
and after a couple of hiccups with events not firing, and changing
Request.Path to Request.Url.ToString, I've managed to get everything
working.

Except that - if you take a look at the generated XHTML (which isn't
valid yet by the way) - you'll find there is two hidden input fields
called "__VIEWSTATE". One of them lives inside a <div> tag (valid
XHTML), the other does not (invalid XHTML).

Forgive me if I'm asking a question in the realms of newbie-dom, but
I've no idea why two ViewState containers are being generated, and would
really appreciate some help.

For clarity, the default namespace in this project is "Listers.Group",
and the assembly is called Listers.Group.dll.

' --- BEGIN CODE BLOCK - TestForm.aspx ---
<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="listers.aspx.vb" Inherits="Listers.Group.Pages.Listers" %>
<%@ Register TagPrefix="XHTML" Namespace="Listers.Group.XHTML"
Assembly="Listers.Group" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title runat="server" id=lgTitle>ListersGroup.co.uk - The largest
privately-owned
motor group in the Midlands!</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="MSSmartTagsPreventParsing" content="true" />
<meta name="description" content="" id="lgDescription" runat="server" />
<meta name="keywords" content="" id="lgKeywords" runat="server" />
<link rel="stylesheet" type="text/css" href="inc/css/ListersAll.css"
media="all" title="ListersGroup.co.uk" />
</head>
<body>
<XHTML:Form id="ListersForm" method="post" runat="server">
<div id="Page">
<div id="Header">
<h1>ListersGroup.co.uk</h1>
<!-- A Custom Control normally lives here -->
</div>
<div id="Body">
<div id="Navigation">
<!-- A Custom Control normally lives here -->
</div>
<div id="Content">
<!-- A Custom Control normally lives here -->
<p>A button, to test viewstate and event firing:<br /><asp:button
id="Button1" runat="server" Text="Button"></asp:button></p>
</div>
<div>
<div id="Footer">
<!-- A Custom Control normally lives here -->
</div>
</div>
</XHTML:Form>
</body>
</html>
' --- END CODE BLOCK - TestForm.aspx ---

' --- BEGIN CODE BLOCK - XHTML.vb ---
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Imports System.Web.UI.WebControls
Imports System.IO

Namespace XHTML
Public Class Page
Inherits System.Web.UI.Page

Public Sub New()
' ...
End Sub ' New

Protected Overrides Function
LoadPageStateFromPersistenceMedium() As Object
Dim Format As New LosFormatter
Dim ViewState As String =
Request.Form("__VIEWSTATE").Trim.ToString
Return Format.Deserialize(ViewState)
End Function ' LoadPageStateFromPersistenceMedium

Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal
ViewState As Object)
For Each c As Control In Me.Controls
If c.GetType.ToString = "Listers.Group.XHTML.Form" Then
Dim Format As New LosFormatter
Dim Writer As New StringWriter
Format.Serialize(Writer, ViewState)

Dim StateContainer As New LiteralControl
StateContainer.Text = _
"<div id=""ViewStateContainer"">" & _
"<input type=""hidden""
name=""__VIEWSTATE"" value=""" & Writer.ToString & """ />" & _
"</div>"

c.Controls.AddAt(0, StateContainer)
End If
Next
End Sub ' SavePageStateToPersistenceMedium

End Class

Public Class Form
Inherits System.Web.UI.HtmlControls.HtmlForm

Public Sub New()
' ...
End Sub ' New

Protected Overrides Sub RenderAttributes(ByVal Output As
System.Web.UI.HtmlTextWriter)
Output.WriteAttribute("id", Me.ID)
Output.WriteAttribute("method", Me.Method)
Output.WriteAttribute("action",
HttpContext.Current.Request.Url.ToString)
End Sub
End Class
End Namespace
' --- END CODE BLOCK - XHTML.vb ---

Thanks in advance for any help!
--
Anthony Williams
http://www.bigtone.net
 
Reply With Quote
 
 
 
 
Anthony Williams
Guest
Posts: n/a
 
      02-17-2004
Anthony Williams wrote:

> Except that - if you take a look at the generated XHTML (which isn't
> valid yet by the way) - you'll find there is two hidden input fields
> called "__VIEWSTATE". One of them lives inside a <div> tag (valid
> XHTML), the other does not (invalid XHTML).


Allow me to direct you to a site where you can see the generated XHTML:
http://dev.listersgroup.com/listers.group/listers.aspx

Whoops! )

--

Anthony Williams
BigTone Interactive
http://www.bigtone.net
 
Reply With Quote
 
 
 
 
Steven Cheng[MSFT]
Guest
Posts: n/a
 
      02-18-2004
Hi Anthony,


Thanks for posting in the community!
From your description, you've implement a group of custom ASP.NET server
controls which'll render out valid XHTML element and also, you 've override
the certain methods which used to load and save viewstate so as to maintain
the viewstate yourself. However, you found that the page's response content
will contain two hidden field named "__VIEWSTATE", one is the one you
manually generated which is valid and the other not. You're wondering what
is the other one and how to avoid it,yes?
If there is anything I misunderstood, please feel free to let me know.

As for this this problem, I think it is a general behavior because the
ASP.NET page will store and mantain the page's control's setting in a
certain hidden field named "__VIEWSTATE", the content is encoded as base64
format string. And when page is rendered out to client , the page's
viewstate will be added into this field, also when the page posted back,
the ASP.NET will retrieve back these infos and instantial it from this
hidden field. The two method you've ovrride in your code:
Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
................
End Function ' LoadPageStateFromPersistenceMedium

Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal
.....
End Function

Bydefault , the parent class (page class) will do these operations on
viewstate. Since you've overrided the two method especially the
SavePageStateToPersistenceMedium, and you didn't call the parent's method
in your override method. The page won't set the hidden filed <input
type="hidden" name ="__VIEWSTATE"...>. And because you've added another
hidden field also named "__VIEWSTATE" , that's why you found there are two
hidden field named "__VIEWSTATE" in the response content, do you think so?

So as for your situation, you have implemented your own SERVER Controls and
the Viewstate's Serializer and Deserializer, you manually write and
retrieve the viewstate, the original "hidden" field is useless for you.
However, this hidden field is added by ASP.NET's page class implicitly(when
the page is rendered out to client), so we don't have any explicit
interfaces to remove it unless we disable the viewstate(I think that's not
what we want). How do you think of this?

Here is a tech article discussing on the VIEWSTATE in ASP.NET
#Taking a Bite Out of ASP.NET ViewState
http://msdn.microsoft.com/library/en...001.asp?frame=
true

Please check out the preceding suggestions and tell me your further
requirement on this so as for me to do some further research to assit you.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx

 
Reply With Quote
 
Steven Cheng[MSFT]
Guest
Posts: n/a
 
      02-18-2004
Hi Anthony,


I've searched for some further materials on the XHTML issue with ASP.NET
page and control. Here is a good tech article which exactly discussing on
this and provide some informative solutions. I'm not sure whether you've
already read it before, here is the web link to it:

#Valid XHTML within .NET
http://www.liquid-internet.co.uk/con...1article1.aspx

I notice that it has implement a custom Form class(named Liquid:CustomForm)
which derived from the ASP.NET HtmlForm Class , then we should use this
custom form in ASP.NET web page rather then the normal <form> tag, for
example:
<%@ Page Inherits="Liquid.Tutorial.CustomPage" AutoEventWireup="True" %>
<%@ Register TagPrefix="Liquid" Namespace="Liquid.Tutorial"
Assembly="Liquid.Tutorial" %>
<?xml version="1.0" encoding="utf-8"?>
...........................................
<body>
<Liquid:CustomForm
id="myId"
method="post"
runat="server">
<fieldset>
<legend>Sample form</legend>
<input type="submit"/>
<asp:Literal
id="inputViewState"
runat="server"/>
</fieldset>
</Liquid:CustomForm>
............. </body>
</html>


Then, do you think it possbile to use this "Liquid:CustomForm" instead in
your web pages?

In addition to the above solution, I think there is still another means to
manually modify the response content. We can use the Http Module in ASP.NET
to do some modification on the certain request or response object. And the
httpModule has serverl events such as
BeginRequest.
EndRequest
PreSendRequestHeaders
PreSendRequestContent
And the "PreSendRequestContent" event signals that content is about to be
sent to the client. This provides an opportunity to modify the content
before it is sent.

So I think you can take advantage of this event and manually remove the
additional useless <input type=hidden name="__VIEWSTATE" ..> tag in the
response's stream, do you think so?

and here are some tech articles on using the response filter(httpmodule),
the first one is exactly focus on the XHTML
compliant:

# Producing XHTML-Compliant Pages With Response Filters
http://www.aspnetresources.com/artic...tpFilters.aspx

#Implementing Intercepting Filter in ASP.NET Using HTTP Module
http://msdn.microsoft.com/library/en...erceptingFilte
rInASP.asp?frame=true


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx




 
Reply With Quote
 
Anthony Williams
Guest
Posts: n/a
 
      02-18-2004
Steven Cheng[MSFT] wrote:

> Thanks for posting in the community!
> From your description...


....snip snip snippety snip...

> ...which is valid and the other not. You're wondering what
> is the other one and how to avoid it,yes?


Yes, that's exactly what I'm doing.

> As for this problem, I think it is a general behavior because the
> ASP.NET page will store and mantain the page's control's setting in a
> certain hidden field named "__VIEWSTATE", the content is encoded as base64
> format string. And when page is rendered out to client , the page's
> viewstate will be added into this field, also when the page posted back,
> the ASP.NET will retrieve back these infos and instantial it from this
> hidden field. The two method you've ovrride in your code:
> Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
> ...............
> End Function ' LoadPageStateFromPersistenceMedium
>
> Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal
> ....
> End Function


I know. It's the general (default) behaviour that I'm trying to override
here, because it generates invalid markup.

> Bydefault , the parent class (page class) will do these operations on
> viewstate. Since you've overrided the two method especially the
> SavePageStateToPersistenceMedium, and you didn't call the parent's method
> in your override method. The page won't set the hidden filed <input
> type="hidden" name ="__VIEWSTATE"...>. And because you've added another
> hidden field also named "__VIEWSTATE" , that's why you found there are two
> hidden field named "__VIEWSTATE" in the response content, do you think so?


Actually no, that's not it. I'm wondering why, when I've overridden the
SavePageStateToPersistenceMedium method, it appears to fire the same
method in the parent System.Web.UI.Page class.

> So as for your situation, you have implemented your own SERVER Controls and
> the Viewstate's Serializer and Deserializer, you manually write and
> retrieve the viewstate, the original "hidden" field is useless for you.


Not useless - just invalid.

> However, this hidden field is added by ASP.NET's page class implicitly(when
> the page is rendered out to client), so we don't have any explicit
> interfaces to remove it unless we disable the viewstate(I think that's not
> what we want). How do you think of this?


Well, here's the clincher. I've previously tried to do this in C#, and
it worked perfectly - something to do with the fact that, in C#, unless
you explicitly call the parent's methods within your overridden method,
they will not fire. I'm just wondering why this isn't the case with
VB.NET (or maybe I'm wrong.)

I don't want to disable ViewState, I simply want to make it persist to
the page using valid XHTML, preferably using VB.NET (because that's what
everyone else in my team is using) and within the same project.

Thanks!
--
Anthony Williams
http://www.bigtone.net
 
Reply With Quote
 
Anthony Williams
Guest
Posts: n/a
 
      02-18-2004
Steven Cheng[MSFT] wrote:

> I've searched for some further materials on the XHTML issue with ASP.NET
> page and control. Here is a good tech article which exactly discussing on
> this and provide some informative solutions. I'm not sure whether you've
> already read it before, here is the web link to it:
>
> #Valid XHTML within .NET
> http://www.liquid-internet.co.uk/con...1article1.aspx


Cool... though I'm sure I've seen that link somewhere before...

> Anthony Williams wrote:
>
>> I've taken to extending the System.Web.UI.Page and
>> System.Web.UI.HtmlControls.HtmlForm controls (using Liquid Internet's
>> methods, but converted to VB.NET, from
>> http://www.liquid-internet.co.uk/con...1article1.aspx)
>> and after a couple of hiccups with events not firing, and changing
>> Request.Path to Request.Url.ToString, I've managed to get everything
>> working.


Ah yes... that's where I saw it.

> I notice that it has implement a custom Form class(named Liquid:CustomForm)
> which derived from the ASP.NET HtmlForm Class , then we should use this
> custom form in ASP.NET web page rather then the normal <form> tag, for
> example:


Steven, I've pretty much used the Liquid Internet method, except I've
chosen to use VB.NET instead of C#, and because I'm the only member of
my team who is using Visual Studio (everyone else is using Visual
Basic.NET 2003) they would be unable to work on the project.

If you check out the Liquid example, you'll see that the C# code does
not implicitly call the parent method.

> Then, do you think it possbile to use this "Liquid:CustomForm" instead in
> your web pages?


I'd rather use my own code, as I need to extend some other controls too.

> In addition to the above solution, I think there is still another means to
> manually modify the response content. We can use the Http Module in ASP.NET
> to do some modification on the certain request or response object. And the
> httpModule has serverl events such as
> BeginRequest.
> EndRequest
> PreSendRequestHeaders
> PreSendRequestContent
> And the "PreSendRequestContent" event signals that content is about to be
> sent to the client. This provides an opportunity to modify the content
> before it is sent.


If this is the only way to get around the implicit firing of the parent
event, then I guess I shall have to go with it, but from my own
research, I've found that this method is only useful for sites with
small amounts of traffic - perforing a RegEx operation on a string
everytime a page is requested seems like overkill - all I want to do is
stop my method from implicitly calling the parent method.

--
Anthony Williams
http://www.bigtone.net
 
Reply With Quote
 
Anthony Williams
Guest
Posts: n/a
 
      02-20-2004
Steven Cheng[MSFT] wrote:
> Hi Anthony,
>
> I've created a small sample application(VB.NET). It contains one page,
> using the Liquid class, and the page is use codebehind page. I change the
> Liquid class, divede it into two parts. And now it could work. Since I
> haven't other XHTML controls ,may be you can try adding some XHTML controls
> onto it to see whether it works.


Cool - the page works, but it's not doing it exactly as I want it to.

The Liquid method requires that you place a Literal control onto the
page - I don't want to do this, as this isn't the idea behind extending
the Page class.

Whilst my method also uses a Literal control, it creates the control
programatically and inserts it at position 0 in the XHTML form's
Controls collection.

> In addition, I found that the VS.NET IDE will change the HTML source(aspx
> page SOURCE) when you change from the Html view and design view of the
> page, and that'll cause the page's source become invalid. So it is
> recommend that you edit aspx page use text edit or just in html source.


Yeah, this is something that - as a standards based designer - I've been
aware of for ages. It's one of the most annoying things about VS' HTML
editor, and I'll be glad when Whideby finally moves into a more stable
release so that I can ditch 2002/2003 for good.

> Please check out my sample page. Also, if you have got any further ideas ,
> please also feel free to post here. Thanks.


It works fine, but not as I need it to - I'd also be interested in how
you managed to get the parent method of the Page to *not* fire, and not
have the net result of two viewstate fields.

I'll probably go and ask the bods in the m.p.d.f.a.buildingcontrols
group (which I've only just found) to see if they know of any ways to
explicitly override the parent methods - I don't want them firing
implicitly as they are!

Thanks for your help.
--
Anthony Williams
http://www.bigtone.net
 
Reply With Quote
 
Steven Cheng[MSFT]
Guest
Posts: n/a
 
      02-21-2004
Hi Anthony,


Thanks for your response. Yes, the Liquid class used a Literal Control to
Contain the <input hidden > element for store viewstate. However, I think
you can replace it with other controls( your custom XHTML controls), please
try replace the Literal Control member of the Page CLASS in my sample with
your own custom control, don't modify the other function to see whether it
work. Also, as for how to let the page only display only one "<input
type=hidden name="__viewstate" >" field, I think it is mainly due to that
you must override the CustomForm class's RenderChild method. You may have a
further view and check on the sample page or the Liquid form's class code,
I believe you'll get the idea. Any way, hope you'll soon get the ideas you
want.



Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx

 
Reply With Quote
 
Anthony Williams
Guest
Posts: n/a
 
      02-24-2004
Steven Cheng[MSFT] wrote:

> Hi Anthony,
>
> Thanks for your response. Yes, the Liquid class used a Literal Control to
> Contain the <input hidden> element for store viewstate. However, I think
> you can replace it with other controls( your custom XHTML controls), please
> try replace the Literal Control member of the Page CLASS in my sample with
> your own custom control, don't modify the other function to see whether it
> work.


Yeah, I've chosen to use the literal control also, I'll happily post the
code here when I'm done. I'm creating the control programatically as
opposed to declaratively as shown in the Liquid method.

> Also, as for how to let the page only display only one "<input
> type=hidden name="__viewstate" >" field, I think it is mainly due to that
> you must override the CustomForm class's RenderChild method.


That sounds promising. I'll check it out - thanks for the direction!
--
Anthony Williams
http://www.bigtone.net
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
convert xhtml to another xhtml using xslt Usha2009 XML 0 12-20-2009 01:13 PM
Should I Convert Site To XHTML or XHTML mobile? chronos3d HTML 9 12-05-2006 04:46 PM
can java produce .exe? if it can produce jar,how do you do? aungkopyay@gmail.com Java 5 10-27-2006 02:07 AM
parse URL (href) from xhtml, xhtml -> text, for data hawat.thufir@gmail.com XML 7 02-08-2006 07:39 PM
did not produce a valid header Sherm Pendley Perl Misc 6 06-20-2005 07:56 PM



Advertisments