문제

나는 많은 것을 피하고 싶다. if Request.IsAjaxRequest() 내 컨트롤러에서.나는 이 논리를 ActionFilter로 압축할 수 있다면 애플리케이션에서 다음과 같은 요청에 대해 두 번째 작업을 제공하는 규칙을 쉽게 채택할 수 있을 것이라고 생각했습니다. 5월 Ajax를 사용하고 JavaScript가 비활성화된 경우 대체 기능을 제공합니다.

public ActionResult Details(int id)
{
  // called normally, show full page
}

public ActionResult Details_Ajax(int id)
{
  // called through ajax, return a partial view
}

나는 처음에 다음과 같은 일을 할 수 있다고 생각했습니다.

public class AjaxRenameAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RouteData.Values["action"] = filterContext.RouteData.Values["action"] + "_Ajax";

    }

그러나 호출할 작업이 결정된 다음 해당 작업에 대한 필터가 처리되기 때문에 작동하지 않습니다.

누군가 작업을 호출할 때마다 RedirectResult를 반환하고 싶지는 않습니다. Http 요청 양을 두 배로 늘리는 것은 약간 무의미해 보입니다.

요청을 다른 작업으로 라우팅하는 다른 방법이 있나요?아니면 내가 하고 있는 일이 바람직하지 않아서 더 나은 일을 하는 방법을 찾아야 합니까?

건배

도움이 되었습니까?

해결책

AcceptAjaxAttribute 아마도 여기에 필요한 것일 것입니다.그러나 나는 이 문제에 대해 다른 사고방식을 제안하고 싶습니다.

모든 Ajax 요청이 동일한 것은 아닙니다.Ajax 요청은 다음 중 하나를 수행하려고 시도할 수 있습니다.

  • JSON 데이터를 풍부한 그리드(예: jqGrid)에 바인딩합니다.
  • RSS 피드와 같은 XML 데이터 구문 분석/변환
  • 페이지 영역에 부분 HTML 로드
  • 비동기적으로 스크립트 로드(google.load 할 수 있습니다);
  • 클라이언트의 단방향 메시지 처리
  • 그리고 아마도 내가 잊어버린 몇 가지가 더 있을 것입니다.

귀하가 오로지 특정 "대체 작업"을 "선택"하는 경우 IsAjaxRequest 방법을 사용하면 매우 일반적인 것(비동기 요청)을 서버의 특정 기능에 연결하게 됩니다.이는 궁극적으로 디자인을 더욱 취약하게 만들고 컨트롤러의 단위 테스트를 더 어렵게 만들 것입니다(비록 이를 수행하는 방법이 있지만 컨텍스트를 모의할 수는 있음).

잘 디자인된 행동 해야한다 일관된, 그것은 단지 관심을 가져야합니다 무엇 요청은 다음을 위한 것이었고 그렇지 않았습니다. 어떻게 요청이 이루어졌습니다.다음과 같은 다른 속성을 가리킬 수도 있습니다. AuthorizeAttribute 예외적으로 필터를 구별하겠습니다. 필터는 대부분의 경우 작업이 "대신"이 아니라 "이전" 또는 "이후"에 발생해야 하는 동작을 설명합니다.

여기서 요점을 말하자면, 질문에 명시된 목표는 좋은 것입니다.당신은해야 분명히 다른 작업으로 올바르게 설명된 작업에 대해 다른 방법이 있습니다.

public ActionResult Details(int id)
{
    return View("Details", GetDetails(id));
}

public ActionResult JsonDetails(int id)
{
    return Json(GetDetails(id));
}

public ActionResult PartialDetails(int id)
{
    return PartialView("DetailTable", GetDetails(id));
}

등등.그러나 이러한 방법 중 하나를 선택하기 위해 Ajax 액션 선택기를 사용하는 것은 다음과 같은 관행을 따르는 것입니다. "우아한 저하", 이는 본질적으로 (적어도 IMO) 다음으로 대체되었습니다. 점진적인 향상.

이것이 제가 ASP.NET MVC를 좋아하지만 대부분의 경우 MVC를 피하는 이유입니다. AjaxHelper, 왜냐하면 그것이 이 개념을 그렇게 잘 표현한다고 생각하지 않기 때문입니다.그것은 당신에게서 너무 많은 것을 숨기려고 합니다."Ajax Form"이나 "Ajax Action"이라는 개념을 갖는 대신, 구분을 없애고 HTML만을 고수하자. 클라이언트가 Ajax 기능을 처리할 수 있다고 확신하면 Ajax 기능을 별도로 주입합니다.

다음은 jQuery의 예입니다. MS AJAX에서도 이 작업을 수행할 수 있습니다.

$(function() {
    $("#showdetails").click(function() {
        $("#details").load("PartialDetails", { id: <%= Record.ID %> });
        return false;
    }
});

이것이 Ajax를 MVC 페이지에 삽입하는 데 필요한 전부입니다.평범한 기존 HTML 링크로 시작하고 이를 Ajax 호출로 재정의합니다. 다른 컨트롤러 작업으로 이동합니다..

이제 사이트의 다른 곳에서 대신 그리드를 사용하기로 결정했지만 부분 렌더링을 사용하여 페이지를 나누고 싶지 않은 경우 다음과 같이 작성할 수 있습니다. 왼쪽에는 "주문" 목록이 있고 오른쪽에는 세부정보 테이블이 있습니다.

$(".detaillink").click(function() {
    $('#detailGrid').setGridParam({
        url: $(this).attr("href").replace(/\/order\/details/i,
            "/order/jsondetails")
    }); 
    $("#detailGrid").trigger("reloadGrid");  
});

이 접근 방식은 클라이언트 동작과 서버 동작을 완전히 분리합니다.서버는 클라이언트에게 효과적으로 다음과 같이 말합니다. JSON 버전을 원하시면, 묻다 JSON 버전의 경우, 아, 그런데 실행 방법을 알고 있는 경우 링크를 변환하는 스크립트가 있습니다. 액션 선택기와 메서드 오버로드로 인한 피날링도 없고, 간단한 테스트를 실행하기 위해 수행해야 하는 특별한 조롱도 없으며, 어떤 액션이 언제 무엇을 하는지에 대한 혼란도 없습니다.JavaScript 몇 줄이면 됩니다.컨트롤러 작업은 원래 그래야 하는 대로 짧고 간단합니다.

이것이 유일한 접근 방식은 아닙니다.분명히 다음과 같은 수업은 AcceptAjaxAttribute 일부 개발자가 요청 감지 방법을 사용할 것으로 예상했기 때문에 존재했습니다.그러나 두 가지 모두를 꽤 많이 실험한 후에 나는 이 방법을 발견했습니다. 많이 추론하기가 더 쉬우므로 올바르게 설계/코딩하기가 더 쉽습니다.

다른 팁

MVCFutures의 Acceptajaxattribute는 어떻습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top