So I am trying to create a new role in my MVC5 application. Every time I get an exception saying:
Name cannot be null or empty
Model:
public class ApplicationRole : IdentityRole
{
public new string Id { get; set; }
[Display(Name = "Name")]
public new string Name { get; set; }
[Display(Name = "Description")]
[StringLength(100, MinimumLength = 5)]
public string Description { get; set; }
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(ApplicationRole model)
{
try
{
if (ModelState.IsValid)
{
var role = new ApplicationRole()
{
Name = model.Name,
Description = model.Description
};
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>());
var result = await roleManager.CreateAsync(role);
if (result.Succeeded)
{
return RedirectToAction("Index", "Roles", model);
}
else
{
AddErrors(result);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
// If we got this far, something failed, redisplay form
return View(model);
}
Execution stops on the following line:
var result = await roleManager.CreateAsync(role);
View:
@model IEnumerable<User_Manager_Interface.Models.ApplicationRole>
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@Html.ActionLink("Create New", "Create", "Roles", new object { }, new { @class = "stdbtn" })
<div class="contenttitle radiusbottom0">
<h2 class="table"><span>Roles</span></h2>
</div>
<table cellpadding="0" cellspacing="0" border="0" class="stdtable" id="dyntable">
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
@Html.ActionLink("Details", "Details", new { id = item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</tbody>
</table>
What I don't get is that role does get the fields I pass in my view but the error persists. Any suggestions on how I can get around this? Hopefully I have provided enough to reproduce the error.
UPDATE to my scenario:
IdentityRole has its own Id and Name properties and if I declare them within the ApplicationRole model and decorating them with the new keyword it will obviously hide the inherited member. I was aware of this when I posted the question.
If I remove the two properties altogether, then the application throws an exception at Runtime detailed:
Mapping and metadata information could not be found for EntityType 'User_Manager_Interface.Models.ApplicationRole
Going back to point 1. above, the reason I went with that implementation over 2. is because with 1., the application does not terminate but instead throws a model state error (as described in the question title) about Name
property being null.
I tried to examine the stack trace for more details about the exception but I couldn't gather more information other than what I already know:
e.StackTrace "
at System.Data.Entity.Core.Objects.ObjectContext.GetTypeUsage(Type entityCLRType)\r\n
at System.Data.Entity.Core.Objects.ObjectContext.ValidateEntitySet(EntitySet entitySet, Type entityType)\r\n
at System.Data.Entity.Core.Objects.ObjectContext.VerifyRootForAdd(Boolean doAttach, String entitySetName, IEntityWrapper wrappedEntity, EntityEntry existingEntry, EntitySet& entitySet, Boolean& isNoOperation)\r\n
at System.Data.Entity.Core.Objects.ObjectContext.AddObject(String entitySetName, Object entity)\r\n
at System.Data.Entity.Internal.Linq.InternalSet1.<>c__DisplayClassd.<Add>b__c()\r\n
1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)\r\n
at System.Data.Entity.Internal.Linq.InternalSet
at System.Data.Entity.Internal.Linq.InternalSet1.Add(Object entity)\r\n
1.Add(TEntity entity)\r\n
at System.Data.Entity.DbSet
at Microsoft.AspNet.Identity.EntityFramework.RoleStore`3.d__2.MoveNext()\r\n---End of stack trace from previous location where exception was thrown ---\r\n
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at Microsoft.AspNet.Identity.RoleManager2.<CreateAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
1.GetResult()\r\n at User_Manager_Interface.Controllers.RolesController.d__5.MoveNext() in C:\Users\Linda\UserManager\FSKUserManager\FSK_UserManager_Web\Controllers\RolesController.cs:line 104"
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter
new
modifier for your properties? It does not what you think. – Federico DipumaDbContext
is possibly not configured correctly. Your first problem is trying to useRoleManager<IdentityRole>
andRoleStore<IdentityRole>
with a derived type likeApplicationRole
(which is not mapped by default). I can't say more without seeing your entire Identity configuration. – Federico Dipuma