MVC4 - ActionLink to either Create() or, if already existing, Edit(Id) - asp.net-mvc

I would like an action link that says "set user default". There's a possibility the database does not already have the UserDetails stored for the user who clicks the link. If this is the case, I would like to direct the user to the Create view when they can save a new object.
If the UserDetails already exists for the user, I would like to direct the user to their Edit(id) page and load their existing UserDetails from the database.
Basically I need an ActionLink that points to a different view based on some information.
What is the preferred/standard way in MVC to accomplish this?
Existing Record
#Html.ActionLink("set user default", "Edit", "User")
Non-Existing Record
#Html.ActionLink("set user default", "Create", "User")
This was an attempt I made however it didn't work since EditOrCreate needs to be a view - ideally this scenario would not require the creation of another view.
public ActionResult EditOrCreate()
{
User user = Get(User.Identity.Name);
if (user != null)
Edit(user);
else
Create();
}

You can achieve that by having action link to SetUserDefault action method such as
#Html.ActionLink("set user default", "SetUserDefault", "User")
Inside the action method detect the user type and then redirect the user to the right action
public ActionResult SetUserDefault()
{
User currentUser = Get(User.Identity.Name);
if (currentUser != null)
return RedirectToAction("Edit", new { id = currentUser.Id });
else
return RedirectToAction("Create");
}

Related

mvc set and get id and name in FormsAuthentication

How can I set and get id and name in FormsAuthentication
Here only I set name
var user = db.usertable.Where(x => x.UserName == L.UserName && x.password == L.password).FirstOrDefault();
if (user == null)
{
ViewBag.Msg = "invalde user";
return View();
}
else
{
FormsAuthentication.SetAuthCookie(user.UserName, false);
return RedirectToAction("Index", "Home");
}
and here only I can get name by this code:
System.Web.HttpContext.Current.User.Identity.Name
How about can I get id user?
When user register in your app "/Account/Register", Identity automatically creates account for him, it would create few new tables in your DB, It would store your new user data in dbo.AspNetUsers.
You have to create Membership object which validates user credentials and manages user settings by user name. And call method ProviderUserKey to get user id.
Membership.GetUser(User.Identity.Name).ProviderUserKey
You can't change user id after creation, it's generated automatically.

Validate user login MVC5

I have a webapp, when I logged in, it redirect me to home/Index, so if I press back on my explorer it redirects me to login again, but I want that user cannot entry if a user is logged...:
In my Regiester controller I use USerName field:
var user = new ApplicationUser { UserName = model.UserName};
So, in my login controller I try somthing like this:
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (UserName == Login())
{
RedirectToAction("Index"/"Home");
}}
but first, it no catch my UserName variable.. how can I do it? or there are any other method like loggout if user click back to Account/register(principal) in my case.

Keeping data between sessions without using get, post or cookies

I have one controller class with two action functions. One action is my login page with one view, and the other is my backend page with multiple views.
public ActionResult Login(...)
{
if (logged in or login success)
{
return RedirectToAction("Backend","Controller");
}
...
return View();
}
public ActionResult Backend(...)
{
if(session expired or not logged in)
{
return RedirectToAction("Login","Controller");
}
...
return View("someView");
}
The issue is when the backend action has to send the user to the login action and I want to show the user a message like "Session expired" on the login page.
As an example ViewBag only lives in the current session. But is there a similar and easy way to store information between sessions? So I can set a message in the backend, then redirect to login, and have the login read that message and display it in the view? Kinda like PersistentViewBag.
I really do not want to use get, post or cookies, as is a viable option but then I rather just have the login as its own view in the backend action instead.
You can simply use the querystring for passing data when you are redirecting to the login page.
public ActionResult Backend(...)
{
if(session expired or not logged in)
{
return RedirectToAction("Login","Controller",new { IsSessionExpired = true });
}
...
return View("someView");
}
In your Login action you can check the querystring and decide if you want to display the message.
Update
You can also use TempData if you do not want to use the querystring.
public ActionResult Backend(...)
{
if(session expired or not logged in)
{
TempData["IsSessionExpired"] = true;
return RedirectToAction("Login","Controller");
}
...
return View("someView");
}
Then you can check it in Login action:
if(TempData["IsSessionExpired"] != null)
{
//Show message
}

symfony - adding a user to a group (sfGuardUserGroup) in a form

I'm trying to save some users in a custom admin form and I'd like to set them in a particular group, in the sfGuardUserGroup.
So If the user I've just created has an id of 25, then I'd expect an entry in the sfGuardUserGroup table with a user_id of 25 and a group_id of 8 (8 is my group id I want o add these users to.)
Could I do this in the form class, or in the processForm action?
I'm using doctrine and SF1.4
Thanks
This should do what you need:
<?php
class AdminUserForm extends sfGuardUserForm
{
public function configure()
{
//customise form...
}
public function save($con = null)
{
//Do the main save to get an ID
$user = parent::save($con);
//Add the user to the relevant group, for permissions and authentication
if (!$user->hasGroup('admin'))
{
$user->addGroupByName('admin');
$user->save();
}
return $user;
}
}
If you require this behaviour for all sfGuardUser's created you should put this logic in the model for sfGuardUser class. [example below]
// sfGuardUser class
public function save(Doctrine_Connection $conn = null) {
if (!$this->hasGroup('group_name'))
$this->addGroupByName('group_name', $conn);
parent::save($conn);
}
If you require this functionality only on this specific form, you should put the logic within the form. Adding logic to the processForm action would be incorrect as you would be placing business logic within the controller.

ASP.NET MVC Ajax post to Action requiring authentication returns login view when user session has timed out

I am using the Ajax.BeginForm to create a form the will do an ajax postback to a certain controller action and then the response view is inserted into the UpdateTargetId.
using (Ajax.BeginForm("Save", null,
new { userId = Model.UserId },
new AjaxOptions { UpdateTargetId = "UserForm" },
new { name = "SaveForm", id = "SaveForm" }))
{
[HTML SAVE BUTTON]
}
Everything works great except when the Users session has timed out and then they are redirected back to the login page. The login page then gets returned from the Ajax call because of the Authorize attribute and the html gets loaded into the UpdateTargetId and therefore I end up with the login page html within the user profile page (at the Target Id). My controller action looks like this:
[Authorize]
public ActionResult Save(Int32 UserId)
{
//code to save user
return View("UserInfoControl", m);
}
How can I solve this problem?
UPDATE (2011-10-20):
Found this post from Phil Haack about this exact issue - http://haacked.com/archive/2011/10/04/prevent-forms-authentication-login-page-redirect-when-you-donrsquot-want.aspx. I have not gotten a chance to digest or implement his solution yet.
I think that you can handle the authorization issue from inside the action.
First remove [Authorize], the use this code:
public ActionResult Save(Int32 UserId)
{
if (!User.Identity.IsAuthenticated)
{
throw new Exception();
}
//code to save user
return View("UserInfoControl", m);
}
Then you can put a OnFailure condition in your AjaxOptions and redirect your page or something.

Resources