ASP.NET MVC에서 Server.Transfer를 시뮬레이션하는 방법은 무엇입니까?


124

ASP.NET MVC에서는 리디렉션 ActionResult를 매우 쉽게 반환 할 수 있습니다.

 return RedirectToAction("Index");

 or

 return RedirectToRoute(new { controller = "home", version = Math.Random() * 10 });

이것은 실제로 HTTP 리디렉션을 제공하며 일반적으로 괜찮습니다. 그러나 Google Analytics를 사용할 때 원래 참조자가 손실되어 Google이 어디에서 왔는지 알지 못하기 때문에 큰 문제가 발생합니다. 이로 인해 검색 엔진 용어와 같은 유용한 정보가 손실됩니다.

참고로이 방법은 캠페인에서 가져온 매개 변수를 제거하는 장점이 있지만 여전히 서버 측에서 캡처 할 수 있습니다. 쿼리 문자열에 남겨두면 사람들이 북마크하거나 트위터 또는 블로그에해서는 안되는 링크를 남길 수 있습니다. 나는 사람들이 캠페인 ID를 포함하는 우리 사이트에 대한 링크를 트위터에 올린 곳에서 이것을 여러 번 보았다.

어쨌든, 나는 다른 장소 또는 대체 버전으로 리디렉션 할 수있는 사이트로 들어오는 모든 방문에 대해 '게이트웨이'컨트롤러를 작성하고 있습니다.

지금은 실수로 북마크하는 것보다 지금은 Google에 더 관심이 많으며 홈페이지 버전 7 인으로 이동하면 /얻을 수있는 페이지를 방문 하는 사람을 보낼 수 있기를 원합니다 /home/7.

이전에 말했듯이 이렇게하면 Google이 리퍼러를 분석 할 수있는 기능을 잃게됩니다.

 return RedirectToAction(new { controller = "home", version = 7 });

내가 정말로 원하는 것은

 return ServerTransferAction(new { controller = "home", version = 7 });

클라이언트 측 리디렉션없이 그 뷰를 얻을 수 있습니다. 나는 그런 것이 존재한다고 생각하지 않는다.

현재 내가 생각 해낼 수있는 가장 좋은 방법 HomeController.Index(..)은 내 GatewayController.Index액션 에서 전체 컨트롤러 로직을 복제하는 것 입니다. 이것은 내가 이동했다 의미 'Views/Home''Shared'는 액세스 할 수있었습니다 있도록. 더 나은 방법이있을 텐데 ?? ..


ServerTransferAction복제하려는 것이 정확히 무엇입니까 ? 그게 실제인가요? (... 그것에 질문에 대한 감사를 모든 정보를 찾을 수 없습니다, BTW, 대답은 아래 절경입니다)
jleach는

Server.Transfer (...)를 찾습니다. 클라이언트 측 리디렉션없이 클라이언트가 리디렉션 된 페이지를 수신하는 서버 측에서 기본적으로 '리디렉션'을 수행하는 방법입니다. 일반적으로 최신 라우팅에는 권장되지 않습니다.
Simon_Weaver 2016 년

1
"전송"은 라우팅을 사용하여 올바른 컨트롤러 작업 으로 직접 이동할 수 있기 때문에 MVC에서 더 이상 필요하지 않은 구식 ASP.NET 기능입니다 . 자세한 내용은 이 답변 을 참조하십시오.
NightOwl888

@ NightOwl888 그렇습니다.하지만 때로는 비즈니스 로직으로 인해 필요하고 더 쉽습니다. 나는 이것을 사용하여 끝낸 곳을 돌아 보았습니다. (다행히 한곳에있었습니다.) 어떤 복잡한 조건에 대해 역동적 이길 원했던 홈페이지가있어서 배후에서는 다른 경로를 보여줍니다. 라우팅 또는 경로 조건을 위해 가능한 한 피하고 싶지만 때로는 간단한 if진술이 너무 유혹적인 솔루션입니다.
Simon_Weaver

