#asp.net-mvc-5 #ajax.beginform
#asp.net-mvc-5 #ajax.beginform
Вопрос:
Я пытаюсь использовать Ajax.BeginForm, чтобы я мог передать значение флажка в действие моего контроллера.
Я использовал @Ajax.ActionLink, но я не могу получить значение недавно введенного флажка, поэтому я хочу использовать Ajax.BeginForm в будущем.
Начиная с @Ajax.ActionLink работает в представлении, я предполагаю, что Ajax работает должным образом, поэтому я могу это исключить.
Вот несколько вариантов, которые я пробовал. Когда я наводлю курсор на кнопки, они обе отображают URL моей веб-страницы вместо URL контроллера и действия. Когда я нажимаю на кнопки, страница в основном обновляется вместо вызова действия getCode в контроллере PublicOffers.
Любая помощь очень ценится! Спасибо!
Вариант 1
<div>
@using (Ajax.BeginForm("GetCode", "PublicOffers", null, new AjaxOptions()
{
UpdateTargetId = "detailsDiv",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
OnBegin = "onStart",
OnComplete = "onComplete",
OnSuccess = "myCallback"
}))
{
//bool checkedOption = false;
//@Html.CheckBoxFor(x => checkedOption, new { Name = "OptIn" })
@Html.CheckBoxFor(model => model.OptIn);
@Html.HiddenFor(model => model.Id);
<input type="submit" value="Get Code" class="button btn-primary" />
}
</div>
Вариант 2
<div>
@using (Ajax.BeginForm(new AjaxOptions()
{ HttpMethod = "GET",
Url = "PublicOffers/GetCode",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "detailsDiv",
OnBegin = "onStart",
OnComplete = "onComplete",
OnSuccess = "myCallback"
}))
{
//bool checkedOption = false;
//@Html.CheckBoxFor(x => checkedOption, new { Name = "OptIn" })
@Html.CheckBoxFor(model => model.OptIn)
//@Html.HiddenFor(model => model.Id, new { Name = "OfferId" })
@Html.HiddenFor(model => model.Id);
@Html.AntiForgeryToken()
<input type="submit" value="Submit" />
}
</div>
Комментарии:
1. Можете ли вы предоставить код контроллера для варианта 1?
2. Я добавил это в свой ответ, чтобы люди могли видеть, как передать значение флажка контроллеру.
Ответ №1:
Это не совсем ответ, но он может помочь.
Сначала убедитесь, что у вас есть это, я использую NuGet для его установки, Microsoft.jQuery.Ненавязчивый.Ajax
Затем убедитесь, что она отправляется на страницу либо через bundle scripts, либо через ссылку на скрипт в cshtml
Сначала простая модель…
namespace AjaxTest.Models
{
public class AjaxTestModel
{
public bool OptIn { get; set; }
}
}
Далее немного cshtml…
@model AjaxTest.Models.AjaxTestModel
@{ ViewBag.Title = "AjaxTest1";}
<h2>AjaxTest1</h2>
@using (Ajax.BeginForm("AjaxTest1", "Home", null,
new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "OnSuccess(xhr)",
OnFailure = "OnFailure(xhr, status)"
},
new { id = "myform" }))
{
@Html.CheckBoxFor(model => model.OptIn);
<span id="lbl_message"></span>
<br />
<button id="btn_submit" type="submit" class="">Submit</button>
}
@section scripts{
<script>
$(document).ready(function () {
console.log("ready to rock and roll....");
});
function OnBegin() {
console.log("OnBegin");
}
function OnSuccess(xhr) {
console.log("OnComplete");
$("#lbl_message").text("Ok:" xhr.responseJSON.param2);
}
function OnFailure(xhr, status) {
console.log("OnFailure");
$("#lbl_message").text("Error:" xhr.responseJSON.param2);
}
</script>
}
Волшебство заключается в контроллере, обратите внимание, что я возвращаю объект Json, а не представление.
public class HomeController : Controller
{
public ActionResult AjaxTest1()
{
AjaxTestModel model = new AjaxTestModel();
return View();
}
[HttpPost]
public ActionResult AjaxTest1(AjaxTestModel model)
{
if (model.OptIn)
{
dynamic errorMessage = new { param1 = "param1", param2 = "You opted in." };
HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
return Json(errorMessage, JsonRequestBehavior.AllowGet);
}
else
{
dynamic errorMessage = new { param1 = "param1", param2 = "You opted out." };
HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
return Json(errorMessage, JsonRequestBehavior.AllowGet);
}
}
}
Обратите внимание, HttpContext.Response.StatusCode будет определять, какой обратный вызов Ajax активирован, возвращать HttpStatusCode.Ок, и onSuccess будет вызван, верните HttpStatusCode.Не найден или почти любой другой код ошибки, и будет вызван сбой.
Комментарии:
1. Спасибо за помощь! У меня получилось, но я не использовал ваш метод. Пожалуйста, смотрите мой ответ ниже. Я понятия не имею, почему это работает.
2. Если это помогло, вы можете щелкнуть значок «помогло», повысить мою репутацию :))
Ответ №2:
Я заставил это работать, добавив метод beginform.BeginForm для начала. Это почти так, как будто первый экземпляр вызывает второй метод Ajax.BeginForm. Поскольку в первом методе нет кнопки или чего-либо еще, на странице ничего не отображается.
ПРИМЕЧАНИЕ: Я изменил свой Get на Post, чтобы атрибут [ValidateAntiForgeryToken] работал для действия контроллера. Я читал, что это не сработало бы с Get.
<div>
@using (Ajax.BeginForm("GetCode", "PublicOffers", new { offerId = Model.Id }, new AjaxOptions()
{
//Nothing here, but for some reason without this code the Ajax.BeginForm below won't work
}))
{
//Nothing here, but for some reason without this code the Ajax.BeginForm below won't work
}
</div>
<div>
@using (Ajax.BeginForm("GetCode", "PublicOffers", new { offerId = Model.Id },
new AjaxOptions { OnBegin = "onStart", UpdateTargetId = "detailsDiv",
InsertionMode = InsertionMode.Replace, HttpMethod = "Post",
OnComplete = "onComplete",
OnSuccess = "myCallback"},
new { @style = "display:inline-block" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
@Html.CheckBoxFor(model => model.OptIn, new { Name = "optIn"})
</div>
</div>
<input type="submit" class="button btn-primary" value="Get Code" id="get-code button" />
}
</div>
Вот мое действие контроллера.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> GetCode(Guid offerId, bool optIn = false)
{
//Code here
return PartialView("_OfferCode");
}