How do I output Massive ORM dynamic query to an MVC 3 View?

1.3k Views Asked by At

When I use Massive ORM to retrieve a record using the .Find() method, it returns a Massive.DynamicModel.Query object which doesn't get along very well with the ASP.MVC 3 View.

Controller:

public ViewResult Details(int id)
{
    // Massive ORM Find syntax requires this next statement to use 'dynamic' not 'var'
    dynamic table = new Things();

    // Thing will return as type Massive.DynamicModel.Query
    var Thing = table.Find(ThingId:id); 

    return View(Issue);
}

In the View, I've tried both @model dynamic and @model Massive.DynamicModel.Query, but neither will allow me to access the properties of my 'Thing' object using the normal @Model.Name syntax.

There is some discussion on here about how to handle ExpandoObjects with MVC3 views, but nothing in particular about the Massive.DynamicModel.Query implementation that has worked for me so far.

Any general ideas how to convert the Massive.DynamicModel.Query object to something typed?

4

There are 4 best solutions below

3
On

Two words: View models. Strongly typed view models, that's what you should be passing to your views. Not dynamics, not expandos, not anonymous objects, not ViewData, not ViewBag => only strongly typed view models. So start by defining a view model which will represent the data this view will be working with. Then have your controller action do the necessary in order to convert whatever your repositories spit into a view model which will be passed to the view.

Failing to follow this basic rule, your ASP.NET MVC experience could quickly turn into a nightmare.

0
On

Because of anonymous type are always annotated as "internal" so you can't access your dynamic type instance from View as they are in different scopes.

I find a better way make it work than using ViewBag. And the answer is Mono.Cecil. Grab it handy from NuGet.

With Mono.Cecil's help you can change MSIL code generated from your ASP.NET MVC project and change the type's accessible modifier to "public".

I write a little console program and host it on GitHub.

You can invoke the program from command line or add a post-build event in your ASP.NET MVC project's Build Events:

"$(SolutionDir)DynamicHelper\bin\Debug\DynamicHelper.exe" "$(TargetPath)"

NOTICE: "DynamicHelper" is the the code's project name and you can change it depending on your situation.

0
On

I'm experimenting with dynamics and Massive now. I'm using a dynamic viewModel:

   public ActionResult Index() {
        _logger.LogInfo("In home");
        dynamic viewModel = new ExpandoObject();
        var data = _tricksTable.Query("SELECT TOP(10) * FROM Tricks ORDER BY DateCreated DESC");
        viewModel.TenTricksNewestFirst = data;

        var data2 = _tricksTable.Query("SELECT TOP(10) * FROM Tricks ORDER BY Votes DESC");
        viewModel.TenTricksMostPopularFirst = data2;
        return View(viewModel);
    }

In my view there is no reference to anything strongly typed on the first line eg NOT THIS:

@model IEnumerable<MvcApplication2.Models.Thing>

so in my view I do stuff like this:

@foreach (var item in Model.TenTricksNewestFirst) {
              <div class="post block">
                <div class="tab-image-block">
                    <a href="/tricks/@URL.MakeSpacesMinuses(@item.Name)" title="@item.Name">

                        <img src="/public/images/@item.Thumbnail" alt="@item.Name" class="woo-image thumbnail" /></a>
                </div>
                <h2 class="title">
                    <a href="/video/uncross-your-arms" rel="bookmark" title="@item.Name">@item.Name</a></h2>
                <span class="date">@Dates.ShortDate(@item.DateCreated)</span>
                <span class="likes">Likes: @item.Votes</span>
               </div>
            }

Experience so far is that I'm writing a lot less code.

1
On

I think the easiest way is to use ViewBag because it's dynamic already.

You'd better watch the production because it's about Rob's opinionated way of development more than it is about MVC 3, and describes using Massive and other Rob tools.

But even if you don't make sure to check the code sample here for the production (free), to see how he integrates Massive to MVC 3:

https://github.com/tekpub/mvc3

You can see his production controller looks like. Quite interesting ways.