@Simon_Weaver- 한 컨트롤러에서 다른 컨트롤러로 건너 뛰기 위해 모든 것을 뒤로 구부리지 않고 거기에 진술을 RouteBase넣을 수 있도록 서브 클래 싱에 어떤 문제가 if있습니까?
NightOwl888

답변:


130

TransferResult 클래스는 어떻습니까? ( Stans 답변을 기반으로 함 )

/// <summary>
/// Transfers execution to the supplied url.
/// </summary>
public class TransferResult : ActionResult
{
    public string Url { get; private set; }

    public TransferResult(string url)
    {
        this.Url = url;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        var httpContext = HttpContext.Current;

        // MVC 3 running on IIS 7+
        if (HttpRuntime.UsingIntegratedPipeline)
        {
            httpContext.Server.TransferRequest(this.Url, true);
        }
        else
        {
            // Pre MVC 3
            httpContext.RewritePath(this.Url, false);

            IHttpHandler httpHandler = new MvcHttpHandler();
            httpHandler.ProcessRequest(httpContext);
        }
    }
}

업데이트 됨 : 이제 MVC3에서 작동합니다 ( Simon의 게시물 코드 사용 ). 해야 그것이 IIS7 +의 통합 파이프 라인 내에서 실행중인 여부를보고도 MVC2에서 작업을 (를 테스트 할 수 없었다).

완전한 투명성을 위해; 프로덕션 환경에서는 TransferResult를 직접 사용하지 않았습니다. TransferToRouteResult를 사용하여 차례로 TransferResult를 실행합니다. 내 프로덕션 서버에서 실제로 실행되는 것은 다음과 같습니다.

public class TransferToRouteResult : ActionResult
{
    public string RouteName { get;set; }
    public RouteValueDictionary RouteValues { get; set; }

    public TransferToRouteResult(RouteValueDictionary routeValues)
        : this(null, routeValues)
    {
    }

    public TransferToRouteResult(string routeName, RouteValueDictionary routeValues)
    {
        this.RouteName = routeName ?? string.Empty;
        this.RouteValues = routeValues ?? new RouteValueDictionary();
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        var urlHelper = new UrlHelper(context.RequestContext);
        var url = urlHelper.RouteUrl(this.RouteName, this.RouteValues);

        var actualResult = new TransferResult(url);
        actualResult.ExecuteResult(context);
    }
}

그리고 만약 당신이 T4MVC를 사용 한다면 (그렇지 않다면 ... 할 것!)이 확장이 유용 할 것입니다.

public static class ControllerExtensions
{
    public static TransferToRouteResult TransferToAction(this Controller controller, ActionResult result)
    {
        return new TransferToRouteResult(result.GetRouteValueDictionary());
    }
}

이 작은 보석을 사용하여 할 수 있습니다

// in an action method
TransferToAction(MVC.Error.Index());

1
이것은 잘 작동합니다. 잘못된 URL을 전달하여 첫 번째 시도에서 한 것처럼 무한 루프로 끝나지 않도록주의하십시오. 다른 사용자에게 유용 할 수있는 경로 값 컬렉션을 전달할 수 있도록 약간 수정했습니다. ... 위 또는 아래에 게시
Simon_Weaver

업데이트 :이 솔루션은 잘 작동하는 것 같습니다. 매우 제한된 용량으로 만 사용하고 있지만 아직 문제를 발견하지 못했습니다
Simon_Weaver

한 가지 문제 : POST에서 GET 요청으로 리디렉션 할 수 없지만 반드시 나쁜 것은 아닙니다. 뭔가 생각에주의합니다
Simon_Weaver

2
@BradLaney : 'var urlHelper ...'및 'var url ...'줄을 제거하고 나머지는 'url'을 'this.Url'로 바꾸면 작동합니다. :)
Michael Ulmann 2011 년

1
1 : 결합 / 단위 테스트 / 향후 호환성. 2 : mvc core / mvc 샘플은이 싱글 톤을 사용하지 않습니다. 3 :이 싱글 톤은 비동기 작업 메서드를 사용할 때와 같이 기본값이 아닌 컨텍스트에서 호출 된 풀 스레드 또는 비동기 대리자 인 스레드 (null)에서 사용할 수 없습니다. 4 : 호환성을 위해 mvc는 사용자 코드를 입력하기 전에이 싱글 톤 값을 context.HttpContext로 설정합니다.
Softlion

