Làm cách nào để mô phỏng Server.Transfer trong ASP.NET MVC?


124

Trong ASP.NET MVC, bạn có thể trả về một ActionResult chuyển hướng khá dễ dàng:

 return RedirectToAction("Index");

 or

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

Điều này thực sự sẽ cung cấp một chuyển hướng HTTP, thường là tốt. Tuy nhiên, khi sử dụng google phân tích, điều này gây ra sự cố lớn do người giới thiệu ban đầu bị mất nên google không biết bạn đến từ đâu. Điều này làm mất thông tin hữu ích như bất kỳ thuật ngữ công cụ tìm kiếm nào.

Là một lưu ý phụ, phương pháp này có lợi thế là loại bỏ bất kỳ tham số nào có thể đến từ các chiến dịch nhưng vẫn cho phép tôi chụp chúng ở phía máy chủ. Để chúng trong chuỗi truy vấn dẫn đến mọi người đánh dấu trang hoặc twitter hoặc viết blog một liên kết mà họ không nên. Tôi đã thấy điều này nhiều lần khi mọi người có các liên kết twitter đến trang web của chúng tôi có chứa ID chiến dịch.

Dù sao, tôi đang viết một bộ điều khiển 'cổng' cho tất cả các lượt truy cập đến trang web mà tôi có thể chuyển hướng đến các địa điểm khác nhau hoặc các phiên bản thay thế.

Hiện tại tôi quan tâm nhiều hơn đến Google (hơn là đánh dấu ngẫu nhiên) và tôi muốn có thể gửi ai đó truy cập /vào trang mà họ sẽ nhận được nếu họ truy cập /home/7, đó là phiên bản 7 của trang chủ.

Giống như tôi đã nói trước đây Nếu tôi làm điều này, tôi sẽ mất khả năng google phân tích người giới thiệu:

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

Những gì tôi thực sự muốn là một

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

cái mà sẽ cho tôi cái nhìn đó mà không cần chuyển hướng phía khách hàng. Tôi không nghĩ rằng một điều như vậy tồn tại mặc dù.

Hiện tại, điều tốt nhất tôi có thể đưa ra là sao chép toàn bộ logic của bộ điều khiển HomeController.Index(..)trong GatewayController.IndexHành động của mình . Điều này có nghĩa là tôi phải chuyển 'Views/Home'vào 'Shared'để nó có thể truy cập được. Phải có cách tốt hơn??..


Chính xác thì cái ServerTransferActiongì mà bạn đang cố gắng sao chép? Đó có phải là một điều thực tế? (không thể tìm thấy bất kỳ thông tin nào về nó ... cảm ơn vì câu hỏi, btw, câu trả lời dưới đây là tuyệt vời)
jleach

Tra cứu Server.Transfer (...). Về cơ bản, đó là một cách để thực hiện 'chuyển hướng' ở phía máy chủ nơi khách hàng nhận được trang được chuyển hướng mà không cần chuyển hướng phía máy khách. Nói chung, nó không được khuyến khích với định tuyến hiện đại.
Simon_Weaver

1
"Chuyển" là một tính năng ASP.NET cổ xưa không còn cần thiết trong MVC do khả năng đi trực tiếp đến hành động của bộ điều khiển chính xác bằng cách sử dụng định tuyến. Xem câu trả lời này để biết chi tiết.
NightOwl888

@ NightOwl888 có chắc chắn - nhưng đôi khi do logic kinh doanh, nó cần thiết / dễ dàng hơn. Tôi nhìn lại để xem cuối cùng tôi đã sử dụng cái này ở đâu - (may mắn thay nó chỉ ở một nơi) - nơi tôi có một trang chủ mà tôi muốn năng động trong một số điều kiện phức tạp và vì vậy đằng sau hậu trường nó hiển thị một tuyến đường khác. Chắc chắn muốn tránh nó nhiều nhất có thể có lợi cho các điều kiện định tuyến hoặc tuyến đường - nhưng đôi khi một iftuyên bố đơn giản chỉ là một giải pháp quá hấp dẫn.
Simon_Weaver

