如何在我的MVC _Layout视图中提供数据

时间:2015-11-28 13:12:48

标签: c# asp.net-mvc asp.net-mvc-4 layout viewmodel

我的_Layout使用BaseViewModel在导航栏中呈现用户名,我想通过该应用程序保持一致。我的HomeController上有一个名为Login的操作,在成功登录后会将UserViewModel传递到Dashboard视图。 UserViewModelBaseViewModel派生,仅在仪表板视图中使用。

我的问题是如何使_Layout页面使用的BaseViewModel在应用程序的整个视图中可用。每次页面加载时,是否必须继续调用我的服务(数据库)来获取此数据?因为BaseViewModel所需的数据仅在Login的{​​{1}}操作中获取,因此如果我导航到另一个视图,页面会中断,我会在下面看到此错误

HomeController

BaseViewModel.cs

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[InventoryManager.Web.Models.ProductViewModel]', but this dictionary requires a model item of type 'InventoryManager.Web.Models.BaseViewModel'.

UserViewModel

public class BaseViewModel
{
    public string FirstName { get; set; }

    public string LastName { get; set; }
}

BaseController

public class UserViewModel : BaseViewModel
{
    public Guid UserId { get; set; }

    public string Username { get; set; }

    public string Password { get; set; }
}

的HomeController

public class BaseController : Controller
{
    //
    // GET: /Base/

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        var model = filterContext.Controller.ViewData.Model as BaseViewModel;
    }
}

2 个答案:

答案 0 :(得分:1)

我通常做的是创建一个LayoutController。使用此控制器,我将呈现布局页面上使用的所有持久性信息。

public class LayoutController : Controller
{
    private readonly IProvideData _provider;

    public LayoutController(IProvideData provider)
    {
        _provider = provider;
    }

    [ChildActionOnly]
    public ActionResult AccountInformation()
    {
        var model = _provider.GetUserStuff();
        return PartialView("_AccountInformation", model);
    }
}

ChildActionOnly属性确保只能从视图中调用操作方法作为子方法。在_Layout.cshtml我可以使用以下内容呈现此操作:

@{ Html.RenderAction("AccountInformation", "Layout"); }

这会呈现_AccountInformation部分视图,如下所示:

@model MyApplication.ViewModels.UserInformation
Username: @Model.UserName

答案 1 :(得分:0)

您可以保留UserViewModelBaseViewModel并使用合成功能向您的View发送兼容类型,并避免错误,如下所示。这种方法使用所谓的对象组合

见下文,创建AppViewModel

public class AppViewModel
{
  public UserViewModel UserViewModel { get; set; }
  public List<ProductViewModel> ProductViewModel { get; set; }
}

//登录操作方法或任何操作方法

填充AppViewModel以发送到视图

public class HomeController {
    //Action method
      public ActionResult Login(LoginViewModel model)
      {
        //Do stuff and populate AppViewModel

         UserViewModel userViewModel = new UserViewModel {Username = "username", Password ="secret", FirstName = "John", LastName = "Doe"};
         AppViewModelmodel model = new AppViewModel{UserViewModel = userViewModel };
         return RedirectToAction("Index", "Dashboard", model);
      }
}

// ProductController

public class ProductController
{
  public ActionResult Products()
  {
    ProductViewModel productViewModel = new ProductViewModel { /*Initialize properties here*/};
    AppViewModel model = AppViewModel { ProductViewModel  = new List<ProductViewModel>{ new ProductViewModel =  productViewModel }};
    return View(model);
  }
}

//仪表板视图

// Do include your model namespace
@model AppViewModel 
<div>
   <p> FirstName : @Model.UserViewModel.FirstName</p>
</div>

//产品视图

// Do include your model namespace
@model AppViewModel 
<div>
   //You get the idea
   <p> Product Name: @Model.ProductViewModel.Select( x => x.ProductName).       </p>
</div>