Request.IsAuthenticated Return False all the time - asp.net-mvc-3

I am having an issue with my Request.IsAuthenticated always return false. I am setting the AuthCookie
CurrentRequest currentRequest = null;
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
} else if (login.ValidateUser(acct.UserName, acct.Password))
{
FormsAuthentication.SetAuthCookie(acct.UserName, true); //Edit on 11/12 #11:08
currentRequest = new CurrentRequest();
SessionWrapper.currentRequest = currentRequest;
return RedirectToAction("About", "Home");
}
//This is a partial login page that is supposed to display login or Logoff.
#using KMSS.Helper;
// this is always false
#if (Request.IsAuthenticated) //Same issue with User.Identity.IsAuthenticated
{
if (SessionWrapper.currentRequest != null)
{
<text> Welcome <strong> #SessionWrapper.currentRequest.Username </strong>
[#Html.ActionLink("Sign Off", "Logoff", "Account")]
</text>
} else {
#: [ #Html.ActionLink("Sign In", "Login", "Account") ]
}
} else
{
#:[ #Html.ActionLink("Sign In", "Login", "Account") ]
}
After reading online, I created a class with a bool value and tries to use that class instead. However, I am getting the object is not set to instance of a new variable exception.
Here is how I had it set up:
//Partial Login page
#model KMSS.Helper.ViewModelAuthenticate;
// this is always false
#if (Model.IsAuthenticated)
//The model is null even though I create create a reference in the Login Method i.e.
(ViewModelAuthenticate auth = new ViewModelAuthenticate();
{
if (SessionWrapper.currentRequest != null)
{
<text> Welcome <strong> #SessionWrapper.currentRequest.Username </strong>
[#Html.ActionLink("Sign Off", "Logoff", "Account")]
</text>
} else {
#: [ #Html.ActionLink("Sign In", "Login", "Account") ]
}
} else
{
#:[ #Html.ActionLink("Sign In", "Login", "Account") ]
}
//Here is the class
public class ViewModelAuthenticate
{
public bool IsAuthenticate { get; set; }
}
//Here is where I am initializing the class in the controller
public ActionResult Login()
{
ViewModelAuthenticate auth = new ViewModelAuthenticate();
auth.IsAuthenticate = false;
return View();
}
//I tried this inside and outside of Login, and it is called before the partial login view. However, I am still getting the object is not set to instance of a new variable exception.
What am I doing wrong here? Your help will be appreciated.
//Showing the authentication section of the config file.
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" slidingExpiration="true" />
</authentication>

I replaced my authentication section with this sample that a sample that I found here. It is working now.

Looking at your code, I feel that there is more going on here than you are showing us. Specifically, the variables CurrentRequest and SessionWrapper, setting them to null on the beginning of the Action method call, etc. I would suggest trying a basic, bare bones example in your project and then begin to add items back in as needed. No AJAX, only full page post back to the server from your login form. Such an example would look like:
Login View Model
public class LoginViewModel{
[Required]
public string UserName {get;set;}
[Required]
public string Password {get;set;}
}
Login POST Action method
[HttpPost]
public ActionResult Login(LoginViewModel model, string returnUrl){
if(!ModelState.IsValid){
return View();
}
if(!provider.ValidateUser(model.UserName, model.Password){
ModelState.AddModelError("", "The username/password combination does not match");
return View();
}
FormAuthentication.SetAuthCookie(model.UserName, true);
if(!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl){
return Redirect(returnUrl);
}
return RedirectToAction("About", "Home");
}
About View
#if(Request.IsAuthenticated){
<b>It WORKS!!</b>
}else{
<b>Nope, still not working</b>
}

I was testing and I set my time back a few days. For someone reason it caused this issue after putting the date back it was fine. I assume windows forms had the old date (which was todays date) cached so I assume it was expired. Just a thought about the matter.

Related

issue on redirecting on log in page when already log in in Mvc3

im having a hard time trying to solve this issue. when i input a username and a password ive always redirect again in log in page. why this happen???
here's my code in login
account controller:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
if (Roles.IsUserInRole("Employer"))
{
return RedirectToAction("CustomerIndex", "Customer");
}
else if (Roles.IsUserInRole("Worker"))
{
return RedirectToAction("WorkerIndex", "Worker");
}
else if (Roles.IsUserInRole("Administrator"))
{
return RedirectToAction("ClientIndex", "Client");
}
else
{
return View(model);
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
thanks.for those who willing to help :)
Looking at your code there are 3 possible cases when this can happen:
Model validation failed -> for example the user didn't provide a username
The user provided incorrect credentials and the ValidateUser method returned false
Credential validation succeeded but the user is not in any of the roles Employer, Worker or Administrator.
Put a breakpoint in your code to see which is your case and act accordingly.

TextBoxFor on a boolean field renders the same value even if it was modified on controller side

I have a simple form with a textbox (and a model editor I want to render in specific cases)
#using (Html.BeginForm("Import", "Flow"))
{
#Html.TextBoxFor(model => model.IsConfirmed)
#if (Model.IsConfirmed)
{
#Html.EditorFor(m => m.Preview)
}
}
The model used in this view is the following
public class ImportViewModel
{
public Boolean IsConfirmed { get; set; }
public PreviewViewModel Preview { get; set; }
public ImportViewModel()
{
this.IsConfirmed = false;
}
}
The form posts on the following controller
public class FlowController
{
[HttpPost]
public ActionResult Import(ImportViewModel model)
{
try
{
if (ModelState.IsValid)
{
if (model.IsConfirmed)
{
// do something else
}
else
{
model.Preview = Preview(model.strCA, model.SelectedAccount);
model.IsConfirmed = true;
return View(model);
}
}
}
catch (Exception ex)
{
throw new Exception("arf", ex);
}
return RedirectToAction("Index", "Home");
}
}
On first load, the textbox contains "false"
When posted, the property IsConfirmed of the model is set to "true" and this model is passed to the same view.
I expect the textbox to be "true" but it is still "false"... moreover the Preview property is correctly rendered, so it means Model.IsConfirmed is indeed true...
Am I missing something ?
Thanks
Make sure you remove the value from the ModelState if you intend to modify it:
ModelState.Remove("IsConfirmed");
model.IsConfirmed = true;
The reason you need to do that is because, by design, all Html helpers (such as TextBoxFor) will first look for a value in the ModelState when binding and only not found they will use the value on your model. And since there's a value with the same name in the ModelState (coming from the POST request), that's what's being used.

MVC Role based routing clarification

Small Question at the end of a very long explanation ...
Assuming the Admin User belonging to Admin Role and the Regular User belonging to User Role attempt to access the Index page with the following route registered in Global.asax.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] {"tst.Controllers"}
);
In the HomeController, the Index Action Method is decorated with the Authorize attribute.
[Authorize]
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
Forcing the anonymous user to logon.
If the Admin User logs in with his/her credentials, I would like to redirect him/her to the Index Action Method in the HomeController located in the Admin area.
If a Regular user logs in, I would like to redirect him/her to the Index Action Method in the HomeController located in the User area.
I have the following code in UserAreaRegistration.cs
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"User",
"Profile/{action}",
new { area = AreaName, Controller = "Home", action = "Index" },
new { RoleConstraint = new RoleConstraint()},
new[]{ "tst.Areas.User.Controllers"}
);
}
and the following code for AdminAreaRegistration.cs
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin",
"Profile/{action}",
new { area = AreaName, Controller = "Home", action = "Index" },
new { RoleConstraint = new RoleConstraint()},
new[]{ "tst.Areas.Admin.Controllers"}
);
}
Where the RoleConstraint is defined as follows
public class RoleConstraint: IRouteConstraint
{
public bool Match(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection)
{
RoleProvider rp = new tst.Providers.CustomRoleProvider();
string[] roles = rp.GetRolesForUser(httpContext.User.Identity.Name);
if (roles != null && roles.Length > 0)
{
string roleName = roles[0];
string areaName = route.Defaults["area"].ToString();
return areaName == roleName;
}
return false;
}
}
The stock standard LogOn Action Method in the AdminController in the main Controllers folder...
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl)
&& returnUrl.Length > 1
&& returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//")
&& !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Question:
Am I right in thinking that, When the Admin/Regular User is validated he/she must be redirected in this line in the code snippet above
return RedirectToAction("Index", "Home");
to the appropriate Index Action Method(Read: Index Action Method in the appropriate Area).
If so, I would like to know how.
I am confused because a constant string "Profile" is involved and it is not the usual stuff involving an action method and a controller name. "Profile" is neither a controller nor an action method.
Inspired by this post
MVC role-based routing
Instead of
return RedirectToAction("Index", "Home");
in the LogOn Action Method, I replaced it with
return Redirect("/Profile");
It worked !!!
However, what I don't understand is, when I click Log Off, it renders the Index page in the main Views folder. So I have to click LogOff again to be taken back to the LogOn page.

