Set cookie value before view loaded in MVC? - asp.net-mvc

I need to set a cookie value before my view called. otherwise I have to refresh the page to get cookie value in the view. The problem here is the value of cookie will get in controller.
[HttpGet]
[Route("Abstract/{meetingCode}")]
[AllowAnonymous]
public ActionResult Index(string meetingCode)
{
var meetingAbstract = new MeetingAbstract();
meetingAbstract.Meeting = _abstractContext.GetMeetingWithMeetingCode(meetingCode);
if (meetingAbstract.Meeting != null)
{
var cookie = new HttpCookie("_culture");
cookie.Value = meetingAbstract.Meeting.language.language_locale_code;//"en-US";
cookie.Expires = DateTime.Now.AddDays(365);
cookie.Path = "/";
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
...
Any other way without refresh the page again to set cookie value?

Cookies have some peculiar behaviour, I mean you create them in the Response stream, to be sent to the client, but they are not available in the Request stream until they are sent from the client.
I mean, you cannot access the cookie unless it is being sent from the client.
Anyway, why you need to refresh your page to access the cookie you just created? Is not easier to use the same variable?
[HttpGet]
[Route("Abstract/{meetingCode}")]
[AllowAnonymous]
public ActionResult Index(string meetingCode)
{
var meetingAbstract = new MeetingAbstract();
meetingAbstract.Meeting = _abstractContext.GetMeetingWithMeetingCode(meetingCode);
var cookie;
if (meetingAbstract.Meeting != null)
{
cookie = new HttpCookie("_culture");
cookie.Value = meetingAbstract.Meeting.language.language_locale_code;//"en-US";
cookie.Expires = DateTime.Now.AddDays(365);
cookie.Path = "/";
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
} else {
cookie = this.ControllerContext.HttpContext.Request.Cookies["_culture"];
}
...

Related

How to retain page state when selecting language in Multi Language Implementation using ASP.Net MVC?

I am using the following controller method to store the selected language and return to the Home page when users changes the selected language.
Is there a way I can redirect to the same page which the user is viewing right now with a change in display language instead of redirecting to Home Page.
public ActionResult SetCulture(string culture)
{
string test = this.ControllerContext.RouteData.Values["action"].ToString();
// Validate input
culture = CultureHelper.GetImplementedCulture(culture);
// Save culture in a cookie
HttpCookie cookie = Request.Cookies["_culture"];
if (cookie != null)
cookie.Value = culture; // update cookie value
else
{
cookie = new HttpCookie("_culture");
cookie.Value = culture;
cookie.Expires = DateTime.Now.AddYears(1);
}
Response.Cookies.Add(cookie);
return RedirectToAction("Index");
}

mvc 5 Set Cookie Expire, but expiration back to 01/01/0001

I set cookie when login success like this :
public JsonResult LoginWithPassword(String password)
{
Response.Cookies.Remove("Auth");
string CookieName = "Auth";
long UserId = 4;
HttpCookie myCookie = HttpContext.Response.Cookies[CookieName] ?? new HttpCookie(CookieName);
myCookie.Values["UserId"] = UserId.ToString();
myCookie.Values["LastVisit"] = DateTime.Now.ToString();
myCookie.Expires = DateTime.Now.AddDays(1);
HttpContext.Response.Cookies.Add(myCookie);
return Json(new { IsSuccess = true, ReturnUrl = returnUrl });
}
else
{
return Json(new { IsSuccess = false, Message = "Login fail, Wrong Password" });
}
}
and i read it in next page/action :
public ActionResult Index()
{
if (HttpContext.Request.Cookies["Auth"] == null)
return RedirectToAction("Login", "Access");
return View();
}
Really strange the cookie of "Auth" always empty. When i check the expiration date in debugging breakpoint, i get expiration date : 01/01/0001.
why this happend and how to solve this?
This action in two differents controller
I have tried to implement your code to create cookie. Same code is working fine in MVC5 at my end in firefox browser.
I have used code as below to create cookie -
Response.Cookies.Remove("Auth");
string CookieName = "Auth";
HttpCookie cookie = HttpContext.Response.Cookies[CookieName] ?? new HttpCookie(CookieName);
//HttpCookie cookie = new HttpCookie("Cookie");
cookie.Value = "Hello Cookie! CreatedOn: " + DateTime.Now.ToShortTimeString();
cookie.Expires = DateTime.Now.AddDays(5);
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
In addition the check on "Auth" cookie is successful on Index page as -
public ActionResult Index()
{
if (HttpContext.Request.Cookies["Cookie"] == null)
return RedirectToAction("Login", "Account");
return View();
}
Alternatively I suggest to
1) Set Expiry after cookie is created in login page OR
2) add decimal in expiry days eg. 1.0 or 5.0. See article at link -
http://forums.asp.net/t/1982279.aspx?MVC5+Application+Cookie+expires+when+session+ends
Let me know if this helps you.

