Redirect after log-in cannot work - asp.net-mvc

I have a form to manage the insertion of comments:
#model GatorsWebSite.Comment
#using (Html.BeginForm("Create", "Comments", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.ArticleID)
#Html.TextAreaFor(m => m.Text, new { #class = "form-control wide", #placeholder = "Type your comment", #rows = "3" })
#Html.ValidationMessageFor(m => m.Text, "", new { #class = "text-danger" })
}
This is the action on controller:
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Text, ArticleID")] Comment comment){
if (comment == null || comment.ArticleID <= 0)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
if (ModelState.IsValid){
comment.Date = DateTime.Now;
comment.UserID = User.Identity.GetUserId();
_commentRepository.Add(comment);
_commentRepository.Save();
}
return RedirectToAction("Details", "News", new { ID = comment.ArticleID });
}
Since the action is under authorization, if the user is not logged in
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl){
if (ModelState.IsValid){
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null){
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else{
ModelState.AddModelError("", "Invalid username or password.");
}
}
return View(model);
}
the redirect url will be Comments/Create and will fail with a 404 error, does exist a general solution to manage this problem, since I cannot use a simple redirect to action?

One alternative is to make a Create get action and make it redirect to articles/news list page. For Example:
public ActionResult Create(){
return RedirectToAction("Index", "News");
}
EDIT
and is exactly what I've done:
[Authorize]
[HttpGet]
public ActionResult Create([Bind(Include = "Text, ArticleID")] Comment comment)
{
if (comment == null || comment.ArticleID <= 0)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
if (ModelState.IsValid)
{
comment.Date = DateTime.Now;
comment.UserID = User.Identity.GetUserId();
_commentRepository.Add(comment);
_commentRepository.Save();
}
return RedirectToAction("Details", "News", new { ID = comment.ArticleID });
}
...and work like a charm

Related

Why does the action method get wrong parameter?

