Как мне проверить различные разделы страницы MVC3 - PullRequest
1 голос
/ 01 апреля 2012

Я пытаюсь понять, как мне следует независимо проверять клиентские разделы моей страницы MVC3 и придумать простую версию того, чего я пытаюсь достичь.

Если я использую одну форму:
Плюсы: Когда я отправляю обратно в метод контроллера «PostData», я получаю все данные, содержащиеся в форме. В этом случае оба значения «имя» и «описание», что означает, что я могу создать экземпляр «PersonHobbyModel» и назначить данные, которые я получил. Я могу либо сохранить в базе данных, либо вернуть то же представление.

Минусы: я не могу проверить самостоятельно. Так что, если «имя» не заполнено, и я заполняю «описание», я все равно могу отправить страницу. (Это упрощенная версия того, что я пытаюсь сделать, и у меня будет больше полей, чем просто «имя» и «описание»)

с двумя формами: Плюсы: я могу проверить самостоятельно.

Минусы: метод контроллера получает только данные из замещенных форм, которые в данном случае либо «Имя человека», либо «Описание хобби», что означает, что я не могу воссоздать полный экземпляр «PersonHobbyModel».

Это модель:

 public class Person {

    [Display(Name = "Person name:")]
    [Required(ErrorMessage = "Person name required.")]
    public string Name { get; set; }
}

public class Hobby {

    [Display(Name = "Hobby  description:")]
    [Required(ErrorMessage = "Hobby description required.")]
    public string Description { get; set; }
}

public class PersonHobbyModel {

    public PersonHobbyModel() {
        this.Person = new Person();
        this.Hobby = new Hobby();
    }

    public Person Person { get; set; }
    public Hobby Hobby { get; set; }
}

Это контроллер:

 public class PersonHobbyController : Controller
{
    //
    // GET: /PersonHobby/

    public ActionResult Index()
    {
        var model = new PersonHobbyModel();
        return View(model);
    }


    public ActionResult PostData(FormCollection data) {
        var model = new PersonHobbyModel();

        TryUpdateModel(model.Person, "Person");
        TryUpdateModel(model.Hobby,"Hobby");

        return View("Index", model);
    }

}  

Это вид:

@model MultipleFORMStest.PersonHobbyModel
@{
    ViewBag.Title = "Index";
}
<h2>
    Index</h2>
@using (Html.BeginForm("PostData", "PersonHobby")) {
    <div>
        @Html.LabelFor(model => model.Person.Name)
        @Html.TextBoxFor(model => model.Person.Name)
        @Html.ValidationMessageFor(model => model.Person.Name)
        <input type="submit" value="Submit person" />
    </div>
}
@using (Html.BeginForm("PostData", "PersonHobby")) {
    <div>
        @Html.LabelFor(model => model.Hobby.Description)
        @Html.TextBoxFor(model => model.Hobby.Description)
        @Html.ValidationMessageFor(model => model.Hobby.Description)
        <input type="submit" value="Submit hobby" />
    </div>
    }

ОБНОВЛЕНИЕ 1
Я не упомянул, так как хотел, чтобы вопрос был как можно более простым, но для одного из разделов я использую «диалог jquery ui». Сначала я использовал DIV, чтобы определить диалог, который у меня был в моей основной форме. Это вызвало бы одну проблему, так как я не смог бы проверить на клиенте «диалоговую форму JQuery» независимо от остальной части формы.

Сказав, что этот jquery удалил «div jquery ui dialog» из основной формы, я заставил его включить этот диалог в его собственную форму. По этой причине я закончил с двумя формами. Преимущество заключается в том, что теперь я могу независимо проверять «форму пользовательского интерфейса jquery».

Но я не совсем понимаю, как мне обрабатывать на сервере данные, отправленные из различных форм на клиенте, поскольку есть вероятность, что у пользователя отключен JS. Если я отправляю из одной формы, я не могу получить доступ к данным в других формах.