MVC: cookies are not persisting

I have an overlay div inside a condition. If Cookies["User"] is null then I show an overlay div having two radio buttons and a submit button.
When user selects radio option and clicks submit button, when by ajax call,
I am calling an action which sets cookies.
I have put the overlay div inside _Layout page, so for every call it checks for session.
My issue is: First time after setting cookies, it's not persisted for second time.
Below is my method which sets cookies:
public ActionResult SaveUserTypeCookies(string usertype, string returnUrl)
{
if (Request.Cookies["User"] != null)
{
HttpCookie cookie = Request.Cookies["User"];
cookie.Values["UserType"] = usertype;
cookie.Expires = DateTime.MaxValue;
Response.SetCookie(cookie);
}
else
{
HttpCookie cookie = new HttpCookie("User");
cookie.Values["UserType"] = usertype;
cookie.Expires = DateTime.MaxValue;
Response.Cookies.Add(cookie);
}
return Redirect(returnUrl);
}
Below is my condition for overlay div:
#if ((Request.Cookies["User"]== null))
{
<div id="overlay_div" class="overlay"></div>
}
Use this syntax to get cookie:
HttpCookie cookie = HttpContext.Request.Cookies.Get("User");
And check if cookie exists use this in C#:
HttpContext.Request.Cookies["User"] != null
And to create and save cookie:
HttpCookie cookie = new HttpCookie("User");
cookie.Values["UserType"] = usertype;
cookie.Expires = DateTime.MaxValue;
HttpContext.Response.SetCookie(cookie);

FormsAuthentication and Ajax Requests

I have a problem knowing whether a user is authenticated or not when ajax requests are sent from jQuery.
HttpContext.User.Identity is not empty when a user does a regular request from their browser and the aspxauth cookie is set. When a user tries doing a ajax request from jQuery, the aspxauth is not set at all.
My Web.Config
<authentication mode="Forms">
<forms loginUrl="~/" />
</authentication>
Setting the FormsAuthentication Cookie
var cookie = new AuthCookie
{
UserId = user.UserId,
Email = user.Email,
Name = user.Name,
RememberMe = createPersistentCookie,
TimeZone = user.TimeZone,
CompanyId = user.CompanyId,
Roles = new List<string> { user.Role ?? "user" }
};
string userData = JsonConvert.SerializeObject(cookie);
var ticket = new FormsAuthenticationTicket(1, cookie.Email, DateTime.Now,
DateTime.Now.Add(FormsAuthentication.Timeout),
createPersistentCookie, userData);
string encTicket = FormsAuthentication.Encrypt(ticket);
var httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) { Expires = DateTime.Now.Add(FormsAuthentication.Timeout) };
_httpContext.Response.Cookies.Add(httpCookie);
When I make requests through my broser, the auth cookie appears:
Whenever I make a request through javascript using $.get() or loading javascript scripts / Any other request through javascript, I get:
The odd thing is that on another ASP application I am using WebSecurity and that works perfectly. The auth cookie is always being sent back from client to server. For this ASP MVC 5 application, when I try to use the FormAuthentication, I cannot get the AuthCookie to proceed through all requests.
you are still able to decorate your class/method with [Authorize] and the like. If you're looking to check inside the controller method you have access to the User Property inherited from System.Web.Mvc.Controller or System.Web.Http.ApiController depending on your controller flavor :
//
// Summary:
// Returns the current principal associated with this request.
//
// Returns:
// The current principal associated with this request.
public IPrincipal User { get; set; }
it can be used like so:
if (User != null && User.Identity != null && User.Identity.IsAuthenticated)
{
// user has access - process request
}
Edit:
Here is an example of an [Api]Controller with an ajax[able] method that uses the controller's User property instead of HttpContext's:
public class HelloController : ApiController
{
[HttpGet]
public IHttpActionResult HelloWorld()
{
try
{
if (User != null && User.Identity != null && User.Identity.IsAuthenticated)
{
return Ok("Hello There " + User.Identity.Name + "!");
}
else
{
return Ok("Hello There Anonymous!");
}
}
catch { throw; }
}
}

