Luis Valencia
Luis Valencia

Reputation: 33998

How to bind a dictionary value to a column in asp.net mvc

I am using Active Directory Authentication Library to get a list of users in my active directory. The view is bound to the User class in this library.

@using Microsoft.Azure.ActiveDirectory.GraphClient
@model IEnumerable<User>


@{
    ViewBag.Title = "Index";
    Layout = "~/Areas/GlobalAdmin/Views/Shared/_LayoutGlobalAdmin.cshtml";
}
<h2>Usuarios</h2>

<div class="wrapper wrapper-content animated fadeInRight">
    <div class="row">
        <div class="col-lg-12">
            <div class="ibox float-e-margins">
                <div class="ibox-title">
                    <h5>Lista de Usuarios</h5>
                    <div class="ibox-tools">
                        @Html.ActionLink("Create New", "Create", null, new { @class = "btn btn-primary btn-xs" })
                    </div>
                </div>
                <div class="ibox-content">

                    <table id="directoryObjects" class="table table-bordered table-striped">
                        <tr>
                            <th>
                                UserPrincipalName
                            </th>
                            <th>
                                DisplayName
                            </th>
                            <th>
                                JobTitle
                            </th>
                            <th>
                                ObjectId
                            </th>
                            <th />
                        </tr>
                        @foreach (var item in Model)
    {
        var user = item as User;
                        <tr>
                            <td>
                                @Html.DisplayFor(modelItem => user.UserPrincipalName)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => user.DisplayName)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => user.JobTitle)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => user.ObjectId)
                            </td>
                            <td>
                                @Html.ActionLink("Edit", "Edit", new { objectId = item.ObjectId }) <br />
                                @Html.ActionLink("Details", "Details", new { objectId = item.ObjectId }) <br />
                                @Html.ActionLink("Delete", "Delete", new { objectId = item.ObjectId })  <br />
                                @Html.ActionLink("GroupMembership", "GetGroups", new { objectId = item.ObjectId }) <br />
                                @Html.ActionLink("DirectReports", "GetDirectReports", new { objectId = item.ObjectId }) <br />
                            </td>
                        </tr>
    }
                    </table>

                </div>
            </div>
        </div>
    </div>
</div>

However in Active Directory you can create custom properties, those properties are called Schema Extensions: FYI ONLY http://justazure.com/azure-active-directory-part-6-schema-extensions/

In my list of users some users have custom properties some others dont.

In my view I want to create a column to show the value of that custom property if it exists.

I know how to get the value server side, but I dont know how to bind it on the HTML

This is the index action in the users controller

 public async Task<ActionResult> Index()
    {
        var userList = new List<Microsoft.Azure.ActiveDirectory.GraphClient.User>();
        try
        {
            ActiveDirectoryClient client = AuthenticationHelper.GetActiveDirectoryClient();
            IPagedCollection<IUser> pagedCollection = await client.Users.ExecuteAsync();
            if (pagedCollection != null)
            {
                do
                {
                    List<IUser> usersList = pagedCollection.CurrentPage.ToList();
                    foreach (IUser user in usersList)
                    {
                        var usuarioAD = (Microsoft.Azure.ActiveDirectory.GraphClient.User)user;
                        var extendedProperties = usuarioAD.GetExtendedProperties();

                        foreach (var property in extendedProperties)
                        {
                            if (property.Key.Contains("Compania"))
                            {
                                string value = property.Value.ToString();
                            }
                        }

                        userList.Add((Microsoft.Azure.ActiveDirectory.GraphClient.User)user);
                    }
                    pagedCollection = await pagedCollection.GetNextPageAsync();
                } while (pagedCollection != null);
            }
        }
        catch (Exception e)
        {
            if (Request.QueryString["reauth"] == "True")
            {
                //
                // Send an OpenID Connect sign-in request to get a new set of tokens.
                // If the user still has a valid session with Azure AD, they will not be prompted for their credentials.
                // The OpenID Connect middleware will return to this controller after the sign-in response has been handled.
                //
                HttpContext.GetOwinContext()
                    .Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
            }

            //
            // The user needs to re-authorize.  Show them a message to that effect.
            //
            ViewBag.ErrorMessage = "AuthorizationRequired";
            return View(userList);
        }
        return View(userList);
    }

How can I bind the value? or maybe I can write a complex expression on the razor view without writing anything on the controller to get that value?

Upvotes: 1

Views: 485

Answers (1)

Frank Fajardo
Frank Fajardo

Reputation: 7359

I thought your question and name sounded familiar, and that's when I realised I gave an answer to your question earlier. And I think this question here is linked to that other question you had.

I don't quite get what your Index controller does, but it is probably not too important in answering your question.

I would not use a Dictionary property for your extended properties. Rather I would use a collection of objects of, say ExtendedProperty class, which consists of two properties: Name and Value.

So your User class would have this:

public IList<ExtendedProperty> ExtendedProperties

In your view, you'd do this... Note I would replace your foreach loop with a for loop.

@for(int a = 0; a < Model.Count(); a++)
{
    var user = Model[a];
    ...

    @if (user.ExtendedProperties != null
            && user.ExtendedProperties.Count() > 0) {
        for (int i = 0; i < user.ExtendedProperties.Count(); i++)
        {
            @Html.DisplayFor(m => m[a].ExtendedProperties[i].Name)
            @Html.DisplayFor(m => m[a].ExtendedProperties[i].Value)
        }
    }
}

Upvotes: 1

Related Questions