0

I have the following problem with passing data to metod create in controller. First I display view for method create (GET)

public ActionResult Create(string id)
        {
            RolesUser RolesUser = new RolesUser(id,repository.GetUserById(id).Roles, repository.GetRoles().ToList());          
            return View(RolesUser);
        }

I use the following ViewModel

public class RolesUser
    {
        public RolesUser()
        {

        }

        public RolesUser(string id,ICollection<IdentityUserRole> userRoles,List<IdentityRole> Roles)
        {
            userId = id;
            this.Roles = GetNewRolesForUser(userRoles.ToList(), Roles.ToDictionary(x => x.Id, x => x.Name)).ConvertAll(
                role =>
                {
                    return new SelectListItem()
                    {
                        Text = role.ToString(),
                        Value = role.ToString(),
                        Selected = false
                    };
                });
        }

        public IEnumerable<SelectListItem> Roles { get; set; }

        public string userId { get; set; }

        private List<string> GetNewRolesForUser(List<IdentityUserRole> UserRoles,Dictionary<string,string> Roles)
        {
            List<string> AvaiableRoles = new List<string>();
            List<string> IdUserRoles = new List<string>();
            UserRoles.ForEach(item => IdUserRoles.Add(item.RoleId));

            foreach(KeyValuePair<string,string> Role in Roles)
            {
                if (!IdUserRoles.Contains(Role.Key))
                {
                    AvaiableRoles.Add(Role.Value);
                }
            }
            return AvaiableRoles;
        }

    }

It displays me essential information on my view in Create.cshtml, when I execute Submit it shows me following error Object reference not set to an instance of an object.

The metod create (POST) looks like this

[HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles ="Admin")]
        public ActionResult Create([Bind(Include ="userId")] RolesUser user)
        {
            if (ModelState.IsValid)
            {
                try
                {

                    repository.AssignToRole(user.userId, "Klient");
                    repository.SaveChanges();
                }
                catch
                {
                    ViewBag.exception = true;
                    return View();
                }    
            }
            ViewBag.exception = false;
            return RedirectToAction("Index");
        }

Code for Create.cshtml

@model Repository.ViewModels.RolesUser

@{
    ViewBag.Title = "Create";
}

<h2>Dodaj poziom dostępu</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>@Model.userId</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.userId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DisplayFor(model => model.userId, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
        @Html.Label("Poziomy dostępu", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(m => m.userId, Model.Roles)
        </div>
        </div>



        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Dodaj" class="btn btn-default" />
            </div>
        </div>
    </div>
}

It looks like viewmodel is not passing to method, so I have null exception. But I don't understand why, if GET metod render properly view.

  • Where do your get the `NullReferenceException`? (it will certainly occur if you hit the `return View();` line of code in the POST method) –  Jul 29 '17 at 00:51

1 Answers1

0

The NullReferenceException is likely hit inside the repository.AssignToRole() method because user.userId is null. You should add a hidden input for the userId somewhere inside the form so the userId value is posted to the parameter object on the Create action. If you add it after the @Html.AntiForgeryToken() the start of the form would look like

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(model => model.userId)

    ...
  • Ok it works, but the same problem is with dropdowlistfor, where I select the role and this filed can;t be hidden. –  Jul 29 '17 at 07:10