Tôi biết nó không thực sự trả lời câu hỏi của bạn, nhưng chỉ để mở rộng nhận xét của tôi: -
có vẻ như bạn có một cái gì đó như: -
public class MyModel
{
[Required]
public string Foo { get; set; } // Populated in step 1
[Required]
public string Bar { get; set; } // Populated in step 2
}
Bạn gặp sự cố khi bạn BÀI ĐĂNG bước 1 vì người dùng chưa nhập giá trị cho Bar
, vì vậy, có ModelStateError
.
giải pháp ưa thích của tôi, chứ không phải cố gắng để mess xung quanh với xác nhận của mô hình kiên trì của bạn, sẽ được tách Xem thực hiện của bạn từ việc thực hiện mô hình của bạn với một ViewModel cho mỗi bước Wizard, ví dụ: -
public class MyModel
{
[Required]
public string Foo { get; set; }
[Required]
public string Bar { get; set; }
}
public class StepOneModel
{
[Required]
public string Foo { get; set; }
}
public class StepTwoModel
{
// This really depends on the behaviour you want.
// In this example, the model isn't persisted until
// the last step, but you could equally well persist
// the partial model server-side and just include a
// key in subsequent wizard steps.
[Required]
public StepOneModel StepOne { get; set; }
[Required]
public string Bar { get; set; }
}
hành động điều khiển của bạn trông giống như sau: -
public ActionResult StepOne()
{
return View(new StepOneViewModel());
}
[HttpPost]
public ActionResult StepOne(StepOneViewModel model)
{
if(ModelState.IsValid)
{
var stepTwoModel = new StepTwoViewModel()
{
StepOne = model
};
// Again, there's a bunch of different ways
// you can handle flow between steps, just
// doing it simply here to give an example
return View("StepTwo", model);
}
return View(model);
}
[HttpPost]
public ActionResult StepTwo(StepTwoViewModel model)
{
if (ModelState.IsValid)
{
// You could also add a method to the final ViewModel
// to do this mapping, or use something like AutoMapper
MyModel model = new MyModel()
{
Foo = model.StepOne.Foo
Bar = model.Bar
};
this.Context.MyModels.Add(model);
this.Context.SaveChanges();
}
return View(model);
}
xem StepOne của bạn trông giống như sau: -
@model StepOneModel
@using (html.BeginForm()) {
@html.EditorFor(x => x.Foo);
}
xem StepTwo của bạn trông giống như sau: -
@model StepTwoModel
@using (html.BeginForm("StepTwo")) {
@html.HiddenFor(x => x.StepOne);
@html.EditorFor(x => x.Bar);
}
Ưu điểm lớn so với chỉ tắt mô hình xác nhận là bạn có thể đặt các yêu cầu xác nhận cho bước hiện hành về ViewModel của bạn - bạn có thể đảm bảo rằng tất cả các các giá trị từ bước một là hợp lệ trước khi tiến hành bước hai.
Nếu bạn muốn có một cách tiếp cận RESTful hơn (nơi điều khiển của bạn không quan tâm rằng dữ liệu đến từ một cái nhìn kiểu wizard) một giải pháp phổ biến là để bọc từng bước trong một <div> client-side và sử dụng javascript để ẩn/hiển thị chúng khi người dùng tiến hành.
Nếu mô hình của bạn cần được duy trì giữa các bước, bạn sẽ cần phải suy nghĩ về ValidationAttributes trên mô hình của mình và ý nghĩa của chúng. Nếu bạn đã chú thích User.DateOfBirth
với Required
, nhưng bạn cần có khả năng tồn tại trước khi bước được điền, thì trên thực tế, User.DateOfBirth
không phải là yêu cầu (ví dụ: EF CodeFirst không thể tạo cột NOT NULL vì chúng tôi cần để có thể duy trì giá trị null trong thời gian chờ đợi). Bạn cần thực hiện một số xác thực có điều kiện (ví dụ: IValidatableObject, MvcFoolproof, Fluent Validation) để xác thực mô hình hoàn chỉnh của bạn sau này.
Cá nhân, tôi nghĩ rằng tôi muốn sử dụng một ViewModel khác nhau cho mỗi bước wizard. Điều này sẽ cho phép bạn sử dụng xác nhận nơi bạn cần nó (tức là trên các giá trị từ bước thủ thuật hiện tại!). –