我有一个视图,其中有两个部分,使用ajax将表单发布到操作。 onsuccess回调将用户重定向到另一个URL。但是,当模型状态无效时,我不希望调用此onsuccess函数。我已经尝试从我的控制器返回400级错误来触发onfailure函数,但它会导致一些奇怪的行为并且不会显示验证错误。这是我的代码
动作:
[AllowAnonymous]
[DisableCache]
public ActionResult Login(string returnUrl ="/") //This is the view that contains the two other partial views.
{
var path = VirtualPathUtility.ToAbsolute(returnUrl);
var url = new Uri(Request.Url, path).AbsoluteUri;
ViewBag.ReturnUrl = url;
return View();
}
[AllowAnonymous]
public ActionResult _LoginPartial()
{
return PartialView(new LoginModel());
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult _LoginPartial(LoginModel model)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
return PartialView();
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
Response.StatusCode = 400;
return PartialView(model);
}
登录视图:
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
</hgroup>
@section CustomScripts {
@if (ViewData.ModelState.IsValid){
<script type ="text/javascript">
function OnSuccess() {
var returnUrl = @Html.Raw(Json.Encode(ViewBag.ReturnUrl))
window.location = returnUrl;
}
function OnFailure() {
alert("Fail");
}
</script>
}
}
<section id="loginForm">
@{
if(!WebSecurity.IsAuthenticated){
<h2>Use a Creative Works account to log in.</h2>
@Html.Action("_LoginPartial")
@Html.ActionLink("Forgot your password?", "ResetPassword")
}
}
</section>
<section id ="RegisterForm">
@{
if(!WebSecurity.IsAuthenticated){
<span>Don't have an account? Make one!</span>
@Html.Action("RegisterPartial", new { returnUrl = ViewBag.ReturnUrl })
}
}
</section>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
_LoginPartial view
@model Cwo.Domain.Entities.LoginModel
@{
ViewBag.Title = "LoginPartial";
}
@using (Ajax.BeginForm("_LoginPartial",
new AjaxOptions(){UpdateTargetId = "loginForm",
InsertionMode = InsertionMode.Replace, OnSuccess = "OnSuccess", OnFailure = "OnFailure"
})) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Log in Form</legend>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</li>
<li>
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe, new { @class = "checkbox" })
</li>
</ol>
<input type="submit" value="Log in" />
</fieldset>
}
这里的格式有点混乱,对不起。我希望显示验证错误而不是警报(“失败”)响应。如果有更好的方法,而不是从行动中返回400级错误,请教我!
答案 0 :(得分:0)
我认为另一种解决问题的方法是你不希望执行onsuccess函数的内容吗?如果是这种情况,则将@if(ViewData.ModelState.IsValid){...}移动到OnSuccess函数内部。如果状态无效,那么该函数将没有任何内容,因此无法完成任务。
我个人喜欢将javascript与razor分开...更多的是,javascript应该驻留在自己的js文件中。在这种情况下,您可以使用razor将bool javascript变量设置为函数或对象构造函数,这样只有在变量为true时才能成功运行。