@Simon_Weaver - Và có gì sai khi phân lớp RouteBaseđể bạn có thể đặt ifcâu lệnh của mình ở đó thay vì uốn cong mọi thứ về phía sau để nhảy từ bộ điều khiển này sang bộ điều khiển khác?
NightOwl888

Câu trả lời:


130

Làm thế nào về một lớp TransferResult? (dựa trên câu trả lời của 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);
        }
    }
}

Đã cập nhật: Bây giờ hoạt động với MVC3 (sử dụng mã từ bài đăng của Simon ). Nó cũng (chưa thể kiểm tra nó) cũng hoạt động trong MVC2 bằng cách xem liệu nó có chạy trong đường ống tích hợp của IIS7 + hay không.

Để minh bạch đầy đủ; Trong môi trường sản xuất của chúng tôi, chúng tôi không bao giờ sử dụng TransferResult trực tiếp. Chúng tôi sử dụng TransferToRouteResult, lần lượt các lệnh gọi thực thi TransferResult. Đây là những gì thực sự chạy trên các máy chủ sản xuất của tôi.

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);
    }
}

Và nếu bạn đang sử dụng T4MVC (nếu không ... làm!) Thì tiện ích mở rộng này có thể có ích.

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

Sử dụng viên ngọc nhỏ này bạn có thể làm

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

1
công việc này thật tuyệt hãy cẩn thận để không kết thúc với một vòng lặp vô hạn - như tôi đã làm trong lần thử đầu tiên bằng cách chuyển URL sai. Tôi đã thực hiện một sửa đổi nhỏ để cho phép bộ sưu tập giá trị tuyến đường được truyền qua có thể hữu ích cho người khác. được đăng ở trên hoặc bên dưới ...
Simon_Weaver

cập nhật: giải pháp này có vẻ hoạt động tốt và mặc dù tôi chỉ sử dụng nó trong một khả năng rất hạn chế nhưng vẫn chưa tìm thấy bất kỳ vấn đề nào
Simon_Weaver

một vấn đề: không thể chuyển hướng từ POST sang GET request - nhưng đó không hẳn là điều xấu. một cái gì đó phải thận trọng mặc dù
Simon_Weaver

2
@BradLaney: Bạn chỉ có thể xóa các dòng 'var urlHelper ...' và 'var url ...' và thay thế 'url' bằng 'this.Url' cho phần còn lại và nó hoạt động. :)
Michael Ulmann

1
1: khớp nối / thử nghiệm đơn vị / tương thích trong tương lai. 2: mẫu mvc core / mvc không bao giờ sử dụng singleton này. 3: singleton này không có sẵn trong một luồng (null), hoặc một chuỗi nhóm hoặc ủy nhiệm async được gọi trên một ngữ cảnh khác với mặc định, như khi sử dụng các phương thức hành động không đồng bộ. 4: chỉ cho mục đích tương thích, mvc đặt giá trị singleton này thành bối cảnh.HttpContext trước khi nhập mã người dùng.
Softlion

47

Chỉnh sửa: Đã cập nhật để tương thích với ASP.NET MVC 3

Với điều kiện bạn đang sử dụng IIS7, sửa đổi sau đây dường như hoạt động với ASP.NET MVC 3. Cảm ơn @nitin và @andy vì đã chỉ ra mã gốc không hoạt động.

Chỉnh sửa 4/11/2011: TempData nghỉ với Server.TransferRequest kể từ MVC 3 RTM

Sửa đổi mã dưới đây để ném một ngoại lệ - nhưng không có giải pháp nào khác tại thời điểm này.


Đây là sửa đổi của tôi dựa trên phiên bản sửa đổi của bài viết gốc của Stanus. Tôi đã thêm một hàm tạo bổ sung để lấy từ điển Giá trị tuyến - và đổi tên thành MVCTransferResult để tránh nhầm lẫn rằng nó có thể chỉ là một chuyển hướng.

Bây giờ tôi có thể làm như sau để chuyển hướng:

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

