Asp.net mvc 视图和布局的Asp.net MVC模型
我一直在试图找到一个好方法来处理我们的Asp.NETMVC网站的模型,当所有页面都有公共属性时。这些属性将显示在布局(母版页)中。我正在使用一个“BaseModel”类来保存这些属性,我的布局使用这个BaseModel作为它的模型 其他每个模型都继承自该BaseModel,并且每个模型都具有与其表示的视图相关的特定属性。正如您可能已经猜到的,我的模型实际上是视图模型,即使这在这里不太相关 我尝试了不同的方法来初始化BaseModel值Asp.net mvc 视图和布局的Asp.net MVC模型,asp.net-mvc,Asp.net Mvc,我一直在试图找到一个好方法来处理我们的Asp.NETMVC网站的模型,当所有页面都有公共属性时。这些属性将显示在布局(母版页)中。我正在使用一个“BaseModel”类来保存这些属性,我的布局使用这个BaseModel作为它的模型 其他每个模型都继承自该BaseModel,并且每个模型都具有与其表示的视图相关的特定属性。正如您可能已经猜到的,我的模型实际上是视图模型,即使这在这里不太相关 我尝试了不同的方法来初始化BaseModel值 在每个视图中“手动” 有一个基本控制器,它有一个初始化虚拟方
[Model(typeof(HomeModel))]
public ActionResult Index()
{
var homeModel = TempData["model"] as HomeModel;
// Add View Specific stuff
return View(homeModel);
}
它给了我世界上最好的东西。唯一的缺点是找到一种正确的方法将模型传递回操作
这里是使用TimDATA对象完成的,但我也考虑更新ActoMealth.
中可以找到的模型。对于这一点,我仍然在接受任何严肃的建议/提示/建议/模式/建议,或者前面的几点。我经历的过程与我跳入MVC的过程几乎完全相同。你是对的,没有一个解决方案感觉那么好 最后,我使用了一系列基本模型。出于各种原因,我有几种不同类型的基本模型,但逻辑应该应用于单个基本类型。然后,我的大多数视图模型继承自其中一个基础。然后,根据需要/时间,我在
ActionExecuting
或onactionexecutive
中填充模型的基本部分
我的一段代码应该可以让流程变得清晰:
if (filterContext.ActionParameters.ContainsKey("model")) {
var tempModel = (System.Object)filterContext.ActionParameters["model"];
if (typeof(BaseModel_SuperLight).IsAssignableFrom(tempModel.GetType())) {
//do stuff required by light weight model
}
if (typeof(BaseModel_RegularWeight).IsAssignableFrom(tempModel.GetType())) {
//do more costly stuff for regular weight model here
}
}
最后,我的模式感觉不太令人满意。然而,它是实用的、灵活的,并且易于实现不同级别的继承。我还能够在控制器执行之前或之后注入执行,这在我的案例中非常重要。希望这能有所帮助。让我@EBarr使用动作过滤器的想法实际上是可行的,但最终感觉是错误的,因为在不通过viewbag或httpcontext项或类似内容的情况下,没有干净的方法检索模型。此外,它还强制要求用它的模型装饰每个动作。这也使得回发更加难以处理。我仍然相信这种解决方案有其优点,在某些特定情况下可能会有用 所以我回到原点,开始更多地研究这个话题。我来到了下面。首先,问题有两个方面
public interface IViewModel
{
KeyValuePair<string, PartialViewData>[] Sections { get; }
}
public class PartialViewData
{
public string PartialViewName { get; set; }
public object PartialViewModel { get; set; }
public ViewDataDictionary ViewData { get; set; }
}
实际的解决方案有更多的代码,我在这里试图简化以获得想法。它仍然有点粗糙,需要抛光/错误处理,但有了它,我可以在我的操作中定义,这些部分将是什么,它们将使用什么模型等等。它可以很容易地进行测试,设置DI不应该是一个问题
我仍然必须在每个视图中复制@section行,这似乎有点痛苦(特别是因为我们不能将这些部分放在局部视图中)
我正在调查,看看这是否能取代这些章节。感谢您的反馈。虽然它与我想要的不完全匹配(您的解决方案是3的不同实现)
public interface IViewModel
{
KeyValuePair<string, PartialViewData>[] Sections { get; }
}
public class PartialViewData
{
public string PartialViewName { get; set; }
public object PartialViewModel { get; set; }
public ViewDataDictionary ViewData { get; set; }
}
public class HomeViewModel : IViewModel
{
public Article[] Articles { get; set; } // Article is just a dummy class
public string QuickContactMessage { get; set; } // just here to try things
public HomeViewModel() { Articles = new Article[0]; }
private Dictionary<string, PartialViewData> _Sections = new Dictionary<string, PartialViewData>();
public KeyValuePair<string, PartialViewData>[] Sections
{
get { return _Sections.ToArray(); }
set { _Sections = value.ToDictionary(item => item.Key, item => item.Value); }
}
}
public ActionResult Index()
{
var hvm = ModelFactory.Get<HomeViewModel>(); // Does not much, basicaly a new HomeViewModel();
hvm.Sections = LayoutHelper.GetCommonSections().ToArray(); // more on this just after
hvm.Articles = ArticlesProvider.GetArticles(); // ArticlesProvider could support DI
return View(hvm);
}
public class DefaultLayoutHelper
{
private Controller Controller;
public DefaultLayoutHelper(Controller controller) { Controller = controller; }
public Dictionary<string, PartialViewData> GetCommonSections(QuickContactModel quickContactModel = null)
{
var sections = new Dictionary<string, PartialViewData>();
// those calls were made in methods in the solution, I removed it to reduce the length of the answer
sections.Add("header",
Controller.UserLoggedIn() // simple extension that check if there is a user logged in
? new PartialViewData { PartialViewName = "HeaderLoggedIn", PartialViewModel = new HeaderLoggedInViewModel { Username = "Bishop" } }
: new PartialViewData { PartialViewName = "HeaderNotLoggedIn", PartialViewModel = new HeaderLoggedOutViewModel() });
sections.Add("quotes", new PartialViewData { PartialViewName = "Quotes" });
sections.Add("quickcontact", new PartialViewData { PartialViewName = "QuickContactForm", PartialViewModel = model ?? new QuickContactModel() });
return sections;
}
}
@section quotes { @{ Html.RenderPartial(Model.Sections.FirstOrDefault(s => s.Key == "quotes").Value); } }
@section login { @{ Html.RenderPartial(Model.Sections.FirstOrDefault(s => s.Key == "header").Value); } }
@section footer { @{ Html.RenderPartial(Model.Sections.FirstOrDefault(s => s.Key == "footer").Value); } }