简体   繁体   English

在asp.net mvc 5中进一步说明将数据从控制器传递到布局子视图

[英]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. 我想我有一个非常标准的问题,因为我想将某些数据从asp.net MVC 5控制器传递到共享视图(在我的情况下为导航)。

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. 布局是主视图,当然,我还有其他视图,例如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. 我的项目有一个用户可以访问的漂亮的MVC应用程序。 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. 一旦他登录到MVC应用程序,便会根据从中获取数据的同一个webapi对用户进行身份验证,并存储访问令牌以及其他用户详细信息以供进一步请求。 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. 据我了解,选项将是Cookies,会话和本地存储。 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. 由于我对asp.net,MVC和C#刚起步,所以我还没有弄清楚如何在MVC应用程序中使用[Authorize]属性,因此它可以将用户标记为已通过身份验证:/我猜这是关键问题在于MVC应用程序无权访问数据库,因此无法检查登录名并填充用户标识。

How to transfer data from controller to view: 如何从控制器传输数据到视图:

ViewBag: The easiest way of passing data to the view. ViewBag:将数据传递到视图的最简单方法。 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. 有人告诉我使用它是一种不好的做法,并建议使用viewModels。

ViewData: seems to be kind of the same thing as viewdata. ViewData:似乎和viewdata一样。

ViewModel: A strongly typed model that is passed to the view and needs to be declared in any view that uses it. ViewModel:传递给视图的强类型模型,需要在使用它的任何视图中声明。 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. 这种方法的最大缺点是,每个视图模型都需要具有一个baseViewModel,因此它们具有共同的结构,这种结构显然会在以后引起问题,并阻止我继承其他模型来填充我的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 Cookies:很明显,我可以在登录期间将数据存储在cookie中,然后在视图中访问它们,但是cookie必须存在,因此我将无法将该信息保存在会话或本地存储中

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. LocalStorage:这对我来说是很新的,所以我无法判断。

User Identity: I just discovered that I can also access the user's identity from Context.User.Identity. 用户身份:我刚刚发现我还可以从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). 像[Authorize]属性或自定义属性之类的全局过滤器:如果我正确理解它,使用全局过滤器,我可以在每个控制器操作中自动填充所需的数据,并排除不需要的数据(如登录/注册等)。由于我的项目结构,目前还不确定如何应用这种方式(请参见上文)。

RenderAction: I could also call another controller method via the RenderAction helper method to always render that section of the page. RenderAction:我也可以通过RenderAction帮助器方法调用另一个控制器方法,以始终呈现页面的该部分。

How do you guys solve this problem? 你们如何解决这个问题? If you need more clarification, please do ask. 如果您需要更多说明,请询问。

Thanks :) 谢谢 :)

Use a base ViewModel. 使用基本的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 . 我不确定使用此方法会遇到什么问题,但我建议使用强类型化,可维护的视图模型的好处来弥补这些问题,这些模型可用于所有视图,包括部分视图和_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(...) {
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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