gpt4 book ai didi

c# - 如何在每个 Controller Action 中使用异步 ViewModel?

转载 作者:太空宇宙 更新时间:2023-11-03 23:25:14 24 4
gpt4 key购买 nike

我是 asp.net mvc (5) 的新手,我的网站遇到了问题。

基本上,所有 aspnet_users 都通过 guid 链接到我的特定 user 表。

我有一个带有 UnitOfWorkViewModelBaseBaseController 类:

public class BaseController : Controller
{
protected UnitOfWork UnitOfWork { get; private set; }
public ViewModelBase ViewModel { get; set; }
}

(摘自)ViewModelBase 类,包含布局页面中所需的信息:

public class ViewModelBase
{
public User User { get; set; }
public bool IsAuthentified { get; set; }
public bool Loaded { get; set; }
}

以及使用它的布局:

@model Project.ViewModels.ViewModelBase
<html>
<body>
Some very cool layout stuff related to the User in the ViewModelBase
</body>
</html>

这是一个使用 HomeController 的例子:

public class HomeController : BaseController
{
private new HomeViewModel ViewModel
{
get { return (HomeViewModel)base.ViewModel; }
}

public HomeController()
{
ViewModel = new HomeViewModel();
}

public ActionResult Index()
{
// I need to get the MembershipUser here to retrieve the related User and set it in the ViewModel
return View(ViewModel);
}
}

HomeViewModel:

public class HomeViewModel : ViewModelBase
{
public string HomeSpecificProperty { get; set; }
}

和 View :

@model Project.ViewModels.HomeViewModel

@{
ViewBag.Title = "Home";
Layout = "~/Views/Shared/Layout.cshtml";
}

Welcome @Model.User.UserName !
<br />
@Model.HomeSpecificProperty

这是我的问题。问题是所有页面都有一个继承自 ViewModelBase 的 View 模型,因为它用于布局,但我不知道在哪里以及如何设置 User 属性它。由于 Membership 用于检索 User,它必须在 Action 中,我不能在 ViewModelBase< 中执行此操作 构造函数。

因此我在 BaseController 中添加了这段代码,它在第一个 get 上设置了 ViewModelBase 属性:

private ViewModelBase viewModel;

protected ViewModelBase ViewModel
{
get
{
if (!viewModel.Loaded)
LoadBaseContext();

return viewModel;
}
set { viewModel = value; }
}

private void LoadBaseContext()
{
viewModel.IsAuthentified = HttpContext.User.Identity.IsAuthenticated;

if (viewModel.IsAuthentified)
{
MembershipUser user = Membership.GetUser();
viewModel.Player = UnitOfWork.UserRepo.Get((Guid)user.ProviderUserKey);
}

viewModel.Loaded = true;
}

可能不是很漂亮,但是很管用。但是,由于其中有一些数据库访问(特别是获取 User),我想我应该将 LoadBaseContext 函数放在 async 中。我试过了,因为所有 Action 都使用 ViewModelBase 我也把每个 Action 都异步了。但是 @Html.ActionLink 不再起作用,因为调用的操作是 async

最后,我的问题是:ViewModelBaseUser 属性是正确的做法吗?如果是,LoadBaseContext 应该是异步的吗?那么,如何让它配合 Action 呢?

非常感谢。

更新

布局摘录:

@if (!Model.IsAuthentified)
{
@Html.Action("Index", "Authentification", null) // display login partial view
}
else
{
@Html.Action("Index", "UserInfos", null) // display userinfos partial view
}

Authentication controller Index 的 Action :

public ActionResult Index()
{
ViewModel = new AuthentificationViewModel();
// loads the ViewModelBase properties here
return PartialView("~/Views/Shared/Partials/Login.cshtml", ViewModel);
}

最佳答案

如果您在所有 View 中都有一些您一直想要的东西,您可以确保每个 View 都采用包含或扩展该核心数据集的 View 模型,或者您可以简单地把ViewBag 中的数据。

要执行后者,您可以覆盖基本 Controller 中的 OnActionExecuting,并在那里设置 ViewBag 内容。

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
this.ViewBag["IsAuthenticated"] = this.Request.IsAuthenticated;
// ...
}

如果您想要async 行为,那么您可以调整this post满足您的需求。

要在不覆盖 OnActionExecuting 的情况下执行此操作,您可以在 Controller 基类中放置一个 async 方法来设置 ViewBag 中的数据:

protected async virtual Task PopulateViewBag()
{
this.ViewBag["foo"] = await MyAsyncMethod();

// ...
}

...然后只需从您的每个 Controller 操作中调用它:

public async Task<ActionResult> MyAction()
{
await this.PopulateViewBag();

// ... more code
}

不过,这会有点乏味。

最后一句话:根据您希望拥有的用户数量等,获取用户信息一次,然后将其缓存(例如在Session),而不是在每次请求时重复获取它。大概大多数用户信息不会在请求之间改变......

关于c# - 如何在每个 Controller Action 中使用异步 ViewModel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34024050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com