ASP.NET MVC 4는 들어오는 모든 요청을 차단합니다.


78

ASP.NET MVC 4 앱에 들어오는 모든 요청 을 포착 하고 지정된 컨트롤러 / 작업에 대한 요청을 계속하기 전에 일부 코드를 실행할 수있는 방법이 있습니까?

기존 서비스에서 일부 사용자 지정 인증 코드를 실행해야하며이를 제대로 수행하려면 모든 클라이언트에서 들어오는 모든 요청을 가로 채서 다른 서비스에서 몇 가지 사항을 다시 확인할 수 있어야합니다.


답변:


80

가장 올바른 방법은 ActionFilterAttribute 를 상속 하고 OnActionExecuting메서드를 재정의 하는 클래스를 만드는 것 입니다. 그런 다음에 등록 할 수 있습니다 GlobalFilters.Global.asax.cs

물론 이것은 실제로 경로가있는 요청 만 가로 챌 것입니다.


10
유일한 (추악한) 다른 방법은 protected void Application_BeginRequest(object sender, EventArgs e).
Erik Philips

1
글쎄, 난 당신이 또한 HttpHandler를을 만들고 그 Web.config의 모든 잡으려고 등록 할 수도 있겠죠,하지만 :) 정말 더러운
Yngve B-닐센

1
OnActionExecuting재정의 내에서 리디렉션을 강제하는 방법이 있습니까?
Jesse

2
그래, 당신은 RedirectResult에 filterContext.Result을 설정할 수 있습니다
Yngve B-닐센

1
당신은 당신이 알아서 ActionResult의 어떤 유형의 결과를 변경할 수 있습니다
Yngve B-닐센에게

38

HttpModule을 사용하여이를 수행 할 수 있습니다. 다음은 모든 요청의 처리 시간을 계산하는 데 사용하는 샘플입니다.

using System;
using System.Diagnostics;
using System.Web;

namespace Sample.HttpModules
{
    public class PerformanceMonitorModule : IHttpModule
    {

        public void Init(HttpApplication httpApp)
        {
            httpApp.BeginRequest += OnBeginRequest;
            httpApp.EndRequest += OnEndRequest;
            httpApp.PreSendRequestHeaders += OnHeaderSent;
        }

        public void OnHeaderSent(object sender, EventArgs e)
        {
            var httpApp = (HttpApplication)sender;
            httpApp.Context.Items["HeadersSent"] = true;
        }

        // Record the time of the begin request event.
        public void OnBeginRequest(Object sender, EventArgs e)
        {
            var httpApp = (HttpApplication)sender;
            if (httpApp.Request.Path.StartsWith("/media/")) return;
            var timer = new Stopwatch();
            httpApp.Context.Items["Timer"] = timer;
            httpApp.Context.Items["HeadersSent"] = false;
            timer.Start();
        }

        public void OnEndRequest(Object sender, EventArgs e)
        {
            var httpApp = (HttpApplication)sender;
            if (httpApp.Request.Path.StartsWith("/media/")) return;
            var timer = (Stopwatch)httpApp.Context.Items["Timer"];

            if (timer != null)
            {
                timer.Stop();
                if (!(bool)httpApp.Context.Items["HeadersSent"])
                {
                    httpApp.Context.Response.AppendHeader("ProcessTime",
                                                          ((double)timer.ElapsedTicks / Stopwatch.Frequency) * 1000 +
                                                          " ms.");
                }
            }

            httpApp.Context.Items.Remove("Timer");
            httpApp.Context.Items.Remove("HeadersSent");

        }

        public void Dispose() { /* Not needed */ }
    }

}

Web.Config에 모듈을 등록하는 방법은 다음과 같습니다.

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <add name="PerformanceMonitorModule" type="Sample.HttpModules.PerformanceMonitorModule" />
    </modules>
<//system.webServer>

3
MVC 앱 요청이 컨트롤러로 이동하기 전에 캡처하는 것이 목표라면 필터링이 훨씬 더 나은 접근 방식입니다. 내 문서를 참조 msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx를 - 내 샘플은 좋은 타이밍 필터가
RickAndMSFT

1
runAllManagedModulesForAllRequests성능 저하를 사용하기 때문에이 접근 방식을 권장하지 않습니다 . Application_BeginRequest결과를 달성하기 위해 훨씬 더 간단한 방법처럼 보인다
Quango

25

나는 당신이 검색하는 것이 이것이라고 생각합니다.

Application_BeginRequest()

http://www.dotnetcurry.com/showarticle.aspx?ID=126

당신은 그것을 Global.asax.cs.

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        HttpContext.Current.Request.....;
    }

디버깅 목적으로 이것을 사용하지만 귀하의 경우에 얼마나 좋은 솔루션인지 잘 모르겠습니다.


2

MVC4에 대해 잘 모르겠지만 MVC5와 상당히 유사하다고 생각합니다. 새 웹 프로젝트를 만든 경우-> 살펴보고 메서드에 Global.asax다음 줄이 표시되어야합니다 .FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);Application_Start()

RegisterGlobalFiltersFilterConfig.cs폴더 에있는 파일의 메서드입니다 App_Start.

@ YngveB-Nilsen이 말했듯 ActionFilterAttribute이 내 의견으로는 갈 길이다. .NET에서 파생되는 새 클래스를 추가합니다 System.Web.Mvc.ActionFilterAttribute. System.Web.Http.Filters.ActionFilterAttribute예를 들어 다음 예외와 함께 실패 하므로 이것은 중요 합니다.

지정된 필터 인스턴스는 System.Web.Mvc.IAuthorizationFilter, System.Web.Mvc.IActionFilter, System.Web.Mvc.IResultFilter, System.Web.Mvc.IExceptionFilter, System.Web 필터 인터페이스 중 하나 이상을 구현해야합니다. .Mvc.Filters.IAuthenticationFilter.

디버그 창에 요청을 쓰는 예 :

public class DebugActionFilter : System.Web.Mvc.ActionFilterAttribute
{
  public override void OnActionExecuting(ActionExecutingContext actionContext)
  {
    Debug.WriteLine(actionContext.RequestContext.HttpContext.Request);
  }
}

에서 FilterConfig-> RegisterGlobalFilters-> 다음 줄을 추가합니다 filters.Add(new DebugActionFilter());.

이제 모든 수신 요청을 포착하고 수정할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.