Best way to generate global ViewData?

I have a section of my site that requires global data for navigation, now I am doing the following inside the attribute:

ViewData["projects"] = new[]
{
    new ProjectNav { Id = 1, Name = "Big project in New York" },
    new ProjectNav { Id = 2, Name = "Small project in New Jersey" },
    new ProjectNav { Id = 3, Name = "Big project in Florida" },
}

Then I mark up my controller methods as follows:

[ProjectNav]
public ActionResult Index() 
{
     // strongly typed view returned here
}

And, in my opinion, I would do something like this:

<% foreach (ProjectNav project in (IEnumerable<ProjectNav>)ViewData["projects"]) 
{ %>
// Enumerate here
<% } %>

This works, but is there a way to do this in a more strongly typed way? The only thing I can think of is to create a Dto with ProjectNav material as a member, but then you create a separate Dto for each of the controller methods, and that is definitely NOT DRY. Is there a better way to do this that I'm just missing?

+3
source share
5 answers

NavigationController RenderAction RenderPartial ( ).

+2

ViewModel Projects .

OnResultExecuted ActionFilter. OnResultExecuted (filterContext.Controller.ViewData.Model). , ViewModel. , .

Projects ActionFilter.

, ViewModel... if (model is IDisplayProjects) ....

+1

, , ? , , .

0

Session , . , , . , .

, - ( GetProjects ):

<% if(Session["projects"] == null)
{
   Session["projects"] = DataManager.GetProjects();
}%>

<% foreach (ProjectNav project in (IEnumerable<ProjectNav>)Session["projects"]) 
{ %>
     // Enumerate here
<% } %>

, . , .

0
source

Using child actions is a much better solution. So you should start by defining a controller:

public class ProjectsController: Controller
{
    public ActionResult Index()
    {
        var projects = new[]
        {
            new ProjectNav { Id = 1, Name = "Big project in New York" },
            new ProjectNav { Id = 2, Name = "Small project in New Jersey" },
            new ProjectNav { Id = 3, Name = "Big project in Florida" },
        };
        return View(projects);
    }
}

And then we get a strongly typed fragment that will display them ( ~/Views/Projects/Index.ascx) and finally include this in your main view:

<%= Html.Action("index", "projects") %>

Thus, you do not need to decorate all the actions of your controller with attributes. Just enable the action you need using the assistant Html.Action.

0
source

Source: https://habr.com/ru/post/1779854/


All Articles