Lớp sửa đổi của tôi:

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
Điều này dường như không hoạt động trong MVC 3 RC. Thất bại trên HttpHandler.ProcessRequest (), cho biết: 'HttpContext.SetSessionStateBehavior' chỉ có thể được gọi trước khi sự kiện 'httpApplication.AcquireRequestState' được nêu ra.
Andy

Tôi chưa có thay đổi để xem MVC3. hãy cho tôi biết nếu bạn tìm thấy giải pháp
Simon_Weaver

Server.TransferRquest theo đề xuất của Nitin có làm những gì ở trên đang cố gắng làm không?
Geezer cũ

Tại sao chúng ta cần kiểm tra TempData cho null và đếm> 0?
yurart

Bạn không, nhưng đây chỉ là một tính năng an toàn nên nếu bạn đã sử dụng nó và dựa vào nó thì bạn sẽ không phải gãi đầu nếu nó biến mất
Simon_Weaver

14

Thay vào đó, bạn có thể sử dụng Server.TransferRequest trên IIS7 +.


12

Gần đây tôi phát hiện ra rằng ASP.NET MVC không hỗ trợ Server.Transfer () vì vậy tôi đã tạo ra một phương thức sơ khai (lấy cảm hứng từ 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

Bạn không thể tạo một thể hiện của bộ điều khiển mà bạn muốn chuyển hướng đến, gọi phương thức hành động bạn muốn, sau đó trả về kết quả của điều đó? Cái gì đó như:

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

4
Không, bộ điều khiển bạn tạo sẽ không có những thứ như thiết lập Yêu cầu và Phản hồi chính xác trên nó. Điều đó có thể dẫn đến các vấn đề.
Jeff Walker Code Ranger

Tôi đồng ý với @JeffWalkerCodeRanger: điều tương tự cũng xảy ra sau khi đặt tài sảnotherController.ControllerContext = this.ControllerContext;
T-moty

7

Tôi muốn định tuyến lại yêu cầu hiện tại đến bộ điều khiển / hành động khác, trong khi vẫn giữ đường dẫn thực hiện chính xác giống như khi bộ điều khiển / hành động thứ hai đó được yêu cầu. Trong trường hợp của tôi, Server.Request sẽ không hoạt động vì tôi muốn thêm nhiều dữ liệu hơn. Điều này thực sự tương đương với trình xử lý hiện tại đang thực thi một HTTP GET / POST khác, sau đó truyền kết quả đến máy khách. Tôi chắc chắn sẽ có những cách tốt hơn để đạt được điều này, nhưng đây là những gì phù hợp với tôi:

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);

Bạn đoán đúng: Tôi đặt mã này vào

public class RedirectOnErrorAttribute : ActionFilterAttribute, IExceptionFilter

và tôi đang sử dụng nó để hiển thị lỗi cho các nhà phát triển, trong khi nó sẽ sử dụng chuyển hướng thường xuyên trong sản xuất. Lưu ý rằng tôi không muốn sử dụng phiên ASP.NET, cơ sở dữ liệu hoặc một số cách khác để truyền dữ liệu ngoại lệ giữa các yêu cầu.


7

Thay vì mô phỏng chuyển máy chủ, MVC vẫn có khả năng thực sự thực hiện Server.TransferRequest :

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

Hãy thêm một số văn bản vào câu trả lời của bạn để giải thích thêm.
Wladimir Palant

Lưu ý điều này đòi hỏi MVCv3 trở lên.
Seph

5

Chỉ cần trình điều khiển khác và thực hiện phương thức hành động của nó.


Điều này sẽ không hiển thị URL mong muốn trong thanh địa chỉ
arserbin3

@ arserbin3 - Cả Server.Transfer cũng vậy. Yêu cầu này có lẽ là lý do tại sao câu hỏi ban đầu thậm chí được đăng.
Richard Szalay

2

Bạn có thể làm mới bộ điều khiển khác và gọi phương thức hành động trả về kết quả. Điều này sẽ yêu cầu bạn đặt chế độ xem của bạn vào thư mục dùng chung.

Tôi không chắc đây có phải là ý của bạn khi nhân đôi nhưng:

return new HomeController().Index();

Biên tập

Một tùy chọn khác có thể là tạo Trình điều khiển của riêng bạn, bằng cách này bạn có thể xác định trình điều khiển nào sẽ tạo.


đây có thể là cách tiếp cận, nhưng dường như nó không hoàn toàn đúng ngữ cảnh - ngay cả khi tôi nói hc.ControllContext = this.ControllContext. Thêm vào đó, nó sẽ tìm chế độ xem trong ~ / Lượt xem / Cổng / 5.aspx và không tìm thấy nó.
Simon_Weaver

Thêm vào đó bạn mất tất cả các Bộ lọc hành động. Bạn có thể muốn thử sử dụng phương thức Execute trên giao diện IContler mà bộ điều khiển của bạn phải thực hiện. Ví dụ: ((IControll) HomeContoder mới ()). Thực thi (...). Bằng cách đó bạn vẫn tham gia vào đường dẫn Action Invoker. Bạn sẽ phải tìm ra chính xác những gì cần thực hiện để Thực thi mặc dù ... Reflector có thể giúp đỡ ở đó :)
Andrew Stanton-Nurse

Đúng, tôi không thích ý tưởng làm mới bộ điều khiển, tôi nghĩ tốt hơn hết là bạn nên xác định nhà máy sản xuất bộ điều khiển của riêng mình, có vẻ như là điểm mở rộng thích hợp cho việc này. Nhưng tôi hầu như không trầy xước bề mặt của khung này vì vậy tôi có thể thoát ra.
JoshBerke

1

Không định tuyến chỉ quan tâm đến kịch bản này cho bạn? tức là đối với kịch bản được mô tả ở trên, bạn chỉ có thể tạo một trình xử lý tuyến đường thực hiện logic này.


nó dựa trên các điều kiện lập trình. tức là chiến dịch 100 có thể chuyển sang xem 7 và chiến dịch 200 có thể chuyển sang xem 8, v.v. quá phức tạp để định tuyến
Simon_Weaver

4
Tại sao điều đó quá phức tạp để định tuyến? Có gì sai với các ràng buộc tuyến tùy chỉnh? stephenwalther.com/blog/archive/2008/08/07/ Mạnh
Ian Mercer

1

Đối với bất kỳ ai sử dụng định tuyến dựa trên biểu thức, chỉ sử dụng lớp TransferResult ở trên, đây là một phương thức mở rộng bộ điều khiển thực hiện thủ thuật và bảo toàn TempData. Không cần 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);
}

Cảnh báo: điều này dường như gây ra lỗi 'Lớp SessionStateTempDataProvider yêu cầu trạng thái phiên được bật' mặc dù thực tế nó vẫn hoạt động. Tôi chỉ thấy lỗi này trong nhật ký của tôi. Tôi đang sử dụng ELMAH để ghi nhật ký lỗi và nhận lỗi này cho InProc và AppFoven
Simon_Weaver

1

Server.TransferRequesthoàn toàn không cần thiết trong MVC . Đây là một tính năng cổ xưa chỉ cần thiết trong ASP.NET vì yêu cầu được gửi trực tiếp đến một trang và cần có một cách để chuyển yêu cầu sang một trang khác. Các phiên bản hiện đại của ASP.NET (bao gồm MVC) có cơ sở hạ tầng định tuyến có thể được tùy chỉnh để định tuyến trực tiếp đến tài nguyên mong muốn. Không có điểm nào để cho phép yêu cầu tiếp cận bộ điều khiển chỉ để chuyển nó sang bộ điều khiển khác khi bạn có thể đơn giản thực hiện yêu cầu trực tiếp đến bộ điều khiển và hành động bạn muốn.

