2010-05-03 4 views
1

워크 플로가 두 개 있습니다.asp.net mvc - 워크 플로에서 페이지/컨트롤러 재사용

1) 사용자가 처음으로 가입합니다. 그들은 3 가지 화면, 기본 사용자 정보, 신용 카드 및 일부 추가 프로필 정보를 봅니다. 그들은 패션과 같은 마법사에서이 3 단계를 완료합니다. 유행 할 때마다 "제출"을하고 현재 화면을 떠나 다음 단계로 넘어갑니다.

2) 사용자가 이미 가입되어 있습니다. 그는이 3 개의 별도 페이지에 대한 탐색 링크를 가지고 있습니다. 그는 순서에 관계없이 업데이트 할 수 있습니다. 그가 구원을 쳤을 때 그는 자신이 속한 페이지를 떠나지 않고 상단에 "신용 카드 정보가 저장되었습니다 ..."또는 무엇이든 표시합니다. 어쩌면 아약스를 사용하거나 아마도 전체 페이지 새로 고침을 사용합니다.

두 개의 워크 플로우 사이에이 3 개의 화면에 대한보기뿐만 아니라 컨트롤러의 코드도 재사용하고 싶습니다. 그러나 if ... then 논리에 따라 다음 위치를 결정할 필요가 없습니다. 마법사의 첫 번째 가입 또는 프로필의 개별 부분 업데이트

아이디어가 있으십니까?

public ActionResult SomeAction(int foo, string bar) 
{ 
    MyViewModel model = repository.GetData(foo, bar); 
    return View("SomeView", model); 
} 

그래서 때, 컨트롤러 방법은 매우 슬림 유사해야

public ActionResult Index() 
    { 
     var model = this.GetModel(); 
     return this.View(Views.Index, model); 
    } 

    public ActionResult Save() 
    { 
     var model = this.GetModel(); 
     this.TryUpdateModel(model); 
     this.UserAccountRepository.Save(model.CurrentUser); 
     return this.RedirectToAction<EditCreditCardController>(c => c.Index()); 
    } 

    private EditCreditCardModel GetModel() 
    { 
     var model = new EditCreditCardModel(); 
     model.CCTypes = ModelHelper.PopulateDropDownWithModel(this.CardTypeRepository, this.CurrentUser.CreditCard.CardType); 
     model.States = ModelHelper.PopulateDropDownWithModel(this.StateRepository, this.CurrentUser.BillingAddress.State); 
     model.CurrentUser = this.CurrentUser; 
     return model; 
    } 
+0

클라이언트 측 마법사를 사용하여 단계별로 진행되는 모양을 사용자에게 제공하고 마지막 단계에서 모든 사항을 제출할 수 있습니까? 그렇게하면 한 가지 작업 만 처리 할 수 ​​있으며 요청에서 요청까지 사용자 상태를 넘겨 줄 걱정할 필요가 없습니다. – R0MANARMY

답변

0

을 엄지 손가락의 일반적으로 다음과 같습니다

코드의 종류 내가 재사용하기 위해 노력하고있어입니다 당신은 컨트롤러 재사용에 대해 이야기하고, 당신은 정말로 그것을 필요로하거나 사용해서는 안됩니다. 컨트롤러 로직을 재사용하는 것이 어려워지면 컨트롤러가 너무 뚱뚱하다는 뜻이며, 너무 많이하고있는 것입니다.

보기를 재사용하는 경우 부분보기를 신중하게 사용해야합니다. 좀 더 구체적 일지 모르지만 이러한 견해가 무엇인지 세부 사항을 모른 채로하기는 어렵습니다. 설정된 수의 사용자 프로필 필드와 같은 것이 부분보기에 배치하기가 매우 쉽습니다.


당신의 편집을보고 후, 내가 말할 수있는 최선은 GetModel() 방법은 컨트롤러의 일부가되지 않도록,이 모델의 일부가되어야합니다 (즉, 저장소 또는 어딘가에 서비스), 당신 때문에 이 5 줄의 코드를 다시 작성하지 않아도됩니다.

다른 말로하면 ... 나는 더 이상 추상적 인 것으로부터 당신이 얻을 수있는 것을 실제로 볼 수 없습니다. Index 메서드는 기술적으로 1로 줄일 수있는 두 줄의 코드이며 Save 메서드는 세 줄입니다 (네 번째 줄은 각 컨트롤러마다 다를 수있는 리디렉션입니다).

