Я работаю над проектом с использованием MVC3. Сначала я создал базу данных (с необходимыми ограничениями, такими как PK и FK) и добавил эту базу данных в мое веб-приложение, используя модель данных объекта ADO.NET. Кажется, все работает нормально, но я не могу сделать проверку гибкой. Вот код, чтобы прояснить мой вопрос.
Редактировать: добавлен вид + правильных моделей. Эта версия без импорта базы данных, но результаты те же.
- Модели ----
namespace CustomValidation.Models
{
public class Person : IValidatableObject
{
public int Id { get; set; }
[Required]
public String FirstName { get; set; }
[Required]
public String LastName { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (String.IsNullOrEmpty(FirstName))
{
var field = new[] { "FirstName" };
yield return new ValidationResult("Firstname can't be null", field);
}
}
}
}
namespace CustomValidation.Models
{
public class Address : IValidatableObject
{
public int Id { get; set; }
[Required]
public String Streetname { get; set; }
[Required]
public String Zipcode { get; set; }
[Required]
public String City { get; set; }
[Required]
public String Country { get; set; }
public Person Person { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (String.IsNullOrEmpty(Streetname))
{
var field = new[] { "Streetname" };
yield return new ValidationResult("Streetname can't be null", field);
}
}
}
}
public class MasterModel
{
public List<Address> Addressess { get; set; }
public Person Person { get; set; }
}
}
namespace CustomValidation.Models
{
public class DBEntities : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<Address> Addressess { get; set; }
}
}
---- контроллер ----
namespace CustomValidation.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
MasterModel Model = new MasterModel();
Model.Person = new Person();
Model.Addressess = new List<Address>();
Model.Addressess.Add(new Address());
Model.Addressess.Add(new Address());
return View(Model);
}
[HttpPost]
public ActionResult Index(MasterModel Model)
{
DBEntities _db = new DBEntities();
if (TryValidateModel(Model.Person))
{
_db.People.Add(Model.Person);
_db.SaveChanges();
}
else
{
return View(Model);
}
for (int i = 0; i < Model.Addressess.Count; i++)
{
if (!String.IsNullOrEmpty(Model.Addressess[i].Country))
{
if (TryValidateModel(Model.Addressess[i]))
{
Model.Addressess[i].Person = Model.Person;
_db.Addressess.Add(Model.Addressess[i]);
_db.SaveChanges();
}
else
{
return View(Model);
}
}
}
return RedirectToAction("Index");
}
}
Вот мой взгляд:
@model CustomValidation.Models.MasterModel
@{
ViewBag.Title = "Index";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>
<div class="editor-label">
@Html.LabelFor(m => Model.Person.FirstName)
@Html.EditorFor(m => Model.Person.FirstName)
</div>
<div class="editor-label">
@Html.LabelFor(m => Model.Person.LastName)
@Html.EditorFor(m => Model.Person.LastName)
</div>
</fieldset>
for (int i = 0; i < Model.Addressess.Count; i++)
{
<fieldset>
<legend>Address</legend>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Streetname)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Addressess[i].Streetname)
@Html.ValidationMessageFor(model => Model.Addressess[i].Streetname)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Zipcode)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].Zipcode)
@Html.ValidationMessageFor(model => Model.Addressess[i].Zipcode)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].City)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].City)
@Html.ValidationMessageFor(model => Model.Addressess[i].City)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Country)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].Country)
@Html.ValidationMessageFor(model => Model.Addressess[i].Country)
</div>
</fieldset>
}
<p>
<input type="submit" value="Create" />
</p>
}
Проблема (которую я заметил при отладке чего-то подобного) заключается в том, что перед тем, как запрос попадет внутрь моего действия, MVC сначала запускает валидаторы для вашей коллекции. Поэтому, если я только заполнил Person в своей форме, проверяя Model.Person, он просто возвращает false (я думаю, из-за обязательных полей для Address), и поэтому он возвращается к моему представлению.
Мне нужен какой-то обходной путь, который позволил бы мне решить, какие экземпляры моей коллекции я хочу проверить в своем действии.
Я не смог найти никакого решения после долгого поиска в сети.
Я надеюсь, что кто-то может мне помочь.
PS. Я довольно новичок в Visual Studio и MVC 3, поэтому, пожалуйста, не обращайте на меня внимания:)