Фон
Я прочитал много других сообщений на этом сайте с похожими проблемами, но ничего конкретно не связанного с моим. Я также учусь в Uni и пытаюсь применить свое образование к реальным проблемам, чтобы получить более глубокое понимание MVC, но каждый шаг на этом пути был монументальным усилием. (мы изучали Laravel, что было еще сложнее). Это мой первый пост, и я с нетерпением жду вашей помощи.
Проблема
«Вход в систему» останавливает работу сообщений ajax.
У меня есть форма с выпадающими списками, которые заполняются из базы данных. Целью раскрывающихся списков является настройка строки заказа продукта. После изменения раскрывающегося списка он запускает публикацию ajax, которая отправляет детали формы обратно в метод контроллера, который ищет в базе данных строки упорядочивания, которые могут совпадать, и повторно заполняет форму только возможными параметрами на основе выбранной конфигурации.
Это отлично работает при анонимности, но при входе в систему он не пройдет через атрибут [ValidateAntiForgeryToken] на контроллере.
Все в порядке, когда я комментирую атрибут.
После небольшого исследования кажется, что проблема связана с тем, что токен настроен против имен пользователей, и при входе в систему имя пользователя изменяется, а хэш токена неверен.
Я пробовал AntiForgeryConfig.SuppressIdentityHeuristicChecks = true; в Application_Start() безрезультатно.
Если это так, то у меня 2 вопроса:
- Как обновить токен при входе в систему?
- Если я публикую раскрывающийся контент только через ajax, действительно ли мне нужно использовать токены защиты от подделки? (Я бы предположил, что они требуются для каждого поста).
- Нужен ли мне другой атрибут, например: [Авторизация] или [AllowAnonymous]?
Если не так, то что еще я мог посмотреть?
Просмотр (_config.cshtml)
@model HomeWeb.Models.RtcgConfigurationModel
@using (Html.BeginForm("updateDB", "Rtcg", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h3>Configure RTCG</h3>
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.RtcgCabinetType, "Cabinet Type", new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.DropDownListFor(model => Model.RtcgCabinetType, Model.Cabinets, new { onchange = "changed();" })
@Html.ValidationMessageFor(model => model.RtcgCabinetType)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RtcgAdaptorType, "Adaptor Type", new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.DropDownListFor(model => Model.RtcgAdaptorType, Model.Adaptors, new { onchange = "changed();" })
@Html.ValidationMessageFor(model => model.RtcgAdaptorType)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RtcgQtyAdaptors, "Adaptor Qty.", new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.DropDownListFor(model => Model.RtcgQtyAdaptors, Model.AdaptorQtys, new { onchange = "changed();" })
@Html.ValidationMessageFor(model => model.RtcgQtyAdaptors)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RtcgTerminationMethod, "Termination", new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.DropDownListFor(model => Model.RtcgTerminationMethod, Model.TerminationMethods)
@Html.ValidationMessageFor(model => model.RtcgTerminationMethod)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RtcgFaceplateStyle, "Faceplate Style", new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.DropDownListFor(model => Model.RtcgFaceplateStyle, Model.FacePlateStyles)
@Html.ValidationMessageFor(model => model.RtcgFaceplateStyle)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RtcgScreenPrinting, "Screenprinting", new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.DropDownListFor(model => Model.RtcgScreenPrinting, Model.ScreenPrintOptions)
@Html.ValidationMessageFor(model => model.RtcgScreenPrinting)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RtcgApplication, "Fibre Type", new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.DropDownListFor(model => Model.RtcgApplication, Model.Applications)
@Html.ValidationMessageFor(model => model.RtcgApplication)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RtcgVerminProof, "Vermin Proof", new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.DropDownListFor(model => Model.RtcgVerminProof, Model.VerminProofing)
@Html.ValidationMessageFor(model => model.RtcgVerminProof)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-5 col-md-10">
<input type="submit" value="Get Quotation" class="btn btn-primary" style="float: none" />
</div>
</div>
</div>
}
<script type="text/javascript">
function changed() {
var token = $('[name=__RequestVerificationToken]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
$.ajax({
url: '/Rtcg/Ajax_DropdownChanged',
type: "POST",
data: $('form').serialize(),
headers: headers,
success: function (result) {
$('#config-form').html(result);
},
})
}
</script>
Контроллер
// POST: handle dropdown changes from Ajax
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Ajax_DropdownChanged(RtcgConfigurationModel formData)
{
//handle 'postback' displaying the fields.
if (ModelState.IsValid)
{
RtcgConfigurationModel model = new RtcgConfigurationModel();
using (var db = new ApplicationDbContext())
{
model.Cabinets = DisplayElement.Cabinets(formData);
model.Adaptors = DisplayElement.Adaptors(formData);
model.AdaptorQtys = DisplayElement.AdaptorQuantities(formData);
model.TerminationMethods = DisplayElement.Termination(formData);
model.FacePlateStyles = DisplayElement.Faceplates(formData);
model.ScreenPrintOptions = DisplayElement.ScreenPrinting(formData);
model.Applications = DisplayElement.Application(formData);
model.VerminProofing = DisplayElement.VerminProof(formData);
}
return PartialView("_config", model);
}
else
{
return View();
}
}
ОБНОВЛЕНИЕ
Когда я не вошел в систему, я получаю одну строку токена.
"__RequestVerificationToken = Rt3m8M0YJeJ9u1TENd19Mx6wDxtU6FE208nRAOjo7Py6tkyH_pZdJfgPiXDt70UqJCf_fwasRA_7Ekc792khXWMXDzWS8x3wfXDoWNIZQVQ1 & RtcgCabinetType = RTC2G & RtcgAdaptorType = ЖК & RtcgQtyAdaptors = 06 & RtcgTerminationMethod = FS & RtcgFaceplateStyle = Z & RtcgScreenPrinting = SP & RtcgApplication = SM & RtcgVerminProof = N",
Однако при входе в систему я получаю 2 токена (даже если следую предложению Стивенса ниже и удаляю заголовок).
"__RequestVerificationToken = d21oW7noP0WBLI_3ubvpPo7uHYPbIrsq0VzeIXgNNaxmPiMiA8IBr2N2qU3wepup5X46gpy4VaFDc_MfUhCE-SADGhwplraMk4PFt-72GpnsxTeGW2COOggVhFEAXvRyb_ofh3d-ax3Zc1twpfenUw2 & __ RequestVerificationToken = v0g2f1ukJlO9g1WyXqh6GS3PB_YXHo9rY75BD1Wf8voQFMMbwDFE4nKJRV20orE5nm0EBIj4LOWlo_JdUfFvm2A-364nbEwEdEyHDcJ0tVjmqYTbH1AAorg0b347vSB3KLZ00sulasO9A9_28erP0A2 & RtcgCabinetType = RTC2G & RtcgAdaptorType = LCD & RtcgQtyAdaptors = 06 & RtcgTerminationMethod = FS & RtcgFaceplateStyle = Z & RtcgScreenPrinting = SP & RtcgApplication = SM & RtcgVerminProof = N",
headers["__RequestVerificationToken"] = token;
- ваш кодdata: $('form').serialize(),
уже сериализует токен и отправляет его в запросе. - person   schedule 21.06.2016$('#config-form').html(result);
, но показанная вами форма не имеетid="config-form"
, поэтому я предполагаю, что у вас должно быть 2 формы. Предлагаем вам начать с добавления атрибутаid
к форме, которую вы показали, а затем использоватьdata: $('#yourID').serialize(),
, чтобы обеспечить сериализацию только соответствующей формы. - person   schedule 21.06.2016