ViewModel instance is null on creating

2019-08-06 05:36发布

I created this view model class:

using System.Collections.Generic;
using Microsoft.Azure.ActiveDirectory.GraphClient;

namespace xx.Models.GlobalAdmin.Models
{
    public class UserViewModel
    {
        public  User Usuario { get; set; }
        public List<string> SelectedCompanies { get; set; }
    }
}

and I changed my Create.cshtml from the User class from Active directory to this:

@model CapatechSaasApp.Models.GlobalAdmin.Models.UserViewModel

and all the controls like this:

<div class="form-group">
    @Html.Label("Usuario", new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        <div class="input-group">
            @Html.EditorFor(model => model.Usuario.UserPrincipalName)
            <span class="input-group-addon" id="basic-addon2">@SettingsHelper.Domain.ToString()</span>
            @Html.Validatiomodel => model.Usuario.UserPrincipalName)
        </div>
    </div>
</div>

I also changed the Create action to this:

public async Task<ActionResult> Create(
    [Bind(Include = "UserPrincipalName,AccountEnabled,PasswordProfile,MailNickname,DisplayName,GivenName,Surname,JobTitle,Department"
                )] CapatechSaasApp.Models.GlobalAdmin.Models.UserViewModel user, FormCollection formCollection)
        {
            ActiveDirectoryClient client;
            try
            {
                client = AuthenticationHelper.GetActiveDirectoryClient();
            }
            catch (Exception)
            {
                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();
            }

            try
            {
                var usuario = user.Usuario.UserPrincipalName;
                user.Usuario.UserPrincipalName = usuario+SettingsHelper.Domain;
                user.Usuario.MailNickname = usuario;
                user.Usuario.AccountEnabled = true;
                await client.Users.AddUserAsync(user.Usuario);

                //Setting extended property lookup name
                var extPropLookupName = $"extension_{SettingsHelper.ClientId.Replace("-", "")}_{"Compania"}";

                //TO BE FINISHED
                user.Usuario.SetExtendedProperty(extPropLookupName, formCollection["Empresa"]);
                await user.Usuario.UpdateAsync();
                //Task.WaitAll();

                // Save the extended property value to Azure AD.
                user.Usuario.GetContext().SaveChanges();
                return RedirectToAction("Index");
            }
            catch (Exception exception)
            {
                ModelState.AddModelError("", exception.Message);
                return View();
            }
        }

However user.Usuario is always Null and I cant get the values typed on the form.

I guess there might be something wrong with

[Bind(
                    Include =

But I dont know what could it be or the syntax

1条回答
Explosion°爆炸
2楼-- · 2019-08-06 06:14

First of all I don't know what is worst, the magic string spread along the code, the ugly architecture or the fact that you basically add all mvc version tags to the question instead of the version you are working on.

That bind is a Model binder.

By the definition of Model Binder When "Create" is executed the MVC model binder will use the request parameters to populate the user parameter's properties, as you should know. However, the Bind attribute tells the model binder to only populate properties with names specified.

I beat "Usuario" is always null because you are not passing the property in this ugly and giant magic string

[Bind(Include = "UserPrincipalName,AccountEnabled,PasswordProfile,MailNickname,DisplayName,GivenName,Surname,JobTitle,Department"
查看更多
登录 后发表回答