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

标签 c# asp.net-mvc asynchronous viewmodel

我是 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/

相关文章:

ios - 等待异步执行的 block 的iOS(或RubyMotion)惯用法是什么?

c# - 选择正确的报告工具

asp.net-mvc - Azure 网站 - 高延迟

asp.net-mvc - mvc4 new { vs 新对象{

c# - Bootstrap 类不能与 View 中的 HTML 控件一起使用

javascript - 多次调用实习生异步回调

java - 需要解释 : how to use AsyncTask?

c# - 无法在 Firefox 中读取 ashx 中的 session 变量值?

c# - 通用 Windows 平台中找不到文件异常

c# - YouTube 上的教程正在使用 CInt 虽然它不存在