2010-10-25 24 views
33

Mam obecnie w moim kontrolerze metodę akceptującą zbiór formularzy, zapisującą dane, a następnie wyświetlającą dane na stronie "Szczegóły". W tej chwili, kod aktualnie wygląda mniej więcej tak:Przekierowanie ASP.NET MVC z modelem

[HttpPost] 
public ActionResult Create(PersonModel person)<br> 
{ 
    if (person.IsValid()) 
    { 
     person.additionalData = "Person created successfully"; 
     return View("Details", person); 
    } 
} 

Problem polega na tym, że powrót widoku szczegółów w ten sposób zachowuje URL mojawitryna/osoba/Create - idealnie chciałbym URL być mojawitryna/osoba/Szczegóły/IdGoesHere.

Jestem pewien, że to musi być możliwe. Oczywiście mógłbym użyć Response.Redirect, ale to nie pozwala mi przekazać modelu do widoku. O ile mogę powiedzieć, nie mogę przekazać modelu za pomocą RedirectToAction?

Dzięki za pomoc.

EDYCJA: Aby potwierdzić - model utworzony przez akcję Utwórz jest inny niż domyślny utworzony przez akcję Szczegóły. Dlatego wykonanie prostego przekierowania do działania i przekazanie Id nie działa, ponieważ wyprodukowany model nie jest poprawny. Aby podać więcej kontekstu, model z akcji Utwórz zawiera dodatkową wartość mówiąc "Osobiście utworzono pomyślnie", jeśli przekierowuję do akcji Szczegóły, ten komunikat nie jest obecny w modelu.

Odpowiedz

29

user460667,

prosto z własnej aplikacji:

public ActionResult Create(Booking item) 
{ 
    if (ModelState.IsValid) 
    { 
     int newID = _tasks.Create(item); 
     // NEW section to emulate model being populated for use in Details view 
     TempData["additionalData"] = "Person created successfully"; 
     return RedirectToAction("Details", new { id = newID }); 
    } 
    else 
    { 
     return View(); 
    } 
} 

wtedy nie mógł swoje dane działanie będzie tak:

public ActionResult Details(int id) 
{ 
    var item = _tasks.GetByKey(id); 
    var additionalData = TempData["additionalData"]; 
    if(item != null) { 
     if(additonalMessage!=null) 
     { 
      item.additionalData = additionalData; 
     } 
     return View(item); 
    } 
    else 
     return View("Notfound"); 
} 

nie można przyjąć podobne podejście?

[edytuj]:

użytkownik ponownie swój EDIT. nie możesz po prostu wykonać przekierowania zgodnie z konwencją i ustawić flagę (na tempdata jak wyżej), która przekazuje tę wiadomość? flaga tempadata byłaby TYLKO ustawiona w akcji tworzenia, dlatego może się zdarzyć tylko przy tworzeniu nowego obiektu "osoba". W ten sposób działanie Szczegóły będzie zawsze tylko pokazać go jako konsekwencja działania Tworzenie

+3

To jest droga.Jeśli prosta wiadomość w tempdata nie wystarczy, możesz po prostu rzucić cały obiekt "PersonModel" w tempdata i odzyskać go z tempdata w metodzie akcji "Szczegóły". – Charlino

6

Powinieneś przenieść się do Modelu szczegółowego, przekazując identyfikator.

return RedirectToAction("Details", new { id = person.PersonID }); 
+0

Witaj, problem polega na tym, że domyślne działanie nie wypełnia modelu tymi samymi danymi, które pochodzą z akcji "Utwórz". Patrząc na inne odpowiedzi, najlepszym rozwiązaniem wydaje się być TempData. – user460667

+1

Można utworzyć metodę InitializeModel, która wszystkie dane przypisuje magii dla ciebie .. –

6

Umysł można również przyjąć podejście typu bezpieczny z MvcContrib i zrobić

return this.RedirectToAction<MyController>(c => c.Details(person.PersonID)); 
+0

A jeśli nie chcesz pełnej mocy MvcContrib, możesz użyć MvcNavigationHelpers na https://github.com/uglybugger/MvcNavigationHelpers –

8

Można uzupełnienia tego, co zostało zaproponowane (wykorzystanie RedirectToAction i routing) z wykorzystaniem TempData

[HttpPost] 
public virtual ActionResult Create(IEnumerable<OrderItem> orderItems) 
    { 
     if (orderItems.Count() == 0) 
     { 
      return RedirectToAction("NoOrderItems"); 
     } 
     else 
     { 
      TempData["orderItems"] = orderItems; 
      return RedirectToAction("Confirm"); 
     } 
    } 

    [HttpGet] 
    public virtual ActionResult Confirm() 
    { 
     var orderItems = TempData["orderItems"] as IEnumerable<OrderItem>; 
     if (orderItems == null || orderItems.Count() == 0) 
     { 
      this.InvokeHttp404(ControllerContext.HttpContext); 
     } 

     return View(orderItems); 
    } 

używam tego dla elementów, które nie chcą, aby ponownie utworzyć na kolejnych żądań lub utrzymują dość jeszcze w bazie danych jeszcze. W związku z tym nie potrzebuję w moim odczuciu kontroli zerowej, ponieważ strona "Potwierdź" może zostać "zdobyta" jedynie, jeśli istnieją dla niej dane.

+0

świetny kod, którego nie testowałem jeszcze, ale wkrótce muszę pracować nad takim komponentem, mam pytanie, co jeśli odświeżę stronę, to zadziała lub tempdata się skończy –

Powiązane problemy