#c# #asp.net-mvc #asp.net-identity
#c# #asp.net-mvc #asp.net-identity
Вопрос:
Извините за название, но я не знал, как объяснить это всего в одном предложении. У меня есть представление с формой:
@using (Html.BeginForm("AddComment", "Restaurants"))
{
@Html.TextBoxFor(c => c.NewComment.Body)
@Html.HiddenFor(m => m.Restaurant.Id)
<button type="submit">Add comment</button>
}
И действие AddComment в контроллере ресторанов:
public ActionResult AddComment(RestaurantViewModel model, Comment newComment)
{
var userId = User.Identity.GetUserId();
var user = _context.Users.FirstOrDefault(u => u.Id == userId);
newComment.RestaurantId = model.Restaurant.Id;
newComment.AuthorId = Guid.Parse(userId);
newComment.AuthorName = user.UserName;
newComment.DateTime = DateTime.Now;
_context.Comments.Add(newComment);
_context.SaveChanges();
return RedirectToAction("Details", "Restaurants", new { id = model.Restaurant.Id});
}
И я добавил фильтр авторизации:
filters.Add(new AuthorizeAttribute());
Когда я пытаюсь отправить форму от имени не зарегистрированного пользователя, она перенаправляет меня на страницу входа. Если я вхожу на эту страницу, она вызывает AddComment
действие, но передает аргументы Model.Restaurant
и NewComment.Body
в виде нулей. Как это исправить, чтобы при входе в систему меня перенаправляли на предыдущую страницу с заполненным текстовым полем или просто вызывали AddComment
, но передавали правильные значения аргументов.
Комментарии:
1. Если вы добавите фильтр, требующий авторизации пользователя при каждом действии, а пользователь не авторизован, что, по вашему мнению, должно было произойти? Рассматривали ли вы вместо этого требование авторизации только для методов действий, которым требуется авторизация?
2. Я ожидал чего-то подобного: я не вошел в систему => Я нажимаю кнопку Добавить комментарий => перенаправлен на страницу входа => Я вхожу в систему => перенаправлен на страницу с формой добавления комментария. В данный момент я получаю следующее: я не вошел в систему => Я нажимаю кнопку Добавить комментарий => перенаправлен на страницу входа => Я вхожу в систему => Вызывается действие AddComment, а переданные аргументы равны нулю. Если я нажму добавить комментарий, когда я уже вошел в систему, все работает, переданные аргументы в порядке.
Ответ №1:
Для этого нет встроенного способа. Причина в том, что это не «способ ведения дел». Если у вас есть форма с защищенным действием POST, также сделайте соответствующую страницу GET аутентифицированной-только для аутентификации.
Комментарии:
1. Использование
filters.Add(new AuthorizeAttribute());
означает, что каждое отдельное действие, независимо от его типа, защищено с помощью[Authorize]
. Это, безусловно, может произойти, если срок действия сеанса истек после перехода на эту страницу
Ответ №2:
Попробуйте удалить эту строку:
filters.Add(new AuthorizeAttribute());
И добавление обозначения [Authorize]
к вашему методу, например:
[Authorize]
public ActionResult AddComment(RestaurantViewModel model, Comment newComment)
{
var userId = User.Identity.GetUserId();
var user = _context.Users.FirstOrDefault(u => u.Id == userId);
newComment.RestaurantId = model.Restaurant.Id;
newComment.AuthorId = Guid.Parse(userId);
newComment.AuthorName = user.UserName;
newComment.DateTime = DateTime.Now;
_context.Comments.Add(newComment);
_context.SaveChanges();
return RedirectToAction("Details", "Restaurants", new { id = model.Restaurant.Id});
}
Ответ №3:
Я не предлагаю делать это за пределами простейших случаев. Вы можете изменить свою форму, чтобы использовать get
вместо post
:
@using (Html.BeginForm("AddComment", "Restaurants", FormMethod.Get))
{
@Html.TextBoxFor(c => c.NewComment.Body)
@Html.HiddenFor(m => m.Restaurant.Id)
<button type="submit">Add comment</button>
}
Предостережения:
- Это сработает, только если вы используете встроенную аутентификацию или ваша реализация пересылает значения querystring.
- Во-вторых, значения будут в URL, поэтому их можно легко подделать.
- И последнее, но не менее важное: если у
AddComment
естьHttpPost
атрибут, вам придется удалить его.