ASP.NET MVC persistent data and code organization
I'm giving开发者_运维技巧 MVC another shot, and I feel like I'm learning freakin' HTML all over again.
So, stupid question: At the top of my master page, I've got a partial view (or similar - I'm using the string template view engine and so far I love it) which either displays a small login form (similar to what NewEgg has), or a message like
You are signed in as (Name). [Profile] | [Sign out]
Unfortunately, I'm having a brain cramp and can't determine the best way to get that data (username, id) into the ViewData collection without explicitly specifying it in every controller method, like
public ActionResult Index()
{
ViewData["IsAuthenticated"] = Session["IsAuthenticated"];
ViewData["user.firstname"] = User.FirstName;
return View("login");
}
That's pretty annoying to have to replicate all over the place. My next option would be to create a method called PopulateCommonViewData() and just call that from every action method, but that also seems lousy.
Am I missing something here?
Derive your controllers from a base controller. Then move your method creating common view data into the OnActionExecuting/OnActionExecuted override in that base controller.
public class BaseController : Controller
{
public override void OnActionExecuting( ActionExecutingContext filterContext )
{
ViewData["IsAuthenticated"] = Request.IsAuthenticated;
ViewData["user.firstname"] = User.FirstName;
}
}
public class MyController : BaseController // and you're done
{
...
}
I would use ASP.NET membership and just check state and get info from the page context methods in the masterpage. Makes it simple!
Couple of options off the top of my head, use a common base controller that all your controllers inherit from which adds the info in the OnActionExecuting method/override or you could possibly use an action filter if it is not required globally...
How about a base ViewModel class which gets injected with the IUserContext & all the other ViewModels in the application derive from this ViewModel?
Somehow, I am not comfortable with the concept of doing: ViewData["magic_string"] = "magic"; pattern recommended here...
Perhaps I am missing a point & would love to know what?
HTH
Do not put these data in ViewData or model at all, and store it in static properties. These static properties could wrap Session or Application state, the ASP.NET cache or the request context bag, whatever is appropriate. So you do not clutter your controller with this kind of global stuff.
Two approaches I could see taking here. One is to use custom action filter attributes to get the data you need into the view model after your controller action executes (the OnResultExecuted method on ActionFilterAttribute would probably do it).
The other is to utilize a base controller class, and override the OnActionExecuted method there.
Since it sounds like you are going to want this on all pages, it seems the latter option would be less maintenance going forward.
精彩评论