47

편집 : ASP.NET MVC 3과 호환되도록 업데이트되었습니다.

IIS7을 사용하는 경우 다음 수정은 ASP.NET MVC 3에서 작동하는 것 같습니다. 원래 코드가 작동하지 않았다는 점을 지적한 @nitin 및 @andy에게 감사드립니다.

2011 년 4 월 11 일 편집 : MVC 3 RTM에서 TempData가 Server.TransferRequest로 중단됨

예외를 발생 시키도록 아래 코드를 수정했지만 현재 다른 솔루션은 없습니다.


Markus의 Stan의 원본 게시물 수정 버전을 기반으로 한 수정 사항입니다. 경로 값 사전을 가져 오기 위해 추가 생성자를 추가하고 리디렉션 일 수 있다는 혼동을 피하기 위해 이름을 MVCTransferResult로 변경했습니다.

이제 리디렉션을 위해 다음을 수행 할 수 있습니다.

return new MVCTransferResult(new {controller = "home", action = "something" });

내 수정 된 수업 :

public class MVCTransferResult : RedirectResult
{
    public MVCTransferResult(string url)
        : base(url)
    {
    }

    public MVCTransferResult(object routeValues):base(GetRouteURL(routeValues))
    {
    }

    private static string GetRouteURL(object routeValues)
    {
        UrlHelper url = new UrlHelper(new RequestContext(new HttpContextWrapper(HttpContext.Current), new RouteData()), RouteTable.Routes);
        return url.RouteUrl(routeValues);
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var httpContext = HttpContext.Current;

        // ASP.NET MVC 3.0
        if (context.Controller.TempData != null && 
            context.Controller.TempData.Count() > 0)
        {
            throw new ApplicationException("TempData won't work with Server.TransferRequest!");
        }

        httpContext.Server.TransferRequest(Url, true); // change to false to pass query string parameters if you have already processed them

        // ASP.NET MVC 2.0
        //httpContext.RewritePath(Url, false);
        //IHttpHandler httpHandler = new MvcHttpHandler();
        //httpHandler.ProcessRequest(HttpContext.Current);
    }
}

1
이것은 MVC 3 RC에서 작동하지 않는 것 같습니다. HttpHandler.ProcessRequest ()에서 실패 함 : 'HttpContext.SetSessionStateBehavior'는 'HttpApplication.AcquireRequestState'이벤트가 발생하기 전에 만 호출 할 수 있습니다.
Andy

나는 아직 MVC3를 볼 변화가 없었습니다. 당신이 솔루션을 발견하면 알려주세요
Simon_Weaver

Nitin이 제안한 Server.TransferRquest는 위의 작업을 수행합니까?
Old Geezer 2011

TempData에서 null 및 count> 0을 확인해야하는 이유는 무엇입니까?
yurart

당신이 이미 사용하고 의존 그래서 만약이 사라지면 그 다음 당신은 머리를 긁적 왼쪽되지 않습니다에 당신은하지 않습니다,하지만 단지 안전 기능
Simon_Weaver

14

대신 IIS7 +에서 Server.TransferRequest 를 사용할 수 있습니다 .


12

최근에 ASP.NET MVC가 Server.Transfer ()를 지원하지 않는다는 사실을 알게되었으므로 스텁 메서드 (Default.aspx.cs에서 영감을 얻음)를 만들었습니다.

    private void Transfer(string url)
    {
        // Create URI builder
        var uriBuilder = new UriBuilder(Request.Url.Scheme, Request.Url.Host, Request.Url.Port, Request.ApplicationPath);
        // Add destination URI
        uriBuilder.Path += url;
        // Because UriBuilder escapes URI decode before passing as an argument
        string path = Server.UrlDecode(uriBuilder.Uri.PathAndQuery);
        // Rewrite path
        HttpContext.Current.RewritePath(path, false);
        IHttpHandler httpHandler = new MvcHttpHandler();
        // Process request
        httpHandler.ProcessRequest(HttpContext.Current);
    }

