Reputation: 13
Dear All,
This is my first post on Stackoverflow so if something is incorrect with the post please signal it so I could modify.
The issue
I have a view that provides visibility on the account information of a selected user based on a passed model that has a selected ApplicationUser as a member. When I make an HTTPpost request with a button every data from the model is passed but the ApplicationUser ID changes for some reason, therefore my HTTPPost action later on with FindById is not working correctly.
The model
public class ModifyAccountModel
{
public ApplicationUser SelectedUser { get; set; }
public IEnumerable<string> CurrentRoles { get; set; }
public IEnumerable<IdentityRole> AvailableRoles { get; set; }
}
The view
@model Time_Window_Management_MVC.Models.ModifyAccountModel
@{
ViewBag.Title = "Modify Account";
}
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm("ModifyAccount", "Admin", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Attributes</h4>
<div>
@ViewBag.Errormessage
</div>
@Html.ValidationSummary("", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-2">
User ID
</div>
@*@Html.LabelFor(m => m.FirstName, new { @class = "col-md-2 control-label" })*@
<div class="col-md-10">
@Html.DisplayFor(m => m.SelectedUser.Id)
</div>
</div>
<div class="form-group">
<div class="col-md-2">
First Name
</div>
@*@Html.LabelFor(m => m.FirstName, new { @class = "col-md-2 control-label" })*@
<div class="col-md-10">
@Html.TextBoxFor(m => m.SelectedUser.FirstName, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-2">
Second Name
</div>
@*@Html.LabelFor(m => m.SecondName, new { @class = "col-md-2 control-label" })*@
<div class="col-md-10">
@Html.TextBoxFor(m => m.SelectedUser.SecondName, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-2">
Sales Org.
</div>
@*@Html.LabelFor(m => m.SecondName, new { @class = "col-md-2 control-label" })*@
<div class="col-md-10">
@Html.TextBoxFor(m => m.SelectedUser.SalesOrg, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-2">
SAP System
</div>
@*@Html.LabelFor(m => m.SecondName, new { @class = "col-md-2 control-label" })*@
<div class="col-md-10">
@Html.TextBoxFor(m => m.SelectedUser.SAP_System, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-2">
Email
</div>
@*@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })*@
<div class="col-md-10">
@Html.TextBoxFor(m => m.SelectedUser.Email, new { @class = "form-control" })
</div>
</div>
<h4>Roles</h4>
<table class="table">
<tr>
<td>
Role name
</td>
<td>
Actions
</td>
</tr>
@if (Model.CurrentRoles.Count() == 0)
{
<tr>
@Html.ActionLink("Add new role", "AddAccountRole", new { Id = Model.SelectedUser.Id })
</tr>
}
else
{
foreach (var role in Model.CurrentRoles)
{
<tr>
<td>
@role
</td>
<td>
@Html.ActionLink("Delete", "DeleteAccountRole", new { Id = Model.SelectedUser.Id, Role = @role })
</td>
</tr>
}
<tr>
@Html.ActionLink("Add new role", "AddAccountRole", new { Id = Model.SelectedUser.Id })
</tr>
}
</table>
<div class="form-group">
<div class="col-md-12">
<input type="submit" class="btn btn-default" value="Save changes" />
</div>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
The action responding to post request
[HttpPost]
public async Task<ActionResult> ModifyAccount(ModifyAccountModel model)
{
if (ModelState.IsValid)
{
ApplicationUser account = await UserManager.FindByIdAsync(model.SelectedUser.Id);
if (account == null)
{
return RedirectToAction("ManageAccounts", "Admin", "Account modification couldn't be done.");
}
account.FirstName = model.SelectedUser.FirstName;
account.SecondName = model.SelectedUser.SecondName;
account.SalesOrg = model.SelectedUser.SalesOrg;
account.SAP_System = model.SelectedUser.SAP_System;
return RedirectToAction("ModifyAccount", "Admin", new { id = model.SelectedUser.Id });
}
return RedirectToAction("ManageAccounts", "Admin", "Something went wrong.");
}
The only thing in the model that is changing is the ApplicationUser ID, everything stays as it should.
I know that as a workaround I could create an action that just sends the ID as string and then do the FindByIdAsync search based on that but would still like to know what is causing this issue.
I suspect that a new ApplicationUser is being created when posting with the same content as the original one and thus a new ID is created but I would like to have some clarification and probably some help on the matter.
Many thanks for any feedback, have a nice day!
Daniel
Upvotes: 1
Views: 85
Reputation: 130
You can use @Html.HiddenFor(m => m.SelectedUser.Id)
ex. or, as RizkiDPrast wrote, @Html.TextBoxFor(m => m.SelectedUser.Id), new { @readonly = true })
with readonly attrib.
Upvotes: 0
Reputation: 1725
Good day, on this line
@Html.DisplayFor(m => m.SelectedUser.Id)
will only render int
of current userId as an html string
it will not be included in your post request then on your server the Binding
will create new ApplicationUser with a new GUID
every time.
try simply changes it to
@Html.TextBoxFor(m => m.SelectedUser.Id)
that will produces html input
(with Name attribute)
Upvotes: 1