저는 두 가지 해결책을 생각해 냈습니다. 하나는 내가 일하는 사람이 고안 한 것이고, 다른 하나는 더 우아한 해결책입니다.
첫번째 해결책은 지정된 경로에 대해 MVcRouteHandler
을 확장하는 클래스를 지정하는 것이 었습니다. 이 경로 처리기는 HttpContext
의 양식에서 경로를 검사하고 양식 데이터를 읽고 RequestContext에서 RouteData
을 업데이트 할 수 있습니다.
MapRoute(routes,
"Book",
"{locale}/book",
new { controller = "Reservation", action = "Index" }).RouteHandler = new ReservationRouteHandler();
은 ReservationRouteHandler은 다음과 같습니다
이
public class ReservationRouteHandler: MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var request = requestContext.HttpContext.Request;
// First attempt to match one of the posted tab types
var action = ReservationNavigationHandler.GetActionFromPostData(request);
requestContext.RouteData.Values["action"] = action.ActionName;
requestContext.RouteData.Values["viewStage"] = action.ViewStage;
return base.GetHttpHandler(requestContext);
}
NavigationHandler 실제로 양식 데이터를 찾고의 일을하지만 당신은 아이디어를 얻을.
이 솔루션은 효과가 있지만 컨트롤러 클래스를 보면 결코 알 수 없지만 en-gb/book이 다른 방법을 가리키는 이유는 알 수 없습니다. 이것은 실제로 재사용이 가능하다고 느끼지 않습니다.
더 나은 솔루션은 컨트롤러에 오버로드 된 메서드가있는 것입니다. 즉,이 메서드는 모두이 경우 book이라고하며 사용자 지정의 ActionMethodSelectorAttribute를 정의합니다. 이것은 HttpPost 속성이 파생 된 것입니다.
public class FormPostFilterAttribute : ActionMethodSelectorAttribute
{
private readonly string _elementId;
private readonly string _requiredValue;
public FormPostFilterAttribute(string elementId, string requiredValue)
{
_elementId = elementId;
_requiredValue = requiredValue;
}
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (string.IsNullOrEmpty(controllerContext.HttpContext.Request.Form[_elementId]))
{
return false;
}
if (controllerContext.HttpContext.Request.Form[_elementId] != _requiredValue)
{
return false;
}
return true;
}
}
MVC는 주어진 컨트롤러에서 올바른 작업 방법을 해결하려고 할 때이 클래스를 호출합니다. 다음과 같이 우리는 다음 작업 방법을 선언
public ActionResult Book(HotelSummaryPostData hotelSummary)
{
return View("CustomerDetails");
}
[FormFieldFilter("stepID", "1")]
public ActionResult Book(YourDetailsPostData yourDetails, RequestedViewPostData requestedView)
{
return View(requestedView.RequestedView);
}
[FormFieldFilter("stepID", "2")]
public ActionResult Book(RoomDetailsPostData roomDetails, RequestedViewPostData requestedView)
{
return View(requestedView.RequestedView);
}
[HttpGet]
public ActionResult Book()
{
return View();
}
우리는 SelectorAttributes가 제대로되는 행동 방식을 결정하는이 페이지의 형태가 일반적인 URL에 다시 게시 할 때 있도록 숨겨진 필드가 다른 페이지에 stepID 정의해야 호출. 동일한 속성의 메소드가 존재하지 않고 속성 세트가 존재할 때 액션 메소드를 올바르게 선택한다는 사실에 놀라움을 금치 못했다.
이러한 메서드 선택기를 스택 할 수 있는지 여부를 살펴 보지 않았습니다. MVC에서이 기능을 매우 멋진 기능으로 만들 수 있다고 생각합니다.
나는이 답변이 나 이외의 다른 누군가에게 유용하기를 바랍니다. :)