9

리디렉션하려는 컨트롤러의 인스턴스를 만들고 원하는 작업 메서드를 호출 한 다음 그 결과를 반환 할 수 없습니까? 다음과 같은 것 :

 HomeController controller = new HomeController();
 return controller.Index();

4
아니요, 생성 한 컨트롤러에는 요청 및 응답 설정과 같은 항목이 올바르게 설정되어 있지 않습니다. 그것은 문제로 이어질 수 있습니다.
Jeff Walker Code Ranger

나는 @JeffWalkerCodeRanger에 동의합니다 : 속성을 설정 한 후에도 같은 일otherController.ControllerContext = this.ControllerContext;
T-moty

7

두 번째 컨트롤러 / 작업이 요청 된 것처럼 실행 경로를 정확히 동일하게 유지하면서 현재 요청을 다른 컨트롤러 / 작업으로 다시 라우팅하고 싶었습니다. 제 경우에는 더 많은 데이터를 추가하고 싶기 때문에 Server.Request가 작동하지 않습니다. 이것은 실제로 다른 HTTP GET / POST를 실행 한 다음 결과를 클라이언트로 스트리밍하는 현재 처리기와 동일합니다. 이를 달성하는 더 나은 방법이있을 것이라고 확신하지만 여기에 저에게 효과적인 방법이 있습니다.

RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Public");
routeData.Values.Add("action", "ErrorInternal");
routeData.Values.Add("Exception", filterContext.Exception);

var context = new HttpContextWrapper(System.Web.HttpContext.Current);
var request = new RequestContext(context, routeData);

IController controller = ControllerBuilder.Current.GetControllerFactory().CreateController(filterContext.RequestContext, "Public");
controller.Execute(request);

당신의 추측이 맞습니다 :이 코드를

public class RedirectOnErrorAttribute : ActionFilterAttribute, IExceptionFilter

그리고 나는 그것을 사용하여 개발자에게 오류를 표시하는 반면 프로덕션에서는 정기적 인 리디렉션을 사용합니다. ASP.NET 세션, 데이터베이스 또는 요청간에 예외 데이터를 전달하는 다른 방법을 사용하고 싶지 않았습니다.


7

서버 전송을 시뮬레이션하는 대신 MVC는 실제로 Server.TransferRequest를 수행 할 수 있습니다 .

public ActionResult Whatever()
{
    string url = //...
    Request.RequestContext.HttpContext.Server.TransferRequest(url);
    return Content("success");//Doesn't actually get returned
}

더 자세히 설명하기 위해 답변에 텍스트를 추가하십시오.
Wladimir Palant 2014 년

이를 위해서는 MVCv3 이상이 필요합니다.
Seph

5

다른 컨트롤러를 인스턴스화하고 액션 메소드를 실행하십시오.


이렇게하면 주소 표시 줄에 원하는 URL이 표시되지 않습니다
arserbin3

@ arserbin3-Server.Transfer도 마찬가지입니다. 이 요구 사항은 아마도 원래 질문이 게시 된 이유 일 것입니다.
Richard Szalay 2014 년

2

다른 컨트롤러를 새로 만들고 결과를 반환하는 작업 메서드를 호출 할 수 있습니다. 그러나 공유 폴더에보기를 배치해야합니다.

이것이 중복의 의미인지 확실하지 않지만 다음과 같습니다.

return new HomeController().Index();

편집하다

또 다른 옵션은 고유 한 ControllerFactory를 만드는 것입니다. 이렇게하면 생성 할 컨트롤러를 결정할 수 있습니다.


이것은 접근 방식 일 수 있지만 hc.ControllerContext = this.ControllerContext라고 말하더라도 컨텍스트가 올바르게 표시되지 않는 것 같습니다. 또한 ~ / Views / Gateway / 5.aspx에서 뷰를 찾고 찾지 못합니다.
Simon_Weaver

또한 모든 액션 필터를 잃게됩니다. 컨트롤러가 구현해야하는 IController 인터페이스에서 Execute 메서드를 사용해보고 싶을 것입니다. 예 : ((IController) new HomeController ()). Execute (...). 이렇게하면 여전히 Action Invoker 파이프 라인에 참여할 수 있습니다. 하지만 실행하기 위해 정확히 무엇을 전달해야하는지 알아 내야합니다. 리플렉터가 도움이 될 수 있습니다. :)
Andrew Stanton-Nurse

네, 컨트롤러를 새로 만드는 아이디어가 마음에 들지 않습니다. 적절한 확장 포인트처럼 보이는 자신의 컨트롤러 팩토리를 정의하는 것이 좋습니다. 하지만이 프레임 워크의 표면을 거의 긁어 보지 않았기 때문에 벗어날 수 있습니다.
JoshBerke

1

라우팅이이 시나리오 만 처리하지 않습니까? 즉, 위에서 설명한 시나리오의 경우이 논리를 구현하는 경로 처리기를 만들 수 있습니다.


프로그래밍 조건을 기반으로합니다. 즉, 캠페인 100은 7로 이동하고 캠페인 200은 8로 이동하는 등 라우팅하기에 너무 복잡합니다.
Simon_Weaver

4
라우팅하기에 왜 너무 복잡합니까? 커스텀 라우트 제약의 문제점은 무엇입니까? stephenwalther.com/blog/archive/2008/08/07/…
Ian Mercer

1

위의 TransferResult 클래스 만 사용하는 식 기반 라우팅을 사용하는 모든 사람을 위해 트릭을 수행하고 TempData를 유지하는 컨트롤러 확장 메서드가 있습니다. TransferToRouteResult가 필요하지 않습니다.

public static ActionResult TransferRequest<T>(this Controller controller, Expression<Action<T>> action)
    where T : Controller
{
     controller.TempData.Keep();
     controller.TempData.Save(controller.ControllerContext, controller.TempDataProvider);
     var url = LinkBuilder.BuildUrlFromExpression(controller.Request.RequestContext, RouteTable.Routes, action);
     return new TransferResult(url);
}

경고 : 실제로 여전히 작동하지만 'SessionStateTempDataProvider 클래스는 세션 상태를 활성화해야합니다'라는 오류가 발생하는 것 같습니다. 내 로그에만이 오류가 표시됩니다. 오류 로깅을 위해 ELMAH를 사용하고 있으며 InProc 및 AppFabric에 대해이 오류가 발생합니다
Simon_Weaver

1

Server.TransferRequestMVC 에서는 완전히 불필요 합니다. 이것은 요청이 페이지로 직접 전달되고 요청을 다른 페이지로 전송하는 방법이 필요했기 때문에 ASP.NET에서만 필요했던 구식 기능입니다. 최신 버전의 ASP.NET (MVC 포함)에는 원하는 리소스로 직접 라우팅하도록 사용자 지정할 수있는 라우팅 인프라가 있습니다 . 요청을 컨트롤러에 직접 전달하고 원하는 작업을 수행하기 만하면 다른 컨트롤러로 전송하기 위해 요청이 컨트롤러에 도달하도록 할 필요가 없습니다.

더 많은 것은 원래 요청에 응답하기 때문에 아무것도 넣을 필요가 없다는 것입니다.TempData 때문에 요청을 올바른 위치로 라우팅하기 위해 다른 저장소 나 다른 저장소에 . 대신 원래 요청이 그대로 유지 된 상태로 컨트롤러 작업에 도달합니다. 이 접근 방식은 전적으로 서버 측에서 이루어 지므로 Google에서 승인 할 것입니다.

IRouteConstraint및 둘 다에서 상당한 작업을 수행 할 수 있지만 IRouteHandler라우팅을위한 가장 강력한 확장 포인트는 RouteBase서브 클래스입니다. 이 클래스는 들어오는 경로와 나가는 URL 생성을 모두 제공하도록 확장 될 수 있으므로 URL과 관련된 모든 작업과 URL이 실행하는 작업을 원 스톱으로 처리 할 수 ​​있습니다.

