ASP.NET MVC: How to default to a page given certain condition? - c#

I have a class called PasswordChangeChecker.csthat has a method that returns from the database whether or not a user has changed their password. The signature for that method is:
public bool IsPasswordChangedFromInitial(string IdOfUser)
where IdOfUser is the Id field from the Identity framework User. If it returns true, that means the change password page should not be displayed, otherwise, it should navigate to the change password form. Once the user successfully changes their password, the database flag gets set appropriately, and they should not be prompted for a password change again (unless manually forced to by an admin). How can I put this method in the RouteConfig.cs file, where currently I have:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace IdentityDevelopment
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
How can I add a conditional construct into the defaults parameter so I can use the IsPasswordChangedFromInitial method to decide whether or not to go to the password change page? That page is at /Account/ChangePassword.
EDIT
As per the comments, the appropriate action methods for my specific need are (I have omitted irrelevant code):
Login post action:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginModel details, string returnUrl)
{
if (ModelState.IsValid)
{
AppUser user = await UserManager.FindAsync(details.Name,
details.Password);
if (user == null)
{
AppUser userByName = await UserManager.FindByNameAsync(details.Name);
if(userByName == null)
{
ModelState.AddModelError("", "Invalid username.");
}
else
{
//If this else is reached, it means the password entered is invalid.
//code for incrementing count of failed attempts and navigation to lock out page if needed
}
}
else
{
if(user.LockedOut)
{
//navigate to locked out page
}
else
{
PasswordChangeChecker PassCheck = new PasswordChangeChecker();
string userId = user.Id.ToString();
bool proceed = PassCheck.IsPasswordChangedFromInitial(userId);
//Authorize the user
ClaimsIdentity ident = await UserManager.CreateIdentityAsync(user,
DefaultAuthenticationTypes.ApplicationCookie);
ident.AddClaims(LocationClaimsProvider.GetClaims(ident));
ident.AddClaims(ClaimsRoles.CreateRolesFromClaims(ident));
AuthManager.SignOut();
AuthManager.SignIn(new AuthenticationProperties
{
IsPersistent = false
}, ident);
//persist login into db code
if (proceed)
{
//reset failed logins count
return Redirect(returnUrl);
}
else
{
return ChangePassword();
}
}
}
}
ViewBag.returnUrl = returnUrl;
return View(details);
}
ChangePassword() get action:
[HttpGet]
[Authorize]
public ActionResult ChangePassword()
{
return View();
}
Somehow the view returned is the view in the RouteConfig.cs instead of the ChangePassword.cshtml page.
Thank you.

I would do it with global action filters
you can make a action filter with method
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (showChagePwPage)
{
//redirect to the change password page
filterContext.Result = new RedirectToActionResult("ChangePassword", "Account");
}
base.OnActionExecuting(filterContext);
}
and then adding it into global action filter by
GlobalFilters.Filters.Add(yourFilterContext);

After several days of this hellish exercise similar to yours, where I was trying to route users at login, I realized that I wasn't going to be able to get the value of the UserId while in the login of the Account controller. I did some experimenting and came up with this approach that solved my problem.
I create an ActionResult in my Home controller and called it Purgatory (of course I renamed it to something more suitable once it proved functional). There, I stuffed all my login logic for routing the logged-in user to their respective page upon login.
Then, in the RedirectToLocal in Account controller, I changed the
return RedirectToAction("Index", "Home");
to
return RedirectToAction("Purgatory", "Home");
So now when a user logs in, if the returnTo param isn't set to a particular page, the returnTo param will be null and when it gets to the RedirectToLocal, it'll drop to what used to be the redirect to the home page, which will now go into purgatory.

This sounds like a good time to use an action filter, which you can apply globally or per controller/action.
Here's a simple example:
using System;
using System.Web.Mvc;
using System.Web.Routing;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class VerifyPasswordChangedAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if(!filterContext.ActionDescriptor.ActionName.Equals("changepassword", StringComparison.OrdinalIgnoreCase))
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
var userName = filterContext.HttpContext.User.Identity.Name;
PasswordChangeChecker PassCheck = new PasswordChangeChecker();
if (!PassCheck.IsPasswordChangedFromInitial(userName))
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "account", action = "changepassword", area = string.Empty }));
}
}
}
base.OnActionExecuting(filterContext);
}
}
I would modify your IsPasswordChangedFromInitial method to simply use the authenticated user's username, rather than trying to figure out how to get access to a UserManager instance in an action filter. Otherwise, assuming you're using the OWIN-based ASP.NET Identity, add a claim to store that user.Id field when you create your ClaimsIdentity, so that you don't have to keep looking it up.
The outermost conditional handles the case of this being a global filter - without it, you would get an infinite redirect.