ОБНОВЛЕНИЕ 2
Спасибо за ответы. Я считаю, что мне нужны две формы и две сущности, так как я хочу проверить их независимо на клиенте (за исключением того, что их заставляет JQuery UI Dialog). Например, если у меня есть, вместо одного хобби, у меня есть список хобби, которые я мог бы отображать в виде сетки в том же виде. Поэтому я не смог заполнить имя человека, но продолжаю добавлять хобби в таблицу. Если я не завершу описание хобби, я получу ошибку проверки. (Извините, но я включил оба моих обновления в первоначальный вопрос, но для ясности я хотел, чтобы это было как можно проще)

Ответы [ 2 ]

4 голосов
/ 01 апреля 2012

С моей точки зрения, у вас есть одна модель представления, которая соответствует двум моделям сущностей.На вашем месте я бы использовал одну форму и проверил модель представления, а не думал бы о ней как о двух (зависимых) сущностях.Получите модель представления в вашем действии вместо универсальной коллекции форм и используйте проверку на основе модели с помощью атрибутов аннотаций данных.Получив действительную опубликованную модель, вы можете затем преобразовать ее в соответствующие объекты и сохранить в базе данных.

Модель

public class PersonHobbyViewModel {

    [Display(Name = "Person name:")]
    [Required(ErrorMessage = "Person name required.")]
    public string Name { get; set; }

    [Display(Name = "Hobby  description:")]
    [Required(ErrorMessage = "Hobby description required.")]
    public string Description { get; set; }
}

Контроллер

public class PersonHobbyController : Controller
{
    //
    // GET: /PersonHobby/
    [HttpGet] // mark as accepting only GET
    public ActionResult Create() // Index should probably provide some summary of people and hobbies
    {
        var model = new PersonHobbyViewModel();
        return View(model);
    }

    [HttpPost] // mark as accepting only POST
    public ActionResult Create(PersonHobbyViewModel model) {

        if (ModelState.IsValid) {
           var person = new Person { Name = model.Name };
           var hobby = new Hobby { Description = model.Description };
           person.Hobbies = new List<Hobby> { hobby };

           db.Persons.Add( person );
           db.SaveChanges();
        }

        return RedirectToAction( "details", new { id = person.Id } ); // view the newly created entity
    }
}

Вид

@model MultipleFORMStest.PersonHobbyViewModel
@{
    ViewBag.Title = "Create";
}
<h2>
    Create</h2>
@using (Html.BeginForm("Create", "PersonHobby")) {
    <div>
        @Html.LabelFor(model => model.Person.Name)
        @Html.TextBoxFor(model => model.Person.Name)
        @Html.ValidationMessageFor(model => model.Person.Name)
        <input type="submit" value="Submit person" />
    </div>

    <div>
        @Html.LabelFor(model => model.Hobby.Description)
        @Html.TextBoxFor(model => model.Hobby.Description)
        @Html.ValidationMessageFor(model => model.Hobby.Description)
        <input type="submit" value="Submit hobby" />
    </div>
}
1 голос
/ 01 апреля 2012

Я думаю, что ваша ViewModel должна быть только специфичной для того представления, которое вы представляете.В этом случае я бы использовал ViewModel, подобный этому

public class AddPersonHobbyViewModel
{
  [Required]
  [Display (Name="Person Name")]
  public string PersonName { set;get;}

  [Required]
  [Display (Name="Hobby Description")]
  public string HobbyDescription { set;get;}

}

И в своем PostData ActionMethod я проверю проверку модели

[HttpPost]
public ActionResult PostData(AddPersonHobbyViewModel objVM)
{
  if(ModelState.IsValid)
  {
    // Everything is fine. Lets save and redirect to another get View( for PRG pattern)
  }
  return View(objVm);
}

И вы используете только одну форму в вашем представлениикоторый строго набран на AddPersonHobbyViewModel

@model AddPersonHobbyViewModel

@using (Html.BeginForm("PostData","Person"))
{
 @Html.TextBoxFor(m=>m.PersonName)
 @Html.ValidationMessageFor(m => m.PersonName)
 @Html.TextBoxFor(m=>m.HobbyDescription )
 @Html.ValidationMessageFor(m => m.HobbyDescription )
 <input type="submit" value="Save" />
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...