在ASP.NET MVC5中基于拆分视图模型的多步骤注册表单中实现Jquery Ajax
我使用了Darin Dimitrov的方法制作了一个多步骤的寄存器表单,经过解释,效果很好。 现在,我想使用jquery ajax而不是Html.Beginform()来处理“上一步”、“下一步”和“完成”按钮的提交事件 注:在ASP.NET MVC5中基于拆分视图模型的多步骤注册表单中实现Jquery Ajax,jquery,ajax,asp.net-mvc,wizard,multi-step,Jquery,Ajax,Asp.net Mvc,Wizard,Multi Step,我使用了Darin Dimitrov的方法制作了一个多步骤的寄存器表单,经过解释,效果很好。 现在,我想使用jquery ajax而不是Html.Beginform()来处理“上一步”、“下一步”和“完成”按钮的提交事件 注: 我将MVC5与.NET4.5.2一起使用 在我的第二步viewmodel中有fileupload和datetime属性 这是我的视图模型 [Serializable] public class RegisterWizardViewModel { publi
- 我将MVC5与.NET4.5.2一起使用
- 在我的第二步viewmodel中有fileupload和datetime属性
[Serializable]
public class RegisterWizardViewModel
{
public int CurrentStepIndex { get; set; }
public IList<IStepViewModel> Steps { get; set; }
public void Initialize()
{
Steps = typeof(IStepViewModel)
.Assembly
.GetTypes()
.Where(t => !t.IsAbstract && typeof(IStepViewModel).IsAssignableFrom(t))
.Select(t => (IStepViewModel)Activator.CreateInstance(t))
.ToList();
}
public interface IStepViewModel
{
}
[Serializable]
public class RegisterStep1ViewModel : IStepViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
[Serializable]
public class RegisterStep2ViewModel : IStepViewModel
{
[Display(Name = "FirstName", ResourceType = typeof(Resources.Resources))]
public string FirstName { get; set; }
[Display(Name = "LastName", ResourceType = typeof(Resources.Resources))]
public string LastName { get; set; }
[NonSerialized]
private HttpPostedFileBase _file;
public HttpPostedFileBase File
{
get
{
return _file;
}
set
{
_file = value;
}
}
[Display(Name = "BirthDay", ResourceType = typeof(Resources.Resources))]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}", ApplyFormatInEditMode = true)]
public DateTime? BirthDay { get; set; }
[Display(Name = "NationalCode", ResourceType = typeof(Resources.Resources))]
public int NationalCode { get; set; }
[Display(Name = "Gender", ResourceType = typeof(Resources.Resources))]
public bool IsMale { get; set; }
[Display(Name = "Mobile", ResourceType = typeof(Resources.Resources))]
public string MobilePhone { get; set; }
[Display(Name = "Country", ResourceType = typeof(Resources.Resources))]
public string Country { get; set; }
[Display(Name = "Address", ResourceType = typeof(Resources.Resources))]
public string Address { get; set; }
[MustBeTrue]
public bool CaptchaValid { get; set; }
}
}
我在registerwizard索引视图中使用了这个jquery代码通过ajax调用提交
@section scripts{
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script type="text/javascript">
$(function () {
$('form').on("submit", function (e) {
e.preventDefault;
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
window.location = result.url;
}
});
}
return false;
});
});
</script>
}
好的,如果有人面临这个问题并且可能有类似的问题,我将解释我的解决方法。
识别已提交表单的按钮的主要问题:
我添加了一个名为button的隐藏输入,并通过每个按钮上的点击事件jquery动态更改其名称,最后修改了我的控制器以从请求中获取此值。
以下是保存整个表单和我的控制器的后期操作的局部视图。
@using Microsoft.Web.Mvc
@model Models.RegisterWizardViewModel
@{
var currentStep = Model.Steps[Model.CurrentStepIndex];
}
@using (Html.BeginForm("Index", "RegisterWizard", FormMethod.Post, new { @class = "form-horizontal", role = "form", enctype = "multipart/form-data", @id = "mainRWF" }))
{
@Html.AntiForgeryToken()
@Html.Hidden("Button")
@Html.Serialize("wizard", Model)
@Html.Hidden("StepType", Model.Steps[Model.CurrentStepIndex].GetType())
@Html.EditorFor(x => currentStep, null, "")
if (Model.CurrentStepIndex > 0)
{
<div >
<input type="submit" value="Previous" name="prev" />
</div>
}
if (Model.CurrentStepIndex < Model.Steps.Count - 1)
{
<div >
<input type="submit" value="Next" name="next" />
</div>
}
else
{
<div >
<input type="submit" value="Submit" name="finish"/>
</div>
}
}
@使用Microsoft.Web.Mvc
@model Models.RegisterWizardViewModel
@{
var currentStep=Model.Steps[Model.CurrentStepIndex];
}
@使用(Html.BeginForm(“Index”、“RegisterWizard”、FormMethod.Post、new{@class=“form horizontal”、role=“form”、enctype=“multipart/form data”、@id=“mainRWF”}))
{
@Html.AntiForgeryToken()
@Html.Hidden(“按钮”)
@序列化(“向导”,模型)
@Html.Hidden(“StepType”,Model.Steps[Model.CurrentStepIndex].GetType())
@EditorFor(x=>currentStep,null,“”)
如果(Model.CurrentStepIndex>0)
{
}
if(Model.CurrentStepIndex
[ValidateAntiForgeryToken]
公共异步任务索引([反序列化]RegisterWizardViewModel向导,RegisterWizardViewModel.IStepViewModel步骤)
{
wizard.Steps[wizard.CurrentStepIndex]=步骤;
if(ModelState.IsValid)
{
if(Request.Form.GetValues(“按钮”)包含(“下一步”))
{
向导.CurrentStepIndex++;
}
else if(Request.Form.GetValues(“按钮”)包含(“prev”))
{
wizard.CurrentStepIndex--;
}
其他的
{
//用收到的值做一些事情
返回Json(新的{response=“Success”});
}
}
else if(Request.Form.GetValues(“按钮”)包含(“prev”))
{
//即使验证失败,我们也允许用户
//导航到前面的步骤
wizard.CurrentStepIndex--;
}
如果(!ModelState.IsValid),则为else
{
//如果我们走到了这一步,有些东西失败了,那么将它插入ajax的success func的html()中,重新显示有错误的表单
返回PartialView(“\u IndexPartial”,向导);
}
//返回下一步
返回PartialView(“\u IndexPartial”,向导);
}
显然我在上传文件时遇到了问题!并选择html5 formData作为ajax完成调用按钮的数据选项来处理上传。
为了使解决方案更好,我将对该解决方案发表评论 您可以使用@Ajax。BeginForm@BonMacalindong谢谢你的建议,但考虑到对Ajax调用的完全控制,我更喜欢使用jQueryAjax
@using (Html.BeginForm("Index", "RegisterWizard", FormMethod.Post, new { @class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
@Html.Serialize("wizard", Model)
@Html.Hidden("StepType", Model.Steps[Model.CurrentStepIndex].GetType())
@Html.EditorFor(x => currentStep, null, "")
if (Model.CurrentStepIndex > 0)
{
<div class="col-xs-9 col-sm-6 col-md-5 col-lg-5" style="padding-right:0px;">
<input type="submit" class="btn btn-default" value="Previous" name="prev" />
</div>
}
if (Model.CurrentStepIndex < Model.Steps.Count - 1)
{
<div class="col-xs-10 col-sm-8 col-md-6" style="">
<input type="submit" class="btn btn-default" value="Next" name="next" style="float:left;"/>
</div>
}
else
{
<div class="col-xs-3 col-sm-6 col-md-7 col-lg-7" style="padding-right:0px;">
<input type="submit" class="btn btn-default " value="Finish" name="finish" />
</div>
}
}
@using Microsoft.Web.Mvc
@model Models.RegisterWizardViewModel
@{
var currentStep = Model.Steps[Model.CurrentStepIndex];
}
@using (Html.BeginForm("Index", "RegisterWizard", FormMethod.Post, new { @class = "form-horizontal", role = "form", enctype = "multipart/form-data", @id = "mainRWF" }))
{
@Html.AntiForgeryToken()
@Html.Hidden("Button")
@Html.Serialize("wizard", Model)
@Html.Hidden("StepType", Model.Steps[Model.CurrentStepIndex].GetType())
@Html.EditorFor(x => currentStep, null, "")
if (Model.CurrentStepIndex > 0)
{
<div >
<input type="submit" value="Previous" name="prev" />
</div>
}
if (Model.CurrentStepIndex < Model.Steps.Count - 1)
{
<div >
<input type="submit" value="Next" name="next" />
</div>
}
else
{
<div >
<input type="submit" value="Submit" name="finish"/>
</div>
}
}
[ValidateAntiForgeryToken]
public async Task<ActionResult> Index([Deserialize]RegisterWizardViewModel wizard, RegisterWizardViewModel.IStepViewModel step)
{
wizard.Steps[wizard.CurrentStepIndex] = step;
if (ModelState.IsValid)
{
if (Request.Form.GetValues("Button").Contains("next"))
{
wizard.CurrentStepIndex++;
}
else if (Request.Form.GetValues("Button").Contains("prev"))
{
wizard.CurrentStepIndex--;
}
else
{
//Do stuff with received values
return Json(new { response = "Success" });
}
}
else if (Request.Form.GetValues("Button").Contains("prev"))
{
// Even if validation failed we allow the user to
// navigate to previous steps
wizard.CurrentStepIndex--;
}
else if (!ModelState.IsValid)
{
// If we got this far, something failed, redisplay form with errors by inserting this into html() of success func of ajax
return PartialView("_IndexPartial", wizard);
}
// return next step
return PartialView("_IndexPartial", wizard);
}