Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate through a dictionary inserted in a ASP.NET MVC4 page's ViewData via F# code? (Razor)

Call me crazy but I'm developing an ASP.NET MVC4 site in F#. Here's my first roadblock; in the controller I submit a dictionary, this way:

[<HandleError>]
type FooController() =
    inherit Controller()
    member this.Index () =
        this.ViewData.Add("Foo", "Bar")
        this.ViewData.Add("Baz", dict [ (0, 0); (1, 3); (2, 2); ] )
        this.View() :> ActionResult

Now I want to iterate through the values in the Razor template, how to do it? I've tried this:

@foreach (var time in @ViewBag.Baz.Keys)
{
    <hr /><p>Time is @time, and value is @ViewBag.Baz[time]</p>
}

But it throws this error:

Line 119:                    Total: <span class="highlight">6449</span> kW/h.
Line 120:                </p>
Line 121:                @foreach (var time in (@ViewBag.Baz).Keys)
Line 122:                {
Line 123:                    <hr /><p>Time is @time, and value is @ViewBag.Baz[time]</p>

[RuntimeBinderException: 'object' does not contain a definition for 'Keys']
   CallSite.Target(Closure , CallSite , Object ) +280
   System.Dynamic.UpdateDelegates.UpdateAndExecute1(CallSite site, T0 arg0) +924
   ASP._Page_Views_lobby_Index_cshtml.Execute() in c:\Users\knocte\documents\visual studio 2012\projects\fsolar\conclavesolarweb\conclavesolarwebwebapi\Views\Lobby\Index.cshtml:121
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +280
   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +126
   System.Web.WebPages.StartPage.ExecutePageHierarchy() +143
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +181
   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +378
   System.Web.Mvc.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17() +33
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +853420
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +265
   System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +837892
   System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +28
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +15
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +65
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +15
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +51
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +15
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +51
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288
like image 916
knocte Avatar asked Mar 19 '14 18:03

knocte


People also ask

What is ViewData in ASP NET MVC?

In MVC, when we want to transfer the data from the controller to view, we use ViewData. It is a dictionary type that stores the data internally. ViewData contains key-value pairs which means each key must be a string in a dictionary. The only limitation of ViewData is, it can transfer data from controller to view.

Is ViewData a dictionary?

ViewData is a dictionary of objects that are stored and retrieved using strings as keys. It is used to transfer data from Controller to View. Since ViewData is a dictionary, it contains key-value pairs where each key must be a string. ViewData only transfers data from controller to view, not vice-versa.

How do you pass data from view to controller in MVC using ViewData?

ViewData itself cannot be used to send data from View to Controller and hence we need to make use of Form and Hidden Field in order to pass data from View to Controller in ASP.Net MVC Razor.


1 Answers

So the problem you are experiencing is a know limitation of the dynamic keyword and explicit interface implementations. Unfortunately Map will have this problem too. If you really want to use a ViewBag like this, you could use an actual Dictionary<int,int>.

Ultimately, however you should play to F#'s strengths, which is static typing and low ceremony type creation. Create lightweight types in your F# code and use the @model keyword in your views.

like image 187
jbtule Avatar answered Oct 16 '22 18:10

jbtule