그래서에서 얻을, 두 번째 예를 따르도록 //home/7당신은 단순히 적절한 경로 값을 추가하는 경로가 필요합니다.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // Routes directy to `/home/7`
        routes.MapRoute(
            name: "Home7",
            url: "",
            defaults: new { controller = "Home", action = "Index", version = 7 }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

그러나 임의의 페이지가있는 원래 예제로 돌아 가면 경로 매개 변수가 런타임에 변경 될 수 없기 때문에 더 복잡합니다. 따라서 RouteBase다음과 같이 하위 클래스로 수행 할 수 있습니다 .

public class RandomHomePageRoute : RouteBase
{
    private Random random = new Random();

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData result = null;

        // Only handle the home page route
        if (httpContext.Request.Path == "/")
        {
            result = new RouteData(this, new MvcRouteHandler());

            result.Values["controller"] = "Home";
            result.Values["action"] = "Index";
            result.Values["version"] = random.Next(10) + 1; // Picks a random number from 1 to 10
        }

        // If this isn't the home page route, this should return null
        // which instructs routing to try the next route in the route table.
        return result;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        var controller = Convert.ToString(values["controller"]);
        var action = Convert.ToString(values["action"]);

        if (controller.Equals("Home", StringComparison.OrdinalIgnoreCase) &&
            action.Equals("Index", StringComparison.OrdinalIgnoreCase))
        {
            // Route to the Home page URL
            return new VirtualPathData(this, "");
        }

        return null;
    }
}

다음과 같이 라우팅에 등록 할 수 있습니다.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // Routes to /home/{version} where version is randomly from 1-10
        routes.Add(new RandomHomePageRoute());

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

위의 예에서 사용자가 방문한 홈 페이지 버전을 기록하는 쿠키도 저장하여 사용자가 돌아 왔을 때 동일한 홈 페이지 버전을 수신하도록하는 것이 좋습니다.

또한이 접근 방식을 사용하면 쿼리 문자열 매개 변수를 고려하여 (기본적으로 완전히 무시 됨) 라우팅을 사용자 정의하고 그에 따라 적절한 컨트롤러 작업으로 라우팅 할 수 있습니다.

추가 예


액션을 입력 할 때 즉시 전환하지 않고 해당 액션이 일부 작업을 수행하도록 한 다음 조건부로 다른 액션으로 전환하고 싶지 않으면 어떻게하나요? 전송 대상으로 직접 이동하도록 내 라우팅을 변경하는 것은 작동 Server.TransferRequest하지 않으므로 결국 "MVC에서 완전히 불필요"하지 않은 것처럼 보입니다 .
ProfK

0

그 자체로 답은 아니지만 Webforms Server.Transfer ()와 동등한 기능을 "실행"하기위한 실제 탐색뿐만 아니라이 모든 것이 단위 테스트 내에서 완전히 지원되어야한다는 것이 분명합니다.

따라서 ServerTransferResult는 RedirectToRouteResult처럼 "표시"되어야하며 클래스 계층 구조 측면에서 가능한 유사해야합니다.

Reflector를보고 RedirectToRouteResult 클래스와 다양한 Controller 기본 클래스 메서드가 수행하는 모든 작업을 수행 한 다음 확장 메서드를 통해 후자를 Controller에 "추가"하여이 작업을 수행하려고합니다. 다운로드의 용이성 / 게으름을 위해 동일한 클래스 내의 정적 메서드 일 수 있습니까?

내가이 일을하게되면 게시하겠습니다. 그렇지 않으면 다른 사람이 나를 이길 수도 있습니다!


0

Html.RenderActionView 에서 도우미를 활용하여이를 달성했습니다 .

@{
    string action = ViewBag.ActionName;
    string controller = ViewBag.ControllerName;
    object routeValues = ViewBag.RouteValues;
    Html.RenderAction(action, controller, routeValues);
}

그리고 내 컨트롤러에서 :

public ActionResult MyAction(....)
{
    var routeValues = HttpContext.Request.RequestContext.RouteData.Values;    
    ViewBag.ActionName = "myaction";
    ViewBag.ControllerName = "mycontroller";
    ViewBag.RouteValues = routeValues;    
    return PartialView("_AjaxRedirect");
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.