I have the Action method and the View for editing properties of some items.
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin")]
public async Task<ActionResult> Edit(Item item)
{
if (ModelState.IsValid)
{
db.Entry(item).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.CatagorieId = new SelectList(db.Catagories, "ID", "Name", item.CatagorieId);
return View(item);
}
and
#model OpenOrderFramework.Models.Item
#using OpenOrderFramework.Extensions
#{
ViewBag.Title = "edit";
}
<h2>Editing</h2>
#using (Html.BeginForm())
{
<div class="form-horizontal">
<h4>The car</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<-- etc -->
But when I submit the form I get an error
Store update, insert, or delete statement affected an unexpected number of rows (0).
I figured out that in action method ID of the item that was posted is always 0 even if real ID of the item is different.
Why does it happen?
GET Action method:
// GET: Items/Edit/5
[Authorize(Roles = "Admin")]
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Item item = await db.Items.FindAsync(id);
if (item == null)
{
return HttpNotFound();
}
ViewBag.CatagorieId = new SelectList(db.Catagories, "ID", "Name", item.CatagorieId);
return View(item);
}
When you post the form, the http call to your HttpPost action method is a totally separate Http request and Entity framework cannot track that entity.
As Darin mentioned in the comment, It is not a good idea to mix the entity classes in your UI layer. That makes it very tightly coupled.
What you should be using is creating and using a view model for your view. View model's are simply POCO classes, which is specific to the view.
public class ItemViewModel
{
public int Id {set;get;}
public string Name {set;get;}
public List<SelectListItem> Categories { set;get;}
public int SelectedCategory {set;get;}
}
And in your GET action, read the entity from your database,create an object of the view model and set the property values to that
public ActionResult Edit(int id)
{
var vm=new ItemViewModel { Id=id };
var item = db.Items.FirstOrDefault(s=>s.Id==id);
if(item!=null)
{
vm.Name = item.Name;
}
vm.Categories =db.Categories.Select(s=> new SelectListItem { Value=s.Id.ToString(),
Text=s.Name
}).ToList();
return View(vm);
}
And your view will be strongly typed to your view model
#model ItemViewModel
#using(Html.BeginForm())
{
#Html.DropdDownListFor(s=>s.SelectedCategory,Model.Categories,"Select")
#Html.HiddenFor(s=>s.Id)
#Html.TextBoxFor(s=>s.Name)
<input type="submit" />
}
And in your HttpPost action, read the existing entity from your db and update the property values you want to update.
[HttpPost]
public ActionResult Edit(ItemViewModel model)
{
if(ModelState.IsValid)
{
var item = d.Items.FirstOrDefault(s=>s.Id==model.Id);
item.Name = model.Name;
db.Entry(item).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
model.Categories =db.Categories.Select(s=>
new SelectListItem {
Value=s.Id.ToString(),
Text=s.Name }).ToList();
return View(model);
}
Make sure to add enough NULL checkings before accessing the entities/ objects in the code.

Asp.Net MVC 5, View not posting back to the controller

I am creating a simple login form using Asp.Net MVC 5. Everything is fine but when I click on submit button after giving User Id and Password, the view does not go back to the desired Controller Action (LogIn). Here is the Action:
[HttpPost]
public ActionResult LogIn(User user)
{
var auth_user = CheckAuthentication(user);
if(auth_user!=null)
{
Session["user"] = new User() { UserId = user.UserId, Name = user.Name };
return RedirectToAction("Index", "User");
}
return View();
}
[AllowAnonymous]
public ActionResult LogIn()
{
return View();
}
and the view:
#model FinancialManagement.Models.User
#{
ViewBag.Title = "LogIn";
}
<h2>LogIn</h2>
#using (Html.BeginForm("LogIn", "User", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>User</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.UserId, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.UserId)
#Html.ValidationMessageFor(model => model.UserId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log In" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
This is my complete User controller:
[Authorize]
public class UserController : Controller
{
private FinancialManagmentEntities db = new FinancialManagmentEntities();
// GET: /User/
public ActionResult Index()
{
return View(db.Users.ToList());
}
// GET: /User/Details/5
public ActionResult Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
// GET: /User/Create
[AllowAnonymous]
public ActionResult Create()
{
return View();
}
// POST: /User/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(User user)
{
if (ModelState.IsValid)
{
db.Users.Add(user);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
ActionResult LogOut()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index", "Home");
}
User CheckAuthentication(User user)
{
return db.Users.Where(u => u.UserId == user.UserId && u.Password == user.Password).FirstOrDefault();
}
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
public ActionResult LogIn(User user)
{
var auth_user = CheckAuthentication(user);
if(auth_user!=null)
{
Session["user"] = new User() { UserId = user.UserId, Name = user.Name };
return RedirectToAction("Index", "User");
}
return View();
}
[AllowAnonymous]
public ActionResult LogIn()
{
return View();
}
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
// POST: /User/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="UserId,Name,Password")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
// GET: /User/Delete/5
public ActionResult Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
// POST: /User/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(string id)
{
User user = db.Users.Find(id);
db.Users.Remove(user);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
Try to specify the View's Name and your Model like that :
return View("NameOfView", YourModel);
If it doesn't work put the absolute path :
return View("~/Views/FolderName/ViewName.cshtml");

Double Edit ActionResult with [AllowAnonymous] and [Authorize]

I have this problem: I can not create a double "Edit" ActionResult into a controller where my goal is to allow an anonymous user to change a number of fields through a filter that returns only one record in the output .... The system returns this error, and I knew, somehow, that the problem is related to the primary key.
CONTROLLER
// GET:
[Authorize]
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
MyTable mytable = await db.MyTable.FindAsync(id);
if (mytable == null)
{
return HttpNotFound();
}
return View(mytable);
}
[AllowAnonymous]
[HttpGet]
public async Task<ActionResult> EditAnonymus(int? fk_field1, string guid)
{
if (fk_field1 == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var query = (from i in db.MyTable
where i.Guid == guid && i.Fk_Field1==fk_Field1
select new { i.Id }).SingleOrDefault();
MyTable mytable = await db.MyTable.FindAsync(query.Id);
if (mytable == null)
{
return HttpNotFound();
}
return View(mytable);
}
// POST:
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Id,Fk_table1,......")] MyTable mytable)
{
if (ModelState.IsValid)
{
try
{
db.Entry(mytable).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
catch (DbUpdateConcurrencyException ex)
{
Trace.Write(ex.Message);
}
}
return View(mytable);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EditAnonymus([Bind(Include = "Id,........")] MyTable mytable)
{
if (ModelState.IsValid)
{
try
{
db.Entry(mytable).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
catch (DbUpdateConcurrencyException ex)
{
Trace.Write(ex.Message);
}
}
return View(mytable);
}
VIEW (command for entry from another View)
#Html.ActionLink("Modify Anonymus",
"EditAnonumus", controllerName: "NameController",
routeValues: new
{ fk_table1 = Model.Id, guid = Request.QueryString["guid"] },
htmlAttributes: null)
VIEW (Edit)
#model ManagingEvent.Models.MyTable
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Anonymus Edit</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
//omiss
<div class="form-group">
#Html.LabelFor(model => model.Cognome, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Field, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Field, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
ERROR OUTPUT (after save)
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since
entities were loaded. See
http://go.microsoft.com/fwlink/?LinkId=472540 for information on
understanding and handling optimistic concurrency exceptions.The
thread 0x518 has exited with code 0 (0x0).
I think your problem is not related to the primary key but can be this line of code in the EditAnonymus method:
db.Entry(mytable).State = EntityState.Modified;
What you are doing is mark explicitly the entity as modified, EF will try to update it when you call SaveChangesAsync() and will expect to get the count of the rows updated (1), but if no properties have changed it will get 0 (no rows have been updated), therefore it will throw the exception.
I would comment that row and try to do a simple fetch-edit-save and see what happens.
Thanks to the user449689 guidance, I searched in internet and I have found this method works:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EditAnonymus (int? Id)
{
if (Id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var TableToUpdate = await db.myTable.FindAsync(Id);
if (TryUpdateModel(TableToUpdate, "",
new string[] { "Field1","Field2","....","....","Field x" }))
{
try
{
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DataException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}

Validation Message MVC

My code is as followed and the error message are not displayed:
Index.cshtml
#model WebApp.Models.OrderItems
#using (Html.BeginForm("SaveToDB", "Home", FormMethod.Post, new { #class = "form-group", role = "form" }))
{
#Html.Partial("Information")
}
Partial : Information.cshtml
#model WebApp.Models.OrderItems
<div class="col-lg-4">
<div class="form-group">
<label for="input1" class="col-lg-4 control-label">#Html.LabelFor(model => model.CLInfo.ClientName)</label>
#Html.EditorFor(model => model.CLInfo.ClientName, new { style = "width:250px" })
#Html.ValidationMessageFor(model => model.CLInfo.ClientName)
</div>
</div>
Model :
public class OrderItems
{
public InfoCLInfo{ get; set; }
}
Model : the class for Infos
public class Info
{
[Display(Name = "Client Name")]
[Required]
public string ClientName{ get; set; }
}
The controller
[HttpPost]
[MultipleButton(Name = "action", Argument = "SaveToDB")]
public ActionResult SaveToDB(OrderItems Client)
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
if (ModelState.IsValid)
{
if (_db == null)
_db = new OrderDB();
OrderItems ClientOrig = Session["Clientobj"] as OrderItems;
ClientOrig.CLInfo = Client.CLInfo;
Session["Clientobj"] = null;
}
return RedirectToAction("Index", "Home");
}
[Authorize]
public ActionResult Index (OrderItems Client)
{
int ClientID = Convert.ToInt32(Session["Client"]);
if ClientID == 0)
{
ClientID = 2;
Session["Client"] = ClientID;
}
if (Session["Clientobj"] == null)
{
Client = new OrderItems();
Client.CLOrderID = 123;
Session["Clientobj"] = Client;
}
else
{
Client = Session["Clientobj"] as OrderItems
}
return View(Client);
}
on post the ModelState.IsValid return false which true, but I don't have any message to tell the user where is the error to be fixed.
I tried to add : #Html.ValidationSummary(true) after the BeginForm , but it didn
Any idea please
Thanks
You cannot use RedirectToAction if you want to retain your model state. All errors and what not are kept in the ModelState object, and when you redirect to action it's performing a new get action, which starts fresh with a clean slate.
You need to return the view like you do in the original action.

How to allow users to only edit their details in a catalog

I am starting on MVC 5 tutorial and implemented roles and users as followed by the link:
http://typecastexception.com/post/2013/11/11/Extending-Identity-Accounts-and-Implementing-Role-Based-Authentication-in-ASPNET-MVC-5.aspx
With Role based authentication in place, I now have an admin who can create users and also a catalog of companies listed under Catalog Controller. Only this user when logged in with his username and password set by the admin will be redirected to their company page they are representing to make the edits instead of the free control of editing everyone else's company.
How should I go about doing this?
This is my AccountController:
[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; }
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
}
//if (User.Identity.AuthenticationType == "CanEdit" )
//{
// return RedirectToAction()
//}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
[Authorize(Roles = "Admin")]
public ActionResult Register()
{
return View();
}
[HttpPost]
[Authorize(Roles = "Admin")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = model.GetUser();
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
return RedirectToAction("Index", "Account");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
[Authorize(Roles = "Admin")]
public ActionResult Manage(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
ViewBag.HasLocalPassword = HasPassword();
ViewBag.ReturnUrl = Url.Action("Manage");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin")]
public async Task<ActionResult> Manage(ManageUserViewModel model)
{
bool hasPassword = HasPassword();
ViewBag.HasLocalPassword = hasPassword;
ViewBag.ReturnUrl = Url.Action("Manage");
if (hasPassword)
{
if (ModelState.IsValid)
{
IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
}
else
{
AddErrors(result);
}
}
}
else
{
// User does not have a password so remove any validation errors caused by a missing OldPassword field
ModelState state = ModelState["OldPassword"];
if (state != null)
{
state.Errors.Clear();
}
if (ModelState.IsValid)
{
IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
if (result.Succeeded)
{
return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
}
else
{
AddErrors(result);
}
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut();
return RedirectToAction("Index", "Home");
}
protected override void Dispose(bool disposing)
{
if (disposing && UserManager != null)
{
UserManager.Dispose();
UserManager = null;
}
base.Dispose(disposing);
}
[Authorize(Roles = "Admin")]
public ActionResult Index()
{
var Db = new ApplicationDbContext();
var users = Db.Users;
var model = new List<EditUserViewModel>();
foreach (var user in users)
{
var u = new EditUserViewModel(user);
model.Add(u);
}
return View(model);
}
[Authorize(Roles = "Admin")]
public ActionResult Edit(string id, ManageMessageId? Message = null)
{
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName ==id);
var model = new EditUserViewModel(user);
ViewBag.MessageId = Message;
return View(model);
}
[HttpPost]
[Authorize(Roles = "Admin")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(EditUserViewModel model)
{
if (ModelState.IsValid)
{
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName == model.UserName);
user.FirstName = model.FirstName;
user.LastName = model.LastName;
user.Email = model.Email;
Db.Entry(user).State = System.Data.Entity.EntityState.Modified;
await Db.SaveChangesAsync();
return RedirectToAction("Index");
}
// If we got this far, something failed, redisplay form
return View(model);
}
[Authorize(Roles = "Admin")]
public ActionResult Delete(string id = null)
{
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName == id);
var model = new EditUserViewModel(user);
if (user == null)
{
return HttpNotFound();
}
return View(model);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin")]
public ActionResult DeleteConfirmed(string id)
{
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName == id);
Db.Users.Remove(user);
Db.SaveChanges();
return RedirectToAction("Index");
}
[Authorize(Roles = "Admin")]
public ActionResult UserRoles(string id)
{
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName == id);
var model = new SelectUserRolesViewModel(user);
return View(model);
}
[HttpPost]
[Authorize(Roles = "Admin")]
[ValidateAntiForgeryToken]
public ActionResult UserRoles(SelectUserRolesViewModel model)
{
if (ModelState.IsValid)
{
var idManager = new IdentityManager();
var Db = new ApplicationDbContext();
var user = Db.Users.First(u => u.UserName == model.UserName);
idManager.ClearUserRoles(user.Id);
foreach (var role in model.Roles)
{
if (role.Selected)
{
idManager.AddUserToRole(user.Id, role.RoleName);
}
}
return RedirectToAction("index");
}
return View();
}
#region Helpers
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
private bool HasPassword()
{
var user = UserManager.FindById(User.Identity.GetUserId());
if (user != null)
{
return user.PasswordHash != null;
}
return false;
}
public enum ManageMessageId
{
ChangePasswordSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
Error
}
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
#endregion
}
Edit View
Catalog Controller edit view:`#model Catalog.Models.Partner
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm("Edit", "Catalog", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.Company, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Company, new { #class = "form-control", autocomplete = "off" })
#Html.ValidationMessageFor(model => model.Company)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Description, new { #class = "form-control", autocomplete = "off" })
#Html.ValidationMessageFor(model => model.Description)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Details, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Details, new { #class = "form-control", rows = 10 })
#Html.ValidationMessageFor(model => model.Details)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.InCharge, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.InCharge, new { #class = "form-control", autocomplete = "off" })
#Html.ValidationMessageFor(model => model.InCharge)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Email, new { #class = "form-control", autocomplete = "off" })
#Html.ValidationMessageFor(model => model.Email)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Logo, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<hr />
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
`
When grabbing the database context, add a Where() clause that will just grab the information the current user belongs to. if you add this as a namespace using Microsoft.AspNet.Identity; then you can utilize the User.Identity.GetUserId() to return the current user's id and use that in your Where() clause to view only what the user/partner can see.
Despite the date of the question I will leave my answer here because this question is relevant when you are developing a application and face the need to let only the logged user to see, edit or delete (or any other action) its own records.
The example is shown using the Entity Framework and ASP.NET Identity.
First of all you need to link your object model with the user. This is represented by the IdentityUser. Note that we are using the IdentityUser class because we are using ASP.NET Identity, otherwise we could use ClaimsIdentity.
public class UserObject
{
public int Id { get; set; }
public string Name { get; set; }
public IdentityUser User { get; set; }
}
After this point when you save a UserObject on your Context a field referencing the Id property of IdentityUser (the default name of the table for this class is AspNetUsers) will be created along with the UserObject table.
Then to get the current user you call HttpContext.GetOwinContext().Get<UserManager>() to get the UserManager after that you call UserManager.FindById(User.Idendity.GetUserId()). Just remember to get the IdentityDbContext associated with the Owin Context when inserting new objects otherwise a exception will be thrown.
public ActionResult Create(UserObjectViewModel uoViewModel)
{
UserObject uo = new UserObject();
// create the UserObject using the properties from the UserObjectViewModel
...
// get the User Manager
UserManager userManager = HttpContext.GetOwinContext().Get<UserManager>();
// assign the current User
uo.User = userManager.FindById(User.Identity.GetUserId())
...
}
From now on you can call User.Identity.GetUserId() to get the current User Id and send it along with your query parameters like this:
public ActionResult Get()
{
string currentUserId = User.Identity.GetUserId();
yourDbContext.Where(uo => uo.User.Id == currentUserId);
...
}

Resources