Cookie value expiring before the cookie expires

I have an asp.net MVC app that i am working on and I wrote a custom actionfilter in order to filter out certain controller actions based on authorization levels which are set on login and stored in an encrypted cookie along side the formsauthentication cookie, both cookies are set to have the same expiration time but for some reason after awhile of idle time the authorization cookie value becomes blank, i haven't been able to debug and catch it in the act but it just disappears
my actionfilter code looks like this:
string usersRole = "";
if (filterContext.HttpContext.Session["role"] != null)
usersRole = filterContext.HttpContext.Session["role"].ToString();
else if (filterContext.HttpContext.Response.Cookies["ArisPortalCookie"].Value != null)
{
usersRole = filterContext.HttpContext.Response.Cookies["ArisPortalCookie"].Value;
filterContext.HttpContext.Session["role"] = usersRole;
}
string encryptedRole = EncryptionHelper.Encrypt(RoleToCheckFor);
if (encryptedRole == usersRole || usersRole == EncryptionHelper.Encrypt("Admin")) //if the user's role and role required match, we have success
{
//now we break down the response action based on what role was required
if (RoleToCheckFor == "Admin")
{
}
else if (RoleToCheckFor == "Tech" || RoleToCheckFor == "Admin")
{
}
else if (RoleToCheckFor == "Physician" || RoleToCheckFor == "Admin")
{
}
}
else
{
filterContext.Result = new ViewResult
{
ViewName = "NoAuth",
ViewData = filterContext.Controller.ViewData,
TempData = filterContext.Controller.TempData
};
}
I do the same to store Roles. Why have them side by side?
I assume you're doing something like this:
FormsAuthenticationTicket authTicket =
new FormsAuthenticationTicket(1,
username,
DateTime.Now,
DateTime.Now.AddMinutes(60),
rememberMe,
roles);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
authenticationCookie.HttpOnly = true;
contextBase.Response.Cookies.Add(authenticationCookie);
If you are using FormsAuthentication.SetAuthCookie as well, which I don't think you need to and I don't, then make sure your config has timeout set to 60 minutes as well or equivalent to your time of above.
Reading values (piped format) from cookie (as requested)
private static void ReadCookieForPrincipal()
{
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = HttpContext.Current.Request.Cookies[cookieName];
// If the cookie can't be found, don't issue the ticket
if (authCookie == null) return;
// Get the authentication ticket and rebuild the principal & identity
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
string[] roles = authTicket.UserData.Split(new Char[] { '|' });
GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
GenericPrincipal userPrincipal = new GenericPrincipal(userIdentity, roles);
HttpContext.Current.User = userPrincipal;
}

Resources