2013-09-25 7 views
2

는 요구가 성공적으로 ASP.NET MVC 컨트롤러에서 모델을 저장 한 후 다른 페이지로 리디렉션하는 말 작업 :리디렉션 후 부분 뷰에 저장

@{ 
    Layout = "my layout"; 

    Html.RenderAction("something else, a view for example"); 
    Html.RenderAction("Index action of the above controller"); // <---- 
} 

이 경우 RedirectResult 클래스에서 확인하고 상황에 맞는 아이의 행동이 있음을 확인하고 예외를 슬로우 것 "자식 작업은 작업을 재 수행 할 수 없습니다."

응답 스트림에 쓰기가 이미 진행 중이며 여기에서 리디렉션 할 수는 없지만 컨트롤러에서 서버 측 작업을 수행 한 후에도 해당 작업이 자식 인 경우에도 다른 페이지로 리디렉션 할 수 있어야한다는 것을 알고 있습니다. 동작. Layouts 및 RenderActions를 사용하여 페이지 디자인의 공유 부분을 다시 사용합니다.

그런 컨트롤러에서 어떻게 리디렉션을 구현 하시겠습니까?

편집 :

주요 목표는 특정 작업을하고 일부 데이터를 표시하거나 편집 양식을 제공하는 등의 논리적 개념에 분할보기/컨트롤러를 다시 사용하는 것입니다. 내 접근 방식은 RenderAction을 사용하여 결과를 컨테이너로 렌더링하는 것입니다. 컨테이너보기 (기본 페이지의 색인 작업)는 전통적인 asp.net 페이지, 레이아웃보기를 마스터 페이지, 편집 및보기 컨트롤러 /보기는 사용자 정의 컨트롤 (모듈)과 동일합니다. 문제는 무엇인가가 기록 된 후 응답을 리디렉션 할 수있는 방법이 없습니다입니다 :

MVC Redirect after save problem

+0

일반적으로 사용자가 데이터를 게시 한 후 사람들을 리디렉션합니다. 데이터 게시는 절대로 하위 작업 일 수 없습니다. 구체적인 예가 무엇인가요? 어떤 점에서 당신이 아동 행동을 오용하고있는 것처럼 보입니다. – Kristof

+0

코드 샘플은 실제로 구체적인 예에서 나온 것입니다. 보기는 양식 상단에 일부 정보를 렌더링하므로 (렌더링보기와 레이아웃이 두 ​​가지이므로) 성공적인 저장 후에 리디렉션해야합니다 (메시지를 표시하고 리디렉션을위한 링크 또는 버튼 제공하는 대신).) –

+0

여전히 다음과 같지 않습니다. 색인 조치는 실제로 색인이 아니며 저장 조치입니다. 왜 저장 작업을 표시 하시겠습니까? – Kristof

답변

1

내가 청소 일을 유지하기위한 시도로 새로운 답을 제출합니다.
정상적인 MVC 흐름은 다음과 같이 진행한다 :
의 HTTP 명령은 성가대 지휘자 (일명 컨트롤러)로 작동 한 제어기 도달 여러 논리 용기를 호출 (예를 들면 서비스/commandHandlers)

public ActionResult Index(){ 
    var data = _yourService.FetchData(); 
    return View(data); 
} 

이 제어부 (1) 뷰를 렌더링 이는 여러 파셜

부분은 당신이 RenderAction을 추가하거나 Html 헬퍼 확장을 만들 수 생성하기 위해 너무 많은 로직이 포함 된 경우
@{ 
    Layout = "my layout"; 
} 
<p>Some html</p> 
Html.RenderPartial("A shared partial"); 
Html.RenderPartial("shared\yourUserControl", Model.PropertyOrSomething); 

을 가질 수 있습니다.
그러나 이들 중 어느 것도 리디렉션 할 수있는 저장이나 요청의 흐름을 제어 할 수 없어야합니다. 내 의견으로는 뷰 내부에서 절대로 호출해서는 안됩니다.
코드가 너무 커지기 때문에 코드를 컨트롤러에서 재사용하고 싶다고 가정합니다.
필자의 조언은 최대한 많은 논리를 위임함으로써 컨트롤러를 가능한 많이 정리하는 것입니다.
5 초 동안 컨트롤러 방법을 살펴 봄으로써이 작업이 수행 할 작업에 대한 아이디어를 얻을 수 있습니다. 그렇지 않은 경우 : 리팩토링하십시오! :)

0

이 일을보기에 AJAX를 사용해보십시오, 대신 컨트롤러에 RedirectToAction을 반환이하는을 반환 JSON 개체 :

보기 :