나는 모두 추상화와 코드 재사용에 찬성하지만, 단지 2 개의 다른 컨트롤러의 경우, 이미 가지고있는 것 (업데이트 된 코드 예제를 기반으로 한 것) 이상을 수행하려고 시도하는 것이 아마도 과도 할 것입니다 (GetModel 움직일 수있는 조각). 이 코드를 모두 반복하는 5 개 또는 20 개의 컨트롤러가있는 경우 CreditCardController 기본 클래스 또는 CreditCardHelper 유틸리티 클래스를 구현할 수 있습니다. 그러나 아직이 시점에서 컨트롤러 로직을 더욱 모호하게 할 것입니다.

+0

어쩌면 내가 뭔가 잘못하고있는 것 같지만 저장소에서 데이터를 가져 오는 것과 드롭 다운 등을 위해 선택 목록 개체를 채우는 것과 같은 단순한 작업만으로도 논리가있는 컨트롤러를 찾을 수 있습니다. – fregas

+0

public ActionResult Save() \t \t { \t \t \t var model = this.GetModel(); \t \t \t this.TryUpdateModel(model); \t \t \t this.UserAccountRepository.Save(model.CurrentUser); \t \t \t return this.View(Views.Index, model); \t \t } \t \t private EditCreditCardModel GetModel() \t \t { \t \t \t var model = new EditCreditCardModel(); \t \t \t model.CCTypes = ModelHelper.PopulateDropDownWithModel(this.CardTypeRepository, this.CurrentUser.CreditCard.CardType); \t \t \t model.States = ModelHelper.PopulateDropDownWithModel(this.StateRepository, this.CurrentUser.BillingAddress.State); \t \t \t model.CurrentUser = this.CurrentUser; \t \t \t return model; \t \t } fregas

+0

@fregas : 죄송합니다. 하지만 나는 그것을 실제로 읽을 수는 없습니다 ... 대신 질문에 그것을 추가하고 싶을 수도 있습니다. – Aaronaught

0

기본적으로 솔루션은 매우 간단하며 "CommonController"(또는 XController 또는 원하는 모든 컨트롤러)라는 새로운 추상 클래스의 컨트롤러를 만들고 실제 컨트롤러 대신 코드를 배치해야합니다.

public class HomeController : Controller 

새로운 컨트롤러를 생성하고 대신를 사용 :

public abstract class CommonController : Controller 

공지가에서 "추상적"키워드, 즉이다 당신이 일반적으로 컨트롤러를 만들 때 ,이 코드를 사용하다 유일한 차이점. 지금, 실제 컨트롤러에, 당신은 그들을 대신 일반 컨트롤러의 CommonController을 상속, 그래서 사용하는 대신해야

public class HomeController : CommonController 

을 지금,이 클래스에서 :

public class HomeController : Controller 

당신은 사용할 필요가 이제 통신에서 설정을 ViewData 변수의 모든 것을,했던 것을

public void CommonController() { 
ViewData["MyVariable"] = value; 
} 

: 대신 평소 ActionResult 방법, 당신은과 같이 설정 무효 방법이있을 것이다 onController는 컨트롤러에서 반환 된 Views에서 사용할 수 있습니다. 요약

: 는 다음과 같이 "CommonController"라는 새로운 컨트롤러를 설정 :

다음
public abstract class CommonController : Controller { 
    public void CommonController() { 
     // PUT ALL OF YOUR COMMON VARIABLES AND STUFF 
     // IN HERE! 
     ViewData["MyVariable"] = "BOB THE BUILDER!"; 
     if(isLoggedIn) { 
      ViewData["User"] = "BOB"; 
     }else{ 
      ViewData["User"[ = "Unknown User"; 
     } 
     // Etc, etc, etc. 
    } 
} 

기존의 컨트롤러가 기본 컨트롤러 클래스로 CommonController를 사용합니다에서

public class HomeController : CommonController { 
    public ActionResult Index() { 
     return View(); 
    } 
} 

당신의 보기, 당신은 < % = ViewData [ "MyVariable"] %>와 "BOB THE BUILDER!"라고 쓸 수 있어야합니다. 나타날거야! }

+0

그래, 상속을 사용하는 방법에 대해 생각했지만, 그때 하나의 기본 클래스에있는 모든 3 개의 스크린에 대한 모든 책임이 있습니다. 그것은 우려의 좋은 분리 것 같지 않습니다 ... – fregas

+0

아마도,하지만 적어도 한 번에 모든 마법사 로직을 넣을 수 있고 그것은 WizardController라고 할 수 있습니다 - 응용 프로그램의 나머지 부분은 일반 컨트롤러 클래스. –

관련 문제