Search code examples
c#asp.netasp.net-mvcviewbag

Count and Sum functions with help of ViewBag


I have a question how to solve my problem. There is a table with items. Each item has a status "open" or "closed". For instance, 9 items with "closed" status and 14 ones with "open". I need to find the difference between open and closed items (14 - 9 = 5). How can I do it with help of ViewBag? As I understood, it is required to write "count" function in controller and transmit the result to View via ViewBag. But I don't know how to write this code. The result should be shown on the View page.

Request.cs (Model):

public class Request
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public string Status { get; set; } = "";
}

Controller.cs:

public IActionResult Requests()
{
    var Requests = _repo.GetAllRequests();
    return View(Requests);
}

Repository:

public Request GetRequest(int id)
{
    return _ctx.Requests.FirstOrDefault(c => c.Id == id);
}

public List<Request> GetAllRequests()
{
    return _ctx.Requests.ToList();
}

View:

<div>
    <table>
        @foreach (var request in Model)
        {
        <tr>
            <th>@request.Name</th>
            <th>@request.Status</th>
        </tr>
        }
    </table>
</div>

Solution

  • You would pass a predicate to Count to filter the requests by status:

    public IActionResult Requests()
    {
        var requests = _repo.GetAllRequests();
    
        ViewBag.OpenRequests = requests.Count(r => r.Status == "open");
        ViewBag.ClosedRequests = requests.Count(r => r.Status == "closed");
    
        return View(requests);
    }
    

    However, rather than using the ViewBag you could create a view model to hold all the information/data required by the view:

    // ViewModel
    public class RequestViewModel
    {
        public List<Request> Requests { get; set; }
        public int OpenRequests { get; set; }
        public int ClosedRequests { get; set; }
    }
    
    // Controller
    public IActionResult Requests()
    {
        var requests = _repo.GetAllRequests();
        
        var viewModel = new RequestViewModel();
        viewModel.OpenRequests = requests.Count(r => r.Status == "open");
        viewModel.ClosedRequests = requests.Count(r => r.Status == "closed");
        viewModel.Requests = requests;
    
        return View(viewModel);
    }
    
    // View: set the model for the view
    @model Project.Namespace.RequestViewModel
    ...
    <div>
        <div>Open Requests: @model.OpenRequests</div>
        <div>Closed Requests: @model.ClosedRequests</div>
        <div>Difference/delta: @(model.OpenRequests - model.ClosedRequests)</div>
    </div>