ASP.net MVC - Как да запазите модел върху различни изгледи

Ситуация: В някакъв софтуер за управление на проекти, написан на asp.net, имам страница за създаване на проект (работи добре). Трябва да добавя към това възможността за добавяне на задачи от списък с шаблони към това предварително създаване на проект, НО списъкът с налични задачи зависи от някои стойности, намиращи се във формуляра за създаване.

Моето абстрактно решение е следното:

  • Имам изглед „Създаване“ и изглед „Добавяне на задачи“ – и двата строго въведени към съставен viewModel, дефиниран в контролера
  • Моят метод Create проверява кой бутон е бил използван за извикването му - ако бутонът е бил „Добавяне на задачи“, той рендира изгледа AddTasks, предавайки модела от изгледа за създаване, отново в същия контролер.
  • Изгледът AddTasks публикува в изгледа Създаване с един от двата бутона, единият зарежда изгледа, а другият причинява действително запазване на DB.

Моят проблем е следният:

  • Различните изгледи използват различни свойства на един и същ модел, но при предаването на този модел между тях данните се нулират (при всички случаи презареждане или запазване).
  • Предполагам, че това се случва от автоматично обвързване на данни - въпреки че мислех, че полетата, които не присъстват във формуляра, няма да презапишат съществуващите данни на модела, предадени.
  • Едва ли има някакъв код в контролера, който манипулира модела в момента - той се предава само от изглед на изглед в тези случаи.

Това е кодът на контролера:

    // POST: /Project/Create/<viewModel>
    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind(Exclude = "Id,id")] ProjectViewModel model)
    {
        if (model.SubmitValue == "Create")
        {
            try
            {
                model.Project.Id = Guid.NewGuid();
                model.Save(this.User.Identity.Name);
                return this.RedirectToAction("Details", new {id = model.Project.Id});
            }
            catch (Exception e)
            {
                this.ModelState.AddModelError(e.ToString(), e.ToString());
            }
            return View(model);
        }

        if(model.SubmitValue == "AddTasks")
        {
            return this.View("AddTasks",model);
        }

        return this.View(model);

    }


    //POST: /Project/AddTasks/ + model
    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AddTasks([Bind(Include = SelectedCarrierTasks")]ProjectViewModel model)
    {
        return View(model);
    }

Въпросът е: Как да поддържам състоянието на модела в тези изгледи, докато най-накрая го запише?

Бих предпочел да избягвам всякакви хакерски (TempData) или зависими от JS решения, но не съм затворен за тях, ако наистина са най-доброто решение.

Благодаря, Адам Толи


person Adam Tolley    schedule 05.11.2009    source източник


Отговори (4)


В момента не мога да коментирам въпроси на други хора, но единствената реална опция е сесията, ако искате да запазите състояние на обекти по време на уеб заявки, или да го сериализирате и да го поставите в скрито поле.

Или крайната опция би била да промените начина, по който работят вашите страници, така че да можете да запазвате обекта след всяка заявка...

Ако използвате nHibernate, тогава може да искате да разгледате шаблона за разговори, но това просто запазва сесията на nHibernate в сесията на asp.net така или иначе...

person Andy Long    schedule 06.11.2009
comment
Ще отбележа това като отговор, тъй като това е най-пълният набор от опции и включва подхода NHibernate (въпреки че в момента съм останал с EF1). - person Adam Tolley; 06.11.2009

Едно просто решение е да запазите обекта ViewModel в променлива на сесията и да обвържете View от този източник. Това със сигурност не е най-елегантното решение. Друг вариант, и вероятно по-малко елегантен, е запазването на този модел данни в базата данни с някакъв временен/незаписан флаг.

person Oleiro    schedule 05.11.2009

Проблемът е, че когато показвате изгледа за добавяне на задачи, вие не предоставяте полета за вашия обект „Проект“, следователно ModelState губи данните, свързани с проекта, ще трябва да предоставите тези полета, за да сте сигурни, че няма да загубите тези данни .

Не е необходимо да показвате тези полета, те могат да бъдат от тип скрити и ще запазят стойността. Просто се уверете, че ако ще се обвързвате към модел на изглед, ще трябва да наименувате правилно тези полета като това Model.Project.Property.

person jgarcia    schedule 05.11.2009
comment
Така че мога да го поддържам, като го съхранявам от страна на клиента в скрити полета, има ли начин да не завися от хранилището от страна на клиента? Чувства се малко странно да натоварите страница и браузър с доста голям модел като този, само за да запазите различните методи/изгледи в същия контролер. Благодаря за вашето мнение - person Adam Tolley; 05.11.2009

Може би се опитвам да разреша грешния проблем (ала Брус Екел). Ще се опитам да премина към структура, която се нуждае по-малко от този вид размита граница. Не искам да възприема REST парадигма само за да я вкарам в приложение със състояние.

Вероятно тези контроли принадлежат на една и съща страница и мога да използвам някои JQuery добрини, които да поставя в панел с раздели за улеснение на очите.

Благодаря на тези, които отговориха, намерих всеки полезен и ще се опитам да не забравя да гласувам за тях веднага щом имам още представител.

person Adam Tolley    schedule 06.11.2009