Search code examples
c#asp.net-mvcasp.net-mvc-4viewbag

How to return model to view that requires ViewData in .net core MVC?


I have .net core mvc application, which has two action methods inside post controller.

[HttpGet]
public async Task<IActionResult> Create()
{
  var hostAppGetQuery = new Application.Handlers.HostApps.Queries.List.Query();
  var platformGetQuery = new Application.Handlers.Platforms.Queries.List.Query();

  var hostApps = await _mediator.Send(hostAppGetQuery);
  var platforms = await _mediator.Send(platformGetQuery);

  ViewBag.hostApps = ((Application.Handlers.HostApps.Queries.List.Response) hostApps).Items;
  ViewBag.platforms = ((Application.Handlers.Platforms.Queries.List.Response) platforms).Items;

  return View();
}

above is get method which have two ViewBag Variables.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Models.InputModels.Posts.Create.Index model)
{
   if (!ModelState.IsValid)
   {
     return View(model);
   }

   var command = _mapper.Map<Application.Handlers.Posts.Commands.Create.Command>(model);

   var result = await _mediator.Send(command);

    return View();
}

above is post method to create post. i'm getting error here because not returning the viewbag variables in post action. But i'm little bit confused here. do i need to get and set viewbag variables every time post method is called ?? Is there any method to persist this data , without calling database every time?


Solution

  • You can use ViewData or TempData to persist your variables from one Controller action to another. You would use ViewBag when you want to return a value to your View. If you want to persist your TempData values for more requests you can use Peek and Keep functions. This answer can give more insight on these functions. In your case, you can do something like:

    [HttpGet]
    public async Task<IActionResult> Create()
    {
      var hostAppGetQuery = new Application.Handlers.HostApps.Queries.List.Query();
      var platformGetQuery = new Application.Handlers.Platforms.Queries.List.Query();
    
      var hostApps = await _mediator.Send(hostAppGetQuery);
      var platforms = await _mediator.Send(platformGetQuery);
    
      TempData["hostApps"] = ((Application.Handlers.HostApps.Queries.List.Response) hostApps).Items;
      TempData["platforms"] = ((Application.Handlers.Platforms.Queries.List.Response) platforms).Items;
    
      return View();
    }
    

    And your post method would look like:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(Models.InputModels.Posts.Create.Index model)
    {
       if (!ModelState.IsValid)
       {
         return View(model);
       }
    
       var command = _mapper.Map<Application.Handlers.Posts.Commands.Create.Command>(model);
    
       var result = await _mediator.Send(command);
    
       //Get your ViewData variables here
       if (TempData["hostApps"] != null)
       {
        var hostAppsResult = (((Application.Handlers.HostApps.Queries.List.Response) hostApps).Items) TempData["hostApps"];
            ...
       }
    
       //Get your ViewData variables here
       if (TempData["platforms"] != null)
       {
        var platformsResult = (((Application.Handlers.Platforms.Queries.List.Response) platforms).Items) TempData["platforms"];
            ...
       }
    
        return View();
    }
    

    You can read more about this topic in this article