1

Previously on a View to Admin users in my MVC application (was MVC4/EF5), I was using Grid.MVC to easily display my users and set Data Annotations on my Model to quickly set how I wanted each model property to display within the Grid.

View:

<!-- Grid.MVC Code -- Can no longer use with Auto-Generated ASP.Net IDENTITY properties-->
    <div>
        @*Images in Columns: https://gridmvc.codeplex.com/discussions/440977*@

        Html.Grid(Model).Columns(columns =>
        {
            //columns.Add().Encoded(false).Sanitized(false).SetWidth(30).RenderValueAs(o => @Html.CheckBox("checked", false));
            columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => Html.ActionLink("Edit", "Edit", "UserManage", new { id = o.Id }, null));
            columns.Add().Encoded(false).Sanitized(false).RenderValueAs(u => Html.ActionLink("Delete", "Delete", "UserManage", new { id = u.Id }, null));
            columns.Insert(2, u => u.ProfilePictureUrl).Titled("User Img").Encoded(false).Sanitized(false).RenderValueAs(u => @<img class="" src="@u.ProfilePictureUrl" alt="Current Profile Image" width="75px" height="75px" />);

        }).AutoGenerateColumns()
    </div>

Annotation Example on Model:

public class ApplicationUser : IdentityUser
    {
        // Setting GridColumn Annotations allows you to use AutoGenerateColumns on view to auto create the Grid based on the model. https://gridmvc.codeplex.com/
        [Display(Name = "Name")]
        [GridColumn(Title = "Name", SortEnabled = true, FilterEnabled = true, Width = "100")]
        public string Name { get; set; }

        [Display(Name = "Position")]
        [GridColumn(Title = "Position", SortEnabled = true, FilterEnabled = true, Width = "50")]
        public string Position { get; set; }

        [NotMappedColumn]
        public DateTime? RegisteredDate { get; set; }

After attending Microsoft TechED it became viable while still in Development to move to MVC5/EF6, primarily to make use of ASP.Net Identity. In the new project where I am copying everything so far completed over, I was able to replicate my use of Grid.MVC but with one minor issue: the new ASP.Net has several User properties not explicitly listed in the model which are also showing up in my Grid.MVC such as the fields [PasswordHash], [SecurityStamp], [AccessFailedCount], and more found in table [AspNetUsers].

Since these Identity properties are not explicitly within my Model, I cannot use GridMvc.DataAnnotations to set them as [NotMappedColumn].

My new View code looks like the following:

@model IEnumerable<PROJECT.Models.ApplicationUser>

@{
    ViewBag.Title = "View Users";
    Layout = "MyLayout.cshtml";
}

<div class="row" id="submitRow">
    <div class="btn-group ">
        <a href="Create"><button type="submit" value="Create" class="btn btn-success">Create User</button></a>
    </div>
</div>

<div class="overflowPrevention">
    <table class="table">
        <tr>
            <th></th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                Img
            </th>
            <th>
                Position
            </th>
            <th>
                Registered
            </th>
            <th>
                Last Visited
            </th>
            <th>
                Email
            </th>
            <th>
                Confirmed
            </th>
            <th></th>
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.ActionLink("Edit", "Edit", "UserManagement", new { id = item.Id }) |
                    @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                    @Html.ActionLink("Delete", "Delete", new { id = item.Id })
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ProfilePictureSrc)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Position)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.RegisteredDate)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.LastVisitDate)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Email)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.EmailConfirmed)
                </td>
            </tr>
        }

    </table>

I've got all the fields I want correctly display in my Grid and am now working on the Actionlinks for Edit, Details, and Delete. Starting with Edit, I can't seem to figure out where my syntax is off as the Edit link doesn't link to the individual user ID but instead links to the following path:

local:12345/Admin/UserMgmt/Edit?Length=14

Anyone have thoughts on the matter?

tereško
  • 58,060
  • 25
  • 98
  • 150
Analytic Lunatic
  • 3,853
  • 22
  • 78
  • 120

1 Answers1

3

These are the different overloads of Html.ActionLink.

What you intend to do is

[DisplayText][ActionMethod][Controller][RoutingValues]

However when we look at the 4-argument constructor, we see this:

ActionLink(HtmlHelper, String, String, Object, Object)

Returns an anchor element (a element) for the specified link text, action, route values, and HTML attributes.

Which is not what you want. However, this overload has those fields:

ActionLink(HtmlHelper, String, String, String, Object, Object)

Returns an anchor element (a element) for the specified link text, action, controller, route values, and HTML attributes.


Solution

Change this

@Html.ActionLink("Edit", "Edit", "UserManagement", new { id = item.Id })

Into this

@Html.ActionLink("Edit", "Edit", "UserManagement", new { id = item.Id }, null)
Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170