简体   繁体   中英

further clarification about passing data from controller to layout sub view in asp.net mvc 5

I guess I have a pretty standard problem as I want to pass certain data from an asp.net MVC 5 controller to a shared view, in my case navigation.

I have a template that shows username and userpicture in the navigation shared view, so I need to pass the respective data to it.

My layout structure:

  • Shared\\Layout
  • Shared\\Header
  • Shared\\Navigation
  • %Body%
  • Shared\\Footer

Where the Layout ist the master view and of course I also have my other views like Home\\Index. As you can imagine, I have to show the username and his userpicture in every view except the login/registration or any error views. These views do not use the layout at all, so everytime a view is rendered using the layout structure, the user is already logged in.

So I was researching about ways to pass data from my controller to the navigation view, although my controller returns the Index view and would appreciate some clarification on their disadvantages and valid choices in my use case:

Use case:

My project has a pretty dumb MVC application that the user can access. Once he logs into the MVC app authenticates the user against the same webapi where it get's it's data from and stores the access token as well as other user details for further requests. I'm not yet sure where to store that data. As far as I understand it, the options would be Cookies, Session and local storage. As I am pretty new to asp.net, MVC and C# in general, I didn't yet figure out how to make the [Authorize] Attribute work inside the MVC app so it can mark the user as authenticated :/ I guess the key problem is that the MVC app does not have access to the database and therefore cannot check the login and populate the User Identity.

How to transfer data from controller to view:

ViewBag: The easiest way of passing data to the view. It is not strongly typed and can be accessed in all views. I was told it is kind of a bad practise to use it and was advised to use viewModels.

ViewData: seems to be kind of the same thing as viewdata.

ViewModel: A strongly typed model that is passed to the view and needs to be declared in any view that uses it. So if I want to use it in my navigation view, I'd need to declare it there. The big disadvantage of this approach is that every viewmodel needs to have kind of a baseViewModel so they have a common structure which appearently can cause problems later down the road and also prevents me from inheriting other models to populate my viewModelStructure.

Cookies: Obviously I can store data in cookies during login and then access them in the view, but the cookies HAVE to be there so I would not be able to save this information in the session or local storage

Session: I can also store data in the session, but the session expires when the user closes the browser tab.

LocalStorage: This is pretty new to me so I can't judge it.

User Identity: I just discovered that I can also access the user's identity from Context.User.Identity.

Global Filter like the [Authorize] attribute or a custom one: If I understand it correctly, with a global filter I can populate needed data automatically in every controller action and exclude the ones that dont need it like Login/register etc. I'm not yet sure how to apply this way because of my project structure (see above).

RenderAction: I could also call another controller method via the RenderAction helper method to always render that section of the page.

How do you guys solve this problem? If you need more clarification, please do ask.

Thanks :)

Use a base ViewModel. You can still use inheritance to build up functionality in your view models, they'll all just share a common base view model, as you said.

I'm not sure what problems you envisage with this approach, but I would suggest they're outweighed by the benefit of strongly typed, maintainable view models, that can be used by all your views, including partial views and _Layout .

A suggestion to get you started based on your layout structure:

public abstract class ViewModelBase {
    public HeaderViewModel Header {get;}
    public NavigationViewModel Navigation {get;}
    public FooterViewModel Footer {get;}

    public ViewModelBase(HeaderViewModel header, NavigationViewModel navigation, FooterViewModel footer) {
        Header = header;
        Navigation = navigation;
        Footer = footer;
    }
}

public class HeaderViewModel {
    // properties

    public HeaderViewModel(...) {
    }
}

public class NavigationViewModel {
    // properties

    public NavigationViewModel(...) {
    }
}

public class FooterViewModel {
    // properties

    public FooterViewModel(...) {
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM