Set a property on ViewBag dynamic object in F#

2019-03-29 05:44发布

问题:

I have this action method in C#:

  public ActionResult Index() {
      ViewBag.Message = "Hello";
      return View();
  }

And this view (Index.cshtml):

  <h2>@ViewBag.Message</h2>

And this produces the expected "Hello" on the page.

I want to do the controller in F#. I've tried

type MainController() =
  inherit Controller()
  member x.Index() =
    x.ViewBag?Message <- "Hello"
    x.View()

And this produces the error message "Method or object constructor 'op_DynamicAssignment' not found".

I've looked at some of the F# code samples for the dynamic operator, and I can't see anything that's shorter than several pages of description and many lines of code. They seem to be too general for just this property "setter".

回答1:

The ViewBag property is just a wrapper that exposes the ViewData collection as a property of type dynamic, so that it can be accessed dynamically from C# (using property set syntax). You could use implementation of ? based on DLR to do that (see this discussion at SO), but it is easier to define ? operator that adds data directly to ViewDataDictionary (which is exposed by the ViewData property):

let (?<-) (viewData:ViewDataDictionary) (name:string) (value:'T) =
  viewData.Add(name, box value)

Then you should be able to write

x.ViewData?Message <- "Hello"


回答2:

Instead of

x?ViewBag <- "Hello"

Try:

x.ViewBag?Message  <- "Hello"