Related

ASP.NET MVC conditional routing

In my MVC Application I have my routes defined as follows:
routes.MapRoute(
"Category_default",
"{lang}/Category/{categoryid}/{controller}/{action}/{id}",
new { lang = "en", action = "Index", id = UrlParameter.Optional, categoryid = -1 }
).DataTokens.Add("area", "Category");
routes.MapRoute(
name: "Default",
url: "{lang}/{controller}/{action}/{id}",
defaults: new { controller = "home", action = "index", lang = "en", id = UrlParameter.Optional }
);
The application works fine. However, the system administrator just brought to my knowledge that those users who don't have access to the category (in other words, they are logically not associated with it) can also see the data just by switching the categoryid parameter, which is no surprise since I haven't put any check there.
What's the efficient way of checking if the user has privileges over this category or not. In the system I have a User object with User.AllowedCategories List which contains integer values of all the ids the user has access to.
The category area has about 20 controllers (therefore 20 views). Should I put a logic to check on every view? Or I can do it with minimum coding / or can I put this logic globally?
You can achieve that in 3 ways,
Method 1: Global Filters
In FilterConfig.cs:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ValidateUserFilter());
}
In ValidateUserFilter.cs
public class ValidateUserFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//Controllers to avoid validation
if ((new[] { "<<CONTROLLER1>>", "<<CONTROLLER2>>" }).Any(x => x == filterContext.ActionDescriptor.ControllerDescriptor.ControllerName))
{
return;
}
if (!User.AllowedCategories.Any(x => x == FilterContext.RequestContext.RouteData.Values["id"]))
{
//Redirect user to unauthorized page.
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "Controller", "<<CONTROLLER_NAME>>" }, { "Action", "<<ACTION_NAME>>" } });
}
}
}
Method 2: FilterAttribute
public class ValidateControllerAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (!User.AllowedCategories.Any(x => x == filterContext.RequestContext.RouteData.Values["id"]))
{
//Redirect user to unauthorized page.
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "Controller", "<<CONTROLLER_NAME>>" }, { "Action", "<<ACTION_NAME>>" } });
//OR, You can redirect to 403 response
//throw new HttpException((int)System.Net.HttpStatusCode.Forbidden, "You do not have permission to view this page");
}
}
}
You have to add this attribute in every controller which you want to
validate
Ex:
[ValidateController]
public class MyControllerController : Controller
Method 3: ActionMethodSelectorAttribute
public class ValidateActionAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (!User.AllowedCategories.Any(x => x == controllerContext.RequestContext.RouteData.Values["id"]))
{
//Redirect user to unauthorized page.
controllerContext.HttpContext.Response.Clear();
controllerContext.HttpContext.Response.Redirect("~/<<CONTROLLER_NAME>>/<<ACTION_NAME>>");
return false;
//OR, You can redirect to 403 response
//throw new HttpException((int)System.Net.HttpStatusCode.Forbidden, "You do not have permission to view this page");
/*OR,
controllerContext.HttpContext.Response.StatusCode = 403;
return true;*/
}
}
}
You have to add this attribute in every action which you want to
validate
Ex:
[ValidateAction]
public ActionResult Index()
{
return View();
}
If I got it right, essentially the problem is that, unauthorized user is able to access parts of application, which it should not.
You can use Authorize attribute on your action methods, OR on the Controller class, depending on what areas you want to have authorization. If your design allows, you can also consider creating a base controller and apply Authorize attribute on that, if you do not want repetitions.
Now specify the valid users for these controllers, using Roles OR Users parameters
[Authorize(Roles = "Valid Roles", Users = "Valid Users")]
If the default Authorize attribute doesn't suffice your needs you can always create your own custom attribute for authorization.

Authorization with Session variables in asp net mvc 5

So my project requirements changed and now I think I need to build my own action filter.
So, this is my current login controller:
public class LoginController : Controller
{
// GET: Login
public ActionResult Index()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model)
{
string userName = AuthenticateUser(model.UserName, model.Password);
if (!(String.IsNullOrEmpty(userName)))
{
Session["UserName"] = userName;
return View("~/Views/Home/Default.cshtml");
}
else
{
ModelState.AddModelError("", "Invalid Login");
return View("~/Views/Home/Login.cshtml");
}
}
public string AuthenticateUser(string username, string password)
{
if(password.Equals("123")
return "Super"
else
return null;
}
public ActionResult LogOff()
{
Session["UserName"] = null;
//AuthenticationManager.SignOut();
return View("~/Views/Home/Login.cshtml");
}
}
And this is my action filter attempt:
public class AuthorizationFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (HttpContext.Current.Session["UserName"] != null)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary{{ "controller", "MainPage" },
{ "action", "Default" }
});
}
base.OnActionExecuting(filterContext);
}
}
I have already added it to FilterConfig, but when I login it does not load Default.cshtml it just keeps looping the action filter. The action result for it looks like this:
//this is located in the MainPage controller
[AuthorizationFilter]
public ActionResult Default()
{
return View("~/Views/Home/Default.cshtml");
}
So, what would I need to add in order to give authorization so only authenticated users can view the applicationĀ“s pages? Should I use Session variables or is there another/better way of doing this using? I am pretty much stuck with AuthenticateUser(), since what happens there now is just a simple comparison like the one we have there now.
Thank you for your time.
Create an AuthorizeAttribute with your logic in there:
public class AuthorizationFilter : AuthorizeAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
{
// Don't check for authorization as AllowAnonymous filter is applied to the action or controller
return;
}
// Check for authorization
if (HttpContext.Current.Session["UserName"] == null)
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
As long as you have the Login URL Configured in your Startup.Auth.cs file, it will handle the redirection to the login page for you. If you create a new MVC project it configures this for you:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(
new CookieAuthenticationOptions {
// YOUR LOGIN PATH
LoginPath = new PathString("/Account/Login")
}
);
}
}
Using this you can decorate your controllers with [AuthorizationFilter] and also [AllowAnonymous] attributes if you want to prevent the authorization from being checked for certain Controllers or Actions.
You might want to check this in different scenarios to ensure it provides tight enough security. ASP.NET MVC provides mechanisms that you can use out of the box for protecting your applications, I'd recommend using those if possible in any situation. I remember someone saying to me, if you're trying to do authentication/security for yourself, you're probably doing it wrong.
Since your attribute is added to the FilterConfig, it will apply to ALL actions. So when you navigate to your MainPage/Default action it will be applying the filter and redirecting you to your MainPage/Default action (and so on...).
You will either need to:
remove it from the FilterConfig and apply it to the appropriate actions / controllers
or add an extra check in the filter so that it doesn't redirect on certain routes

Defining role-based default routing in .NET MVC

I'm surprised I haven't come across this before, but I'm attempting to find a way to redirect to the default route post-authentication based on a user's role.
To set up an example, let's say there are two roles, Admin and Tester. An Admin's default route should be admin/index and the AdminController shouldn't be accessible to a Tester. A Tester's default route should be test/index and the TestController shouldn't be accessible to Admin.
I looked into route constraints, but apparently they can only be used to determine whether a route is valid. Then I attempted to try to call RedirectToAction after logging in, but that got a bit messy with return URLs and another reason that made it even more of a no-no which I can't remember at the moment.
I've landed on the following which I've implemented in my BaseController, but it's less than optimal to execute this on every controller action:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.Controller.GetType() == typeof(TestController) &&
User.IsInRole("Admin"))
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Admin", action = "Index" }));
else if (filterContext.Controller.GetType() == typeof(AdminController) &&
User.IsInRole("Tester"))
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Test", action = "Index" }));
}
else
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
}
}
Is there a best practice for handling the default route based on user role?
using Microsoft.AspNet.Identity;
[Authrorize]
public class AdminController : Controller{
/* do your stuff in here. If your View is not actually a big difference from the tester view and you will only Hide some objects from the tester or viceversa, I suggest you use the same View but make a different methods inside the Controller. Actually you don't need to make AdminController and Tester Controller at all. */
}
// you can just do this in one Controller like
[Authorize(Roles="Admin")]
public ActionResult DetailsForAdmin(int id)
{
var myRole = db.MyModelsAccounts.Find(id);
return View("Admin", myRole); //<- Admin returning View
}
[Authorize(Roles="Test")]
public ActionResult DetailsForTester
I think you get the Idea.

