![](/img/trans.png)
[英]How to pass viewModel string value with umlauts/special characters to controller action
[英]How to use asynchronous ViewModel in every controller action?
我是asp.net mvc(5)的新手,我在我的網站上遇到了一個問題。
基本上,所有aspnet_users
都通過guid
鏈接到我的特定user
表。
我有一個帶有UnitOfWork
和ViewModelBase
的BaseController
類:
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; }
}
並且觀點:
@model Project.ViewModels.HomeViewModel
@{
ViewBag.Title = "Home";
Layout = "~/Views/Shared/Layout.cshtml";
}
Welcome @Model.User.UserName !
<br />
@Model.HomeSpecificProperty
這是我的問題。 事情是所有頁面都有一個從ViewModelBase
繼承的viewmodel,因為它在布局中使用,但我不知道在哪里以及如何在其中設置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
。 我試過了,因為所有動作都使用ViewModelBase
所以我也把每個動作都設置為異步。 但是,由於調用的操作是async
因此@Html.ActionLink
不再起作用。
最后,我的問題是:這個ViewModelBase
和User
屬性是否正確? 如果是, LoadBaseContext
應該是異步的嗎? 然后,如何讓它與行動一起工作?
非常感謝。
UPDATE
布局提取:
@if (!Model.IsAuthentified)
{
@Html.Action("Index", "Authentification", null) // display login partial view
}
else
{
@Html.Action("Index", "UserInfos", null) // display userinfos partial view
}
認證控制器索引的行動:
public ActionResult Index()
{
ViewModel = new AuthentificationViewModel();
// loads the ViewModelBase properties here
return PartialView("~/Views/Shared/Partials/Login.cshtml", ViewModel);
}
如果您在所有視圖中都有所需的內容,則可以確保每個視圖都采用包含或擴展該核心數據集的視圖模型, 或者您可以簡單地將數據放入ViewBag
。
要執行后者,您可以在基本控制器中覆蓋OnActionExecuting
,並在那里設置ViewBag
內容。
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
this.ViewBag["IsAuthenticated"] = this.Request.IsAuthenticated;
// ...
}
如果您想要async
行為,那么您可以根據需要調整此帖子 。
要在不重寫OnActionExecuting
情況下執行此操作,可以在控制器基類中放置一個async
方法,以設置ViewBag
的數據:
protected async virtual Task PopulateViewBag()
{
this.ViewBag["foo"] = await MyAsyncMethod();
// ...
}
...然后只需從您的每個控制器操作中調用它:
public async Task<ActionResult> MyAction()
{
await this.PopulateViewBag();
// ... more code
}
不過,這會有點單調乏味。
最后一句話:取決於您期望擁有多少用戶等,可能更容易獲取用戶信息一次 ,然后將其緩存(例如在Session
),而不是在每次請求期間反復獲取。 據推測,大多數用戶信息不會在請求之間發生變化......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.