Как выполнить проверку на стороне сервера без изменения ModelState при публикации AJAX в Controller в ASP.Net MVC

У меня есть контроллер Edit который делает вставку и обновление в то же действие. Там я делаю проверку против Active Directory, Приложение должно показывать ошибку проверки, если вставка не удалась из-за несоответствия имени пользователя, введенного пользователем и проверенного agaisnt. Active Directory, Поскольку в действии происходит несколько записей, вставка должна быть остановлена ​​для этого конкретного пользователя, даже если более поздние имена пользователей допустимы.

Проблема: Мой код в настоящее время использует проверку ModelState, но он не работает для передачи сообщения проверки в VIEW, потому что модель фактически не изменяла свое состояние в этом случае.

Вопрос: Как можно выполнить проверку на стороне сервера перед вставкой БД для определенного свойства модели (в данном случае имя пользователя)?

Предположение: Должен ли метод проверки имени пользователя возвращать само имя пользователя, которое затем может быть передано в представление для отображения сообщения об ошибке?

Ограничения: не могу использовать Annotation на модели IsRequired потому что это не обязательное поле. USer должен иметь возможность редактировать текущий список пользователей и сохранять его, даже если текстовое поле username пусто. Только когда имя пользователя введено в текстовое поле и вставка происходит, тогда требуется проверка. Не могу выполнить проверку на стороне клиента Active Directory так как это было бы тяжело. Это не полевая проверка, а проверка того, что неверные данные не попадают в БД.

Модель:

public class User
{
    [Key]
    public string username { get; set; } 

    [Key]
    public string role { get; set; }

}

Посмотреть:

@model List<Project.ViewModels.UserViewModel>
@using (@Html.BeginForm())
{
<table class="table">
    <tr>
        <th>User</th>
        @for (int i = 0; i < Model[0].Roles.Count; i++)
        {
            <th>
                @Model[0].Roles[i].RoleName
            </th>
        }
    </tr>
    @for (int i = 0; i < Model.Count; i++)
    {
        <tr>
            <td>                
                @if (Model[i].UserName == null)
                {
                    @Html.EditorFor(m=> m[i].UserName)
                    @Html.ValidationMessageFor(m=> m[i].UserName)
                    if (!ViewData.ModelState.IsValid)
                    {
                        <span class="field-validation-error">
                            @ViewData.ModelState["UserName"].Errors[0].ErrorMessage
                        </span>
                    }
                }
                else
                {
                    @Html.HiddenFor(m => m[i].UserName)
                    @Model[i].UserName
                }
            </td>
            @for (int j = 0; j < Model[i].Roles.Count; j++)
            {
                <td>
                    @Html.HiddenFor(m => m[i].Roles[j].RoleName)
                    @Html.CheckBoxFor(m => m[i].Roles[j].IsSelected)
                </td>
            }
        </tr>
    }    
</table>

<div class="form-actions">
    <button id="SubmitUserRoles" type="submit" class="btn btn-success submit" value="Save">Save</button>
</div>
}

<script>
    $("#SubmitUserRoles").click(function () {
        $.ajax({
            url: '@Url.Action("Edit", "Users")',
            type: 'POST',
            cache: false,
            data: JSON.stringify($('form').serialize()),
            success: function (data) {
                window.location.href = data
            }, error: function (xhr, ajaxOptions, error) {
                console.log(xhr.status);
                console.log("Error: " + xhr.responseText);
            }
        });
    });
});

контроллер:

[HttpPost]
    public ActionResult Edit(List<UserViewModel> model)
    {
        var level = model[0].Level;
        var location = model[0].Location;

        for (int i = 0; i < model.Count; i++)
        {
            if (model[i].UserName != null)
            {
                var uName = model[i].UserName;
                for (int j = 0; j < model[i].Roles.Count; j++)
                {

                    var uRole = model[i].Roles[j].RoleName;
                    var uRoleSelected = model[i].Roles[j].IsSelected;

                    var userWithSpecificRole = db.Users.FirstOrDefault(m => m.username == uName && m.role == uRole);

                    if (uRoleSelected && userWithSpecificRole == null)
                    {
                        if (DoesUserExist(uName))
                        {
                            if (ModelState.IsValid) 
                            { 
                                db.Users.Add(new User
                                {
                                   username = uName,
                                   role = uRole,
                                });                             
                                db.SaveChanges();
                            }
                        }
                        else
                            ModelState.AddModelError("UserName", "Username does not exist!");
                    }
                }
            }
        }
        return Json(Url.Action("Index", "Users", new {level,location}));
    }

Метод, который проверяет имя пользователя по Active Directory как следует:

    private bool DoesUserExist(string username)
    {
        PrincipalContext domain = new PrincipalContext(ContextType.Domain, "CompanyDomain", "DC=CompanyDomain,dc=com");

        UserPrincipal foundUser = UserPrincipal.FindByIdentity(domain, IdentityType.SamAccountName, username);

        return foundUser != null;
    }

0 ответов

Другие вопросы по тегам