Show Menu Link to Logged In Users ASP.NET MVC 5

So I am brand new to the whole ASP.NET MVC 5 thing and I am creating my first mini application. I need to show the profile link only after a user has logged in. I have a profile controller and the link will redirect the user to the profile controller. Here is the code I have but unfortunately it is not working.
I am using the built-in ASPNet.Identity. I have only modified it to require an email address during signup. Here is the sample code I am using.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using artisan.Models;
namespace artisan.Controllers
{
[Authorize]
public class AccountController : Controller
{
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager { get; private set; }
public ActionResult Profile()
{
return View();
}
//
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
So you are saying, after a user successfully logs in, you want to redirect them to some action located in another controller called ProfileController?
If that's what you're after than it's pretty simple. After you authenticated the user in your login method you simply throw a return RedirectToAction("Index", "Profile"); in there and you should be good to go. Here is an example that does just that. It's a little more convoluted but I commented everything so you can understand. There are more than a couple redirects in there for different reasons.
[AllowAnonymous]
[HttpPost]
public async Task<ActionResult> Login(Models.AccountViewModel vm, string returnUrl)
{
//first make sure they filled in all mandatory fields
if (ModelState.IsValid)
{
//try to find the user by the credentials they provided
var user = await UserManager.FindAsync(vm.LoginModel.Username, vm.LoginModel.Password);
//if user is null then they entered wrong credentials
if (user != null)
{
//if user has confirmed their email already
if (user.EmailConfirmed == true)
{
//attempt to sign in the user
await SignInAsync(user, vm.LoginModel.RememberMe);
//if the return url is empty then they clicked directly on login instead of trying to access
//an unauthorized area of the site which redirected them to the login.
if (!string.IsNullOrEmpty(returnUrl))
return RedirectToLocal(returnUrl);
//returnUrl was empty so user went to log in first
else
{
//lets check and see which roles this user is in so we can direct him to the right page
var rolesForUser = UserManager.GetRoles(user.Id);
//users can be in multiple roles but the first role dictates what they see after they sign in
switch (rolesForUser.First())
{
case "Normal_User":
return RedirectToAction("Feed", "Account");
default:
//user is not in any roles send him to the default screen
break;
}
}
}
//user has not confirmed their email address redirect to email confirmation
else
{
//resend confirmation
await SendConfirmationEmail(user.Id);
//redirect user to unconfirmed email account view
return RedirectToAction("UnconfirmedAccount", "Account", new { Email = user.Email, UserId = user.Id });
}
}
else
{
//add errors to the view letting the user know they entered wrong credentials. Code will fall through and return
//the view below with these errors
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far then validation failed
return View(vm);
}

How to get current user for all actions in a controller?

This is a two-parter
Question 1 (the real question)
I have a DashboardController that is not tied to a model. A User must be logged in before they can access the dashboard. How can I run a check to see if a user is authenticated before every action is executed, and redirect them to the login view if not? I think OnActionExecuted is what I want, but I am not sure what the exact implementation should be. Am I on the right track here?
public class DashboardController : Controller
{
private ApplicationContext db = new ApplicationContext();
//
// GET: /Admin/
public ActionResult Index()
{
var categories = db.Categories.ToList();
return View(categories);
}
public ActionResult Product(int id)
{
var product = db.Products.Find(id);
return View(product);
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if(Session["current_user"] == null)
{
// This (obviously) doesn't work - what should go here?
return RedirectToAction("Create", "Session");
}
base.OnActionExecuted(filterContext);
}
}
Question 2
If the user IS logged in, what is the right way to make the user accessible in all of these views? I have been told ViewBag is generally a bad idea - what should I use?
I can authorize controllers and actions by follow this link:
It's in brazilian portuguese originally, but the link below is translated to english.
https://translate.google.com.br/translate?sl=pt&tl=en&js=y&prev=_t&hl=pt-BR&ie=UTF-8&u=http%3A%2F%2Fdevbrasil.net%2Fprofiles%2Fblogs%2Fautentica-o-e-permiss-es-de-usu-rios-em-asp-net-mvc-4&edit-text=&act=url
You can get the logged user in views by
#HttpContext.Current.User.Identity.Name
PS: Sorry my bad english
Use [Authorize] atrribute.
For example:
[AcceptVerbs(HttpVerbs.Get)]
[Authorize]
public ActionResult add()
{
}
Then in the web.config
<authentication mode="Forms">
<forms name="my_cookie_name" loginUrl="~/login" defaultUrl="~/" timeout="2880"/>
</authentication>
If the user is not authenticated, it will get redirected automatically to the login page.
If you want something simple to control the identity of your users check the highest rated answer here: ASP.NET MVC - Set custom IIdentity or IPrincipal. It's a brilliant example. I use somthing similar in all my projects.
In my login action:
var user = _userService.system_login(systemlogin_model_post.email, systemlogin_model_post.password); // my user model
//... doing all sorts of validations
// once everyone is happy I create a cookie
Response.Cookies.Add(UserCookie.GetCookie(user));
Than using the code from the link above I create cookie:
public static class UserCookie
{
public static HttpCookie GetCookie(User user)
{
CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel { user_id = user.UserId, username = user.Username, roles = user.Roles ,session_token = GUIDGenerator.ToAlphaNumerical() };
JavaScriptSerializer serializer = new JavaScriptSerializer();
string userData = serializer.Serialize(serializeModel);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,
user.UserId.ToString(),
DateTime.Now,
DateTime.Now.AddMinutes(30),
false,
userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
return new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
}
}
When [Authorize] is fired this code takes care of it:
Global.asax
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer serializer = new JavaScriptSerializer();
CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);
CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
newUser.user_id = serializeModel.user_id;
newUser.username = serializeModel.username;
newUser.roles = serializeModel.roles;
newUser.form_token = serializeModel.form_token;
HttpContext.Current.User = newUser;
}
}
1) Authorize attribute of ASP.NET MVC is totally focused on your first problem. You may even go for customization but not suggested for most of scenarios.
2) To assign the currently logged in user and visible in all the views, you may bind the user name using ViewBag/ViewModel property to Layout(_Layout.cshtml) so that it appears on top of every page where the layout is used.
Note: If you want to perform any pre action-invoke logic, then OnActionExecuting filter is the correct place, before entering that action method.
Precisely, you have to create a class and that class inherits the Controller class.
public class MyAuthentication : Controller
{
public MyAuthentication()
{
isAuthenticated();
}
private void isAuthenticated()
{
// do your authentication
//if user authenticated keep user details within a cookie, so that
// when the next request, program logic will search for cookie,
//if it is found then assume user was authenticated else redirect to login page.
}
}
And then inherits this MyAuthentication class in your project for all controllers
public class DashboardController : MyAuthentication
{
public ActionResult Index()
{
var categories = db.Categories.ToList();
return View(categories);
}
// rest of the codes
}
So that the authentication remains in single place. You can inherit this where ever you want.
If you need current user anywhere in the controller/action then better way is to set the user data when you perform authorization.
In your authorization filter , you can use
System.Web.HttpContext.Current.Items["userdata"]=userDataObject;
For authentication , this article can help.
http://www.dotnet-tricks.com/Tutorial/mvc/G54G220114-Custom-Authentication-and-Authorization-in-ASP.NET-MVC.html
First Put the Form Authentication Cookie when the user is logged in. like
[HttpPost]
public ActionResult Login(Acccount obj){
// check whether the user login is valid or not
if(UseIsValid){
FormsAuthentication.SetAuthCookie(obj.username, obj.RememberMe);
return redirectToAction("Index","DashBoard");
}
return View(obj);
}
*
and Use [Authorize] attribute. like*
[Authorize]
public class DashboardController : Controller
{
private ApplicationContext db = new ApplicationContext();
public ActionResult Index()
{
var categories = db.Categories.ToList();
return View(categories);
}
}

Categories