jimminybob
jimminybob

Reputation: 1442

MVC - Display multiple Controller results in one view

I have a controller in my MVC sire that has a couple of methods along the lines of the following:

public ActionResult _GetServiceStatus()
{
...
}

public ActionResult _GetEventLogErrors()
{
...
}

Each of these methods references a different class type that I have stored in my Model, Service and Event respectively. These can be seen below:

public class Service
    {
        public string Name { get; set; }
        public string Status { get; set; }
    }

    public class Event
    {
        public string Source { get; set; }
        public string EntryType { get; set; }
        public string Message { get; set; }
        public DateTime Date { get; set; }
    }

What I want to do is to show the results of these methods on a single view. I already have this working for the Services check, with the results displaying correctly, but I cannot find how to add in the Event results.

What I have currently in my view is below:

@{
    ViewBag.Title = "Monitoring";
}

@model IEnumerable<SystemMonitoringTool.Models.Monitoring.Service>

<div style="width:25%">
    <span>
        Services
    </span>
    <table id="services" style="border:solid; border-width:2px; width:100%">
        @foreach (var item in Model) {  
         <tr>
             <td>
                 @Html.DisplayFor(model => item.Name)
             </td>
             <td>
                 @Html.DisplayFor(model => item.Status)
             </td>
         </tr>                       
        }
    </table>
</div>

Can someone help me find a way to display these side by side on the same view? Will be happy to provide more info if needed.

Upvotes: 0

Views: 1461

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239300

Two options:

  1. Use child actions. Instead of directly going to one of these individual controller actions, instead add an action like:

    public ActionResult Monitoring()
    {
        return View();
    }
    

    You'll notice this action doesn't do much. It's just rendering a view. Then you'll need to move your HTML for services/events into partial views. For example, _GetServiceStatus.cshtml and _GetEventLogErrors.cshtml, where the model for each will be a collection of your Service or Event types, respectively. Finally, in your Monitoring.cshtml view (based on the action name above), you'll add:

    @Html.Action("_GetServiceStatus")
    @Html.Action("_GetEventLogErrors")
    

    This view doesn't need a model, because it's not directly working with anything.

  2. Use a view model that encapsulates your two collections:

    public class MonitoringViewModel
    {
        public List<Service> Services { get; set; }
        public List<Event> Events { get; set; }
    }
    

    Then you'll still need a unifying action. But here, you'll populate both lists. Basically, you'll just be moving your two existing actions into one:

    public ActionResult Monitoring()
    {
        var model = new MonitoringViewModel
        {
            Services = /* code to retrieve services */,
            Events = /* code to retrieve events */
        }
        return View(model);
    }
    

    Then, you can iterate through each list independently to build your HTML:

    Monitoring.cshtml (again, based on the action name)

    @model Namespace.To.MonitoringViewModel
    
    ...
    
    <table id="services" style="border:solid; border-width:2px; width:100%">
        @foreach (var item in Model.Services) { // notice the change here  
         <tr>
             <td>
                 @Html.DisplayFor(model => item.Name)
             </td>
             <td>
                 @Html.DisplayFor(model => item.Status)
             </td>
         </tr>                       
        }
    </table>
    

Upvotes: 3

Related Questions