$.ajax({ 
      url: '<%: Html.ResolveUrl("~/ControllerFolder/ControllerName/") %>', 
      type: "POST", 
      data: data, 
      success: function (result) { 
       $("#Div").html(result); 
       if (result.redirectUrl != null) 
       { 
        window.location = result.redirectUrl; 
       } 
      } 

     }); 

컨트롤러 :

[HttpPost] 
public ActionResult Index(ViewModel viewModel) 
{ 
    if (ModelState.IsValid) 
    { 
     // Do save; 

     return Json(new { redirectUrl = Url.Action("NewAction", "NewController", RouteValues)}); 
    } 

    // display validation errors and so 
    return View(viewModel); 
} 
,

희망이 도움이 ...

+0

아약스는 옵션이 아닌 것 같습니다. Javascript가 클라이언트에서 비활성화 된 경우 (접근성상의 이유로 e.x.) –

+0

자바 스크립트를 사용하지 않도록 설정 한 사용자의 확률이 높습니까? – Aaron

+0

예 : http://www.w3.org/TR/WCAG10/ –

1

내가 올바르게 이해하면 saveAction을 허용하는 상위 컨트롤러가 있고 뷰를 렌더링하는 동안 다른 (?) saveAction을 자식으로 호출합니다.
이 흐름은 나에게 자연스럽지 않습니다.
상위 조치와 상위 조치 만이 저장 명령을 처리해야합니다.
일부 HTML을 렌더링하는 데만 사용되는 한 원하는만큼 많은 하위 작업을 렌더링 할 수 있습니다 (보기와 동일).
리다이렉션이나 저축을 처리하지 못하게하십시오. 그런 식으로 일하는 것은 대학이나 미래의 모든 사람들에게 투명합니다.
컨트롤러 을 제어하지만보기가 아닙니다.

편집 :
정상적인 설정에는 2 개의 동작이 있습니다 (예 : 색인 및 넣기).

public ActionResult Index(){ 
    //fill model with dropdown data etc 
    return View(); 
} 

public ActionResult Put(viewModel data){ 
    if (ModelState.IsValid) 
    { 
     // Do save; 
     return RedirectToAction("whatever"); // <--- here's the problem 
    } 

    // display validation errors and so 
    return View("Index",viewModel); 
} 

Edit2가 : 당신이보기를 반환 할 경우 레이아웃이 그리고 검증 메시지가 modelstate에 위치 할로 는 ("인덱스", 뷰 모델은) 당신은 당신의 인덱스 뷰를 생성합니다.
보기에는 childaction이 하나만 있어야합니다 (저장 액션이 아닌 한 여러 개가있는 경우 더 많아야합니다). 귀하의 인덱스보기는 다음과 같이 수 :

@{ 
    Layout = "my layout"; 
} 
Html.RenderAction("something else, a view for example"); 
@Html.BeginForm("Put","YourController"){ 
    //all your input controls which will also show the validation errors 
} 


편집 3 : 을 당신이 @ Html.Partial 또는 HTML 도우미 확장 방법을 사용한다 html 코드를 다시 사용합니다. 모델을 전달하지 않으면 부모 모델이 전달되지만 부분 모델의 유형 안전성에 맞게 하위 모델을 전달할 수 있습니다.

그것은 다음과 같이 보일 것입니다 :

@{ 
    Layout = "my layout"; 
} 
Html.RenderAction("something else, a view for example"); 
Html.RenderPartial("shared\yourUserControl", Model.PropertyOrSomething); 
+0

이 접근법의 문제점은 유효성 검사 오류의 결과로 뷰를 렌더링하면 레이아웃이 손실된다는 것입니다. 기본보기 (두 개의 Html.RenderActions 및 레이아웃이있는보기)를 참조하십시오. –

+0

나는 내 대답을 편집하여 더 명확하게했습니다. 나는 당신의 문제에 대한 중요한 통찰력을 여전히 놓치고 있다는 느낌이 들었습니다. 그래서 당신이 이같은 시각을 보여 주면 레이아웃 문제를 자세히 설명해주십시오. – Kristof

+0

이 새로운 접근 방식은 모든 부분 뷰의 소스를 공유 뷰 (레이아웃이있는 뷰)에 넣어야한다는 단점이 있습니다. 편집 양식을 재사용 가능한 상태로 유지하고 싶습니다. 어떻게 든 ASP.NET 폼의 사용자 정의 컨트롤을 좋아할 수 있습니다. 비유로 레이아웃보기는 마스터 페이지이며 기본보기는 페이지 및 편집보기이며 제어기는 사용자 제어가 가능합니다. –

관련 문제