Last active
December 12, 2015 04:39
-
-
Save mattanja/4716145 to your computer and use it in GitHub Desktop.
Typesafe viewmodel for MVC frameworks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@* For NancyFx - using ViewBase without generic parameter for basic view-model *@ | |
@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<ViewModel.ViewBase> | |
@* For ASP.NET MVC - using ViewBase without generic parameter for basic view-model *@ | |
@model ViewModel.ViewBase | |
@{ | |
// [...] | |
} | |
<!DOCTYPE html> | |
<head> | |
@* Full IntelliSense support and type-safety without dynamic types *@ | |
<title>@Model.Page.PreFixTitle @Model.Page.Title</title> | |
</head> | |
etc... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class BaseController : Controller { | |
/// <summary> | |
/// Setup default page model properties. | |
/// </summary> | |
protected ViewBase<TContent> GetDefaultModel<TContent>(ViewBase<TContent> model = null) where TContent : ContentBase | |
{ | |
if (model == null) | |
{ | |
model = new ViewBase<TContent>(); | |
} | |
var page = new PageBase() | |
{ | |
IsAuthenticated = this.Context.CurrentUser != null, | |
PreFixTitle = "prefix -", | |
CurrentUserName = this.Context.CurrentUser != null ? this.Context.CurrentUser.UserName : "", | |
Errors = new List<ErrorModel>() | |
}; | |
model.Page = page; | |
return model; | |
} | |
} | |
public class HomeController : BaseController { | |
public ActionResult Start() { | |
var model = this.GetDefaultModel<StartContent>(); | |
model.Page.Title = "Start"; | |
model.Content.Members = dbService.GetMembers(); // This is not using some dynamic but the generic content class. | |
return View(model); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@* For NancyFx *@ | |
@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<ViewModel.ViewBase<ViewModel.StartContent>> | |
@* For ASP.NET MVC *@ | |
@model ViewModel.ViewBase<ViewModel.StartContent> | |
@{ | |
Layout = "_Layout.cshtml"; | |
} | |
<h2>Home</h2> | |
<div>Start</div> | |
<ul> | |
@* Full IntelliSense support and type-safety without dynamic types *@ | |
@foreach (var member in Model.Content.Members) { | |
<li>@member.Email</li> | |
} | |
</ul> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Base view model for the layout. | |
/// </summary> | |
public class ViewBase { | |
public PageBase Page { get; set; } | |
} | |
/// <summary> | |
/// Generic view model to include the view model for the view. | |
/// </summary> | |
/// <typeparam name="TContent"></typeparam> | |
public class ViewBase<TContent> : ViewBase where TContent : ContentBase | |
{ | |
public TContent Content { get; set; } | |
} | |
/// <summary> | |
/// Base view model for settings of the page and layout. | |
/// </summary> | |
public class PageBase | |
{ | |
public String Title { get; set; } | |
public String PreFixTitle { get; set; } | |
public bool IsAuthenticated { get; set; } | |
public List<ErrorModel> Errors { get; set; } | |
public string CurrentUserName { get; set; } | |
} | |
/// <summary> | |
/// Base class for the content of a view (generic parameter of ViewBase). | |
/// </summary> | |
public abstract class ContentBase | |
{ | |
} | |
/// <summary> | |
/// Sample content view model. | |
/// </summary> | |
public class StartContent : ContentBase | |
{ | |
public List<Mail.Member> Members { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment