Использование модальной начальной загрузки для отображения представления с помощью MVC5 / razor

#jquery #asp.net-mvc #twitter-bootstrap #razor

#jquery #asp.net-mvc #twitter-bootstrap #razor

Вопрос:

У меня есть представление списка пользователей, которое содержит foreach для отображения пользователей.

Имя пользователя становится интерактивным с помощью этого:

 @Html.ActionLink(item.UserName, "UserSetAccess", new { id=item.Id }, new{ @class = "dialog" } )
  

Отображаемый HTML:

 <a href="/Admin/UserSetAccess/37ebbad8-c952-4a75-91d2-197d78d1b175" class="dialog">testCustomer7@example.com</a>
  

Щелчок по ссылке запускает этот jQuery:

 $(function () {
    $('a.dialog').click(function () {
        var url = $(this).attr('href');
        var dialog = $('<div style="display:none"></div>').appendTo('body');
        dialog.load(url, {},
            function (responseText, textStatus, XMLHttpRequest) {
                dialog.dialog({
                    close: function (event, ui) {
                        dialog.remove();
                    }
                });
            });
        return false;
    });
});
  

На этой странице нет <form> тегов, но я установил точку останова как для действий GET, так и для POST UserSetAccess в контроллере, и единственное, что попадает, — это СООБЩЕНИЕ, которое портит диалоговое окно.

Почему .load() выдает POST вместо GET? Сначала должно появиться диалоговое окно, содержащее представление из GET, а затем разрешить изменения, чтобы я мог отправить их и опубликовать.

Кто-нибудь видит проблему с приведенным выше кодом или у него есть альтернативный способ заставить это работать правильно? Я исследовал .load () и не вижу нигде, где говорится, что он выдает POST.

Редактировать

По запросу я включаю методы действия контроллера. Оба они в значительной степени используются по умолчанию. Я закомментировал атрибут ValidateAntiForgeryToken в действии POST, потому что в нем была ошибка — вероятно, часть той же проблемы, что и в моем вопросе. Я разберусь с этой проблемой позже.

ПОЛУЧИТЬ действие контроллера:

     //
    // GET: /Admin/UserSetAccess/1
    public async Task<ActionResult> UserSetAccess(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var user = await UserManager.FindByIdAsync(id);
        if (user == null)
        {
            return HttpNotFound();
        }

        var userRoles = await UserManager.GetRolesAsync(user.Id);

        return View(new UserProfileViewModel()
        {
            Id = user.Id,
            Email = user.Email,
            IsApproved = user.IsApproved,
            Name = user.Name,
            Company = user.Company,

            RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
            {
                Selected = userRoles.Contains(x.Name),
                Text = x.Name,
                Value = x.Name
            })
        });
    }
  

Опубликовать действие контроллера:

     //
    // POST: /Admin/UserSetAccess/5
    [HttpPost]
    //[ValidateAntiForgeryToken]
    public async Task<ActionResult> UserSetAccess([Bind(Include = "Email,Id,IsApproved,Name,Company")] 
        UserProfileViewModel editUser, params string[] selectedRole)
    {
        if (ModelState.IsValid)
        {
            var user = await UserManager.FindByIdAsync(editUser.Id);
            if (user == null)
            {
                return HttpNotFound();
            }

            user.UserName = editUser.Email;
            user.Email = editUser.Email;
            user.IsApproved = editUser.IsApproved;
            user.Name = editUser.Name;
            user.Company = editUser.Company;

            var userRoles = await UserManager.GetRolesAsync(user.Id);

            selectedRole = selectedRole ?? new string[] { };

            var result = await UserManager.AddToRolesAsync(user.Id, selectedRole.Except(userRoles).ToArray<string>());

            if (!result.Succeeded)
            {
                ModelState.AddModelError("", result.Errors.First());
                return View();
            }
            result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(selectedRole).ToArray<string>());

            if (!result.Succeeded)
            {
                ModelState.AddModelError("", result.Errors.First());
                return View();
            }
            return RedirectToAction("Users");
        }
        ModelState.AddModelError("", "Something failed.");
        return View();
    }
  

Комментарии:

1. Не могли бы вы опубликовать свои два серверных метода (как GET, так и POST), включая любые атрибуты для них или классов.

2. Джастин, я отредактировал вопрос и включил оба действия контроллера. Спасибо.

Ответ №1:

Причина, по которой это POST происходит, заключается в том, что вы передаете объект .load() методу. Из документации jQuery:

Метод POST используется, если данные предоставляются в виде объекта; в противном случае предполагается GET .

Ваш код должен выглядеть примерно так:

 $(function () {
    $('a.dialog').click(function () {
        var url = $(this).attr('href');
        var dialog = $('<div style="display:none"></div>').appendTo('body');
        dialog.load(url,
            function (responseText, textStatus, XMLHttpRequest) {
                dialog.dialog({
                    close: function (event, ui) {
                        dialog.remove();
                    }
                });
            });
        return false;
    });
});
  

Обратите внимание, что я опустил {} в вызове .load() .