Thêm nữa là vì bạn đang đáp ứng yêu cầu ban đầu , nên không cần phải nhét bất cứ thứ gì vàoTempData hoặc bộ lưu trữ khác chỉ vì mục đích định tuyến yêu cầu đến đúng nơi. Thay vào đó, bạn đến hành động của bộ điều khiển với yêu cầu ban đầu còn nguyên vẹn. Bạn cũng có thể yên tâm rằng Google sẽ chấp thuận phương pháp này vì nó hoàn toàn xảy ra ở phía máy chủ.

Mặc dù bạn có thể thực hiện khá nhiều từ cả hai IRouteConstraintIRouteHandler, điểm mở rộng mạnh nhất để định tuyến làRouteBase lớp con. Lớp này có thể được mở rộng để cung cấp cả các tuyến đến và tạo URL đi, điều này làm cho nó trở thành một điểm dừng cho tất cả mọi thứ phải làm với URL và hành động mà URL thực thi.

Vì vậy, để làm theo ví dụ thứ hai của bạn, để đi từ /đến /home/7, bạn chỉ cần một tuyến đường bổ sung các giá trị tuyến thích hợp.

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 }
        );
    }
}

Nhưng quay trở lại ví dụ ban đầu của bạn, nơi bạn có một trang ngẫu nhiên, nó phức tạp hơn vì các tham số tuyến đường không thể thay đổi khi chạy. Vì vậy, nó có thể được thực hiện với một RouteBaselớp con như sau.

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;
    }
}

Mà có thể được đăng ký trong định tuyến như:

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 }
        );
    }
}

Lưu ý trong ví dụ trên, có thể có ý nghĩa khi lưu trữ cookie ghi lại phiên bản trang chủ mà người dùng đã truy cập để khi họ quay lại, họ sẽ nhận được cùng một phiên bản trang chủ.

Cũng lưu ý rằng bằng cách sử dụng phương pháp này, bạn có thể tùy chỉnh định tuyến để xem xét các tham số chuỗi truy vấn (nó hoàn toàn bỏ qua chúng theo mặc định) và định tuyến đến một hành động điều khiển thích hợp tương ứng.

Ví dụ bổ sung


Điều gì sẽ xảy ra nếu tôi không muốn chuyển ngay lập tức khi tham gia một hành động, nhưng hãy để hành động đó thực hiện một số công việc và sau đó có điều kiện chuyển sang hành động khác. Thay đổi định tuyến của tôi để chuyển trực tiếp đến mục tiêu chuyển sẽ không hoạt động, vì vậy có vẻ như Server.TransferRequestkhông phải là "hoàn toàn không cần thiết trong MVC".
ProfK

0

Không phải là một câu trả lời, nhưng rõ ràng yêu cầu không chỉ là điều hướng thực tế để "làm" chức năng tương đương của Webforms Server.Transfer (), mà còn cho tất cả những điều này được hỗ trợ đầy đủ trong thử nghiệm đơn vị.

Do đó, ServerTransferResult sẽ "trông" giống như RedirectToRouteResult và giống nhau nhất có thể về mặt phân cấp lớp.

Tôi đang nghĩ đến việc thực hiện điều này bằng cách xem Reflector và thực hiện bất kỳ lớp RedirectToRouteResult nào và các phương thức lớp cơ sở khác nhau của Bộ điều khiển, sau đó "thêm" cái sau vào Bộ điều khiển thông qua các phương thức mở rộng. Có lẽ đây có thể là các phương thức tĩnh trong cùng một lớp, để dễ dàng / lười biếng tải xuống?

Nếu tôi đi lòng vòng để làm điều này tôi sẽ đăng nó lên, nếu không thì có lẽ ai đó sẽ đánh bại tôi!


0

Tôi đã đạt được điều này bằng cách khai thác trình Html.RenderActiontrợ giúp trong Chế độ xem:

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

Và trong bộ điều khiển của tôi:

public ActionResult MyAction(....)
{
    var routeValues = HttpContext.Request.RequestContext.RouteData.Values;    
    ViewBag.ActionName = "myaction";
    ViewBag.ControllerName = "mycontroller";
    ViewBag.RouteValues = routeValues;    
    return PartialView("_AjaxRedirect");
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.