How to send data from view to controller in MVC3

Hello everyone I would like to ask how to send data from view to controller ? I would like to describe my question with my controller and view as you can see below
Here is the login action controller
[HttpPost]
public ActionResult Login(Panel model, string Username, string Password, string CaptchaValue, string InvisibleCaptchaValue)
{
bool cv = CaptchaController.IsValidCaptchaValue(CaptchaValue.ToUpper());
bool icv = InvisibleCaptchaValue == "";
if (!cv || !icv)
{
ModelState.AddModelError(string.Empty, "The Captcha Code you entered is invalid.");
}
if (ModelState.IsValid)
{
if (model.Username == Username && model.Password == Password)
{
FormsAuthentication.SetAuthCookie(model.Username, false);
return RedirectToAction("index", "Home");
}
else
{
ModelState.AddModelError("", "Check your name or password");
}
}
return View();
}
So when user login, redirect to Home/index view. At this point everything is okey.
Here is my index view:
[Authorize]
public ActionResult index()
{
return View();
}
My question is how can I hold user's password parameter and send from index view to different controller to use this parameter in controller method but how ? For example I would like to use password parameter at my index_test controller method in where clause but first of all I need to send this data from index.
public ActionResult index_test()
{
return View(db.contents.Where(x => x.test_parameter== password).ToList());
}
You have to add a parameter to your action method:
public ActionResult index_test(string password) { ...
In Your view you can either send data to the action via a standard link:
#Html.ActionLink("Click me", "index_test", "Controller",
new { password = "StringOrVariable")
Or by doing a form post:
#using(Html.BeginForm("index_test")) {
<input type="hidden" name="password" value="mypassword" />
add some fields
<input type="submit" value="Send" />
}
In your view post the form back to the controller, for example
<form action = "yourcontroller/youraction" method = "POST" enctype = "multiparrt/form-data">

Add User Roles on Registration (Forms Authentication) MVC3

I am developing an MVC 3 project and want to add a user to a role when they are registered, using Forms Authentication. So I'd like to create some check boxes, or a drop down list showing the roles, which are selected and the user is assigned to the role as they are registered.
I have this code so far, which works:
public ActionResult Register()
{
ViewData["roleName"] = new SelectList(Roles.GetAllRoles(), "roleName");
return View();
}
And in the view I have:
<label for="roleName">Select Role:</label>
#Html.DropDownList("roleName")
#Html.ValidationMessage("roleName")
This is HttpPost section of the controller, and this is the part that I don't know what to code:
[HttpPost]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus;
Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
return View(model);
So, all the roles do show up in the view. All I need to know is what to add to the HttpPost section to get this working.
Thanks a lot, Amy
if (createStatus == MembershipCreateStatus.Success)
{
Roles.AddUserToRole(model.UserName, "RoleName");
FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
return RedirectToAction("Index", "Home");
}
Try this. It's should work

Resources