I'm poking around with ViewState programming in ASP.NET 2.0 with F# and ran into some mental blocks with IEnumerable and how it works with ControlCollection. I also had some mental hurdles to overcome working with IDictionary and Page ViewState
When I tried to implement the ViewState Test example in Chapter 6 of Pro ASP.NET 2.0 in C#, I ran into the problem of working with ViewState. My SaveAllText() method would complain with the message A protected member is called. These are not allowed in lambda expressions since they could escape the object.. Searching the web on this brings me back to Don Syme's blogs which talked about a GenerateMaximallyAccessibleDerivedClass method that was used in an apparently older version of the F# compiler. I'm banging my head against the wall until I tried creating my own mutable StateBag member variable and set it to refer to ViewState. That seemed to let me progress. I'm stil not sure if I introduced any other problems with this, but it did let me bypass the protected member problem and the page worked as expected
My mental hurdle with IDictionary is I did not how to do something such as
string value = dictionary[mykey]I googled for it and did not turn up with anything at all. Finally, I decided to fire up F# interactive and started to explore a IDictionary object. When I took a look at the signature for
IDictionary.Itemit returned the following signature:
val it : 'a -> obj = <fun:clo@0>I had not realized that IDictionary.Item was a function! Now I know how to find a value by key with a IDictionary object.
The last mental hurdle I have is with IEnumerator objects. I wanted to do something like
IEnumerable.iter myfunc controlsbut I keep getting a complaint about The type ControlCollection is not compatible with the type seq<Control>. Somehow, that error message did not register with me that I'm trying to stuff a nongeneric IEnumerator into a function that's expecting a generic version of IEnumerator object. Finally, after staring at the list of functions available to IEnumerable, I noticed
IEnumerable.untyped_to_typedFinally, the last piece of this puzzle was solved. Below is the code I was struggling with that now works in F#:
#light
namespace FSharp.HttpHandlers
open System
open System.Data
open System.Configuration
open System.Collections
open System.Web
open System.Web.Security
open System.Web.UI
open System.Web.UI.WebControls
open System.Web.UI.WebControls.WebParts
open System.Web.UI.HtmlControls
//
// View State Test example from Chap 6 of Pro ASP.NET 2.0 in C#
//
type ViewStateTest = class
inherit Page as base
val mutable state : StateBag
new () as this = { state = null;testmsg=null } then
this.state <- this.ViewState
member this.SaveAllText (controls:ControlCollection) (saveNested:bool) =
let rec addtoViewstate (state:StateBag) (control:Control) =
if (control :? TextBox) then
let txtbox = control :?> TextBox
state.Item(control.ID) <- txtbox.Text
if ((control.Controls <> null) && saveNested) then
(IEnumerable.untyped_to_typed control.Controls)
|> IEnumerable.iter (addtoViewstate state)
IEnumerable.iter (addtoViewstate this.state) (IEnumerable.untyped_to_typed controls)
member this.RestoreAllText (controls:ControlCollection) (saveNested:bool) =
let rec restoreFormViewstate (state:StateBag) (control:Control) =
if (control :? TextBox) then
let txtbox = control :?> TextBox
txtbox.Text <- ((state.Item control.ID) :?> string)
if ((control.Controls <> null) && saveNested) then
(IEnumerable.untyped_to_typed control.Controls)
|> IEnumerable.iter (restoreFormViewstate state)
IEnumerable.iter (restoreFormViewstate this.state) (IEnumerable.untyped_to_typed controls)
member this.cmdSave_Click ((sender:obj), (e:EventArgs)) =
this.SaveAllText this.Page.Controls true
member this.cmdRestore_Click ((sender:obj), (e:EventArgs)) =
this.RestoreAllText this.Page.Controls true
end
No comments:
Post a Comment