কিভাবে এএসপি.নেট এমভিসিতে সার্ভার.টান্সফার অনুকরণ করবেন?


124

এএসপি.নেট এমভিসিতে আপনি খুব সহজেই পুনর্নির্দেশের অ্যাকশনারসাল্ট ফিরে আসতে পারেন:

 return RedirectToAction("Index");

 or

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

এটি আসলে একটি এইচটিটিপি পুনর্নির্দেশ দেবে যা সাধারণত ভাল। যাইহোক, গুগল অ্যানালিটিক্স ব্যবহার করার সময় এটি বড় সমস্যার কারণ কারণ মূল রেফারারটি হারিয়ে গেছে তাই গুগল জানেন না আপনি কোথা থেকে এসেছেন। এটি কোনও অনুসন্ধান ইঞ্জিনের পদগুলির মতো দরকারী তথ্য হারায়।

পার্শ্ব নোট হিসাবে, এই পদ্ধতিটিতে প্রচারাভিযান থেকে আসা যে কোনও পরামিতি সরিয়ে ফেলার সুবিধা রয়েছে তবে তবুও সেগুলি আমাকে সার্ভারের দিক থেকে ক্যাপচার করতে দেয়। এগুলি ক্যোয়ারী স্ট্রিংয়ে রেখে দেওয়ার ফলে লোকেরা বুকমার্কিং বা টুইটার বা এমন লিঙ্ক ব্লগ করে যা তাদের উচিত নয়। আমি এটি বেশ কয়েকবার দেখেছি যেখানে লোকেরা প্রচারাভিযানের আইডি সহ আমাদের সাইটে লিঙ্কগুলি ছিটিয়ে ফেলেছে।

যাইহোক, আমি সাইটে সমস্ত আগত দর্শনের জন্য একটি 'গেটওয়ে' নিয়ামক লিখছি যা আমি বিভিন্ন স্থান বা বিকল্প সংস্করণে পুনর্নির্দেশ করতে পারি।

আপাতত আমি গুগল সম্পর্কে আপাতত (দুর্ঘটনাজনিত বুকমার্কিংয়ের চেয়ে বেশি) যত্নশীল এবং আমি চাইলে এমন কাউকে পাঠাতে সক্ষম হতে চাই /যে তারা যদি পৃষ্ঠাগুলিতে যান তবে তারা যদি সেখানে যায় তবে /home/7এটি হোমপেজের version সংস্করণ।

যেমন আমি আগে বলেছিলাম যে আমি যদি এটি করি তবে আমি গুগলের রেফারার বিশ্লেষণ করার ক্ষমতা হারাব:

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

আমি আসলে যা চাই তা হ'ল এক

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

যা আমাকে ক্লায়েন্টের পক্ষ থেকে পুনর্নির্দেশ ছাড়াই সেই ভিউটি পাবে। যদিও আমি মনে করি না যে এ জাতীয় একটি জিনিস বিদ্যমান আছে।

বর্তমানে আমি যে সর্বোত্তম জিনিসটি সামনে আসতে পারি তা হ'ল HomeController.Index(..)আমার GatewayController.Indexঅ্যাকশনে সম্পূর্ণ নিয়ামক যুক্তিকে নকল করা । এর অর্থ আমাকে 'Views/Home'প্রবেশ 'Shared'করতে হয়েছিল তাই এটি অ্যাক্সেসযোগ্য ছিল। এর চেয়ে ভাল উপায় অবশ্যই থাকতে হবে ?? ..


আপনি হুবহু ServerTransferActionপ্রতিলিপি তৈরির চেষ্টা করছেন এমনটি আসলে কী? এটা কি আসল জিনিস? (এটিতে কোনও তথ্য খুঁজে
পেল

সার্ভার.টান্সফার (...) দেখুন। এটি সার্ভার সাইডে মূলত একটি 'পুনর্নির্দেশ' করার একটি উপায় যেখানে ক্লায়েন্ট কোনও ক্লায়েন্টের দিকনির্দেশ ছাড়াই পুনঃনির্দেশিত পৃষ্ঠা পায়। সাধারণত এটি আধুনিক রাউটিংয়ের সাথে প্রস্তাবিত নয়।
সাইমন_উইভার

1
"ট্রান্সফারিং" হ'ল একটি পুরানো এএসপি.এনইটি বৈশিষ্ট্য যা রাউটিংয়ের সাহায্যে সরাসরি সঠিক নিয়ামক ক্রিয়ায় সরাসরি যাওয়ার দক্ষতার কারণে এমভিসিতে আর প্রয়োজন হয় না । বিস্তারিত জানার জন্য এই উত্তরটি দেখুন ।
নাইটওয়েল 888

@ নাইটওয়েল ৮৮৮ হ্যাঁ অবশ্যই - তবে কখনও কখনও ব্যবসায়ের যুক্তির কারণে এটি প্রয়োজনীয় / সহজ। আমি এটি ব্যবহার করে কোথায় শেষ হয়ে গেলাম তা দেখার জন্য আমি পিছনে ফিরে তাকালাম - (ভাগ্যক্রমে এটি কেবলমাত্র এক জায়গায় ছিল) - যেখানে আমার একটি হোমপেজ রয়েছে যা আমি কিছু জটিল অবস্থার জন্য গতিশীল হতে চেয়েছিলাম এবং তাই পর্দার পিছনে এটি একটি ভিন্ন পথ দেখায়। রাউটিং বা রুটের অবস্থার পক্ষে যথাসম্ভব এড়াতে চান - তবে কখনও কখনও একটি সরল ifবিবৃতি সমাধানকে খুব লোভনীয় করে তোলে।
সাইমন_উইভার

@ সিমন_উইভার - এবং সাবক্লাসিংয়ে কী সমস্যা আছে RouteBaseযাতে আপনি একটি ifবিবরণী থেকে অন্য নিয়ামকের দিকে ঝাঁপিয়ে পড়ার পরিবর্তে সমস্ত কিছু পিছন দিকে ঘুরিয়ে না দিয়ে নিজের বক্তব্যটি সেখানে রাখতে পারেন ?
নাইটওয়েল ৮৮৮

উত্তর:


130

ট্রান্সফারসেল্ট ক্লাসটি কেমন? ( স্ট্যানসের উত্তরের ভিত্তিতে )

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

আপডেট হয়েছে: এখন এমভিসি 3 ( সিমনের পোস্ট থেকে কোড ব্যবহার করে ) নিয়ে কাজ করে। এটি আইআইএস 7+ এর ইন্টিগ্রেটেড পাইপলাইনের মধ্যে চলছে কিনা তা দেখে এমভিসি 2 তে কাজ করা উচিত (এটি পরীক্ষা করতে সক্ষম হওয়া উচিত নয়)।

সম্পূর্ণ স্বচ্ছতার জন্য; আমাদের উত্পাদন পরিবেশে আমরা কখনই সরাসরি ট্রান্সফারআরসাল্ট ব্যবহার করি নি। আমরা একটি ট্রান্সফারটোরিটসেল্ট ব্যবহার করি যা ঘুরেফিরে কলগুলি ট্রান্সফার রিসাল্ট কার্যকর করে। আমার প্রোডাকশন সার্ভারগুলিতে আসলে যা চলছে তা এখানে।

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
এটি দুর্দান্ত কাজ করে। অসীম লুপটি শেষ না হওয়ার বিষয়ে সতর্ক থাকুন - যেমনটি আমি ভুল ইউআরএল পাস করার মাধ্যমে আমার প্রথম প্রয়াসে করেছিলাম route রুটের মান সংগ্রহকে পাস করার অনুমতি দেওয়ার জন্য আমি একটি ছোট পরিবর্তন করেছি যা অন্যের পক্ষে কার্যকর useful উপরে বা নীচে পোস্ট করা হয়েছে ...
সাইমন_ ওয়েভার

আপডেট: এই সমাধানটি ভালভাবে কাজ করছে বলে মনে হচ্ছে, এবং যদিও আমি এটি কেবলমাত্র খুব সীমিত ক্ষমতার মধ্যে ব্যবহার করছি এখনও কোনও সমস্যা খুঁজে পাওয়া যায় নি
সাইমন_উইভার

একটি ইস্যু: পিওএসটি থেকে জিইটি অনুরোধে পুনর্নির্দেশ করতে পারে না - তবে এটি কোনও খারাপ জিনিস নয়। যদিও কিছু সতর্ক হতে হবে
সাইমন_উইভার

2
@ ব্র্যাডলেনি: আপনি কেবল 'var urlelel ...' এবং 'var url ...' লাইনগুলি সরাতে পারবেন এবং 'url' এর সাথে 'this.Url' দিয়ে প্রতিস্থাপন করতে পারেন এবং এটি কাজ করে। :)
মাইকেল উলমান

1
1: সংযোগ / ইউনিট পরীক্ষা / ভবিষ্যতের সামঞ্জস্য। 2: এমভিসি কোর / এমভিসি নমুনাগুলি কখনও এই সিঙ্গলটন ব্যবহার করে না। 3: এই সিঙ্গলটন কোনও থ্রেডে (নাল) উপলভ্য নয়, হয় পুলের থ্রেড বা অ্যাসিঙ্ক প্রতিনিধি হিসাবে ডিফল্ট ব্যতীত অন্য কোনও প্রসঙ্গে ডাকা হয়, যেমন অ্যাসিঙ্ক অ্যাকশন পদ্ধতি ব্যবহার করার সময়। 4: শুধুমাত্র সামঞ্জস্যের উদ্দেশ্যে, এমভিসি এই সিঙ্গলটন মানকে প্রসঙ্গে সেট করে user ব্যবহারকারী কোড প্রবেশের আগে HTTPContext।
সফটলিয়ন

47

সম্পাদনা করুন: এএসপি.নেট এমভিসি 3 এর সাথে সামঞ্জস্য হতে আপডেট হয়েছে

আপনি যদি আইআইএস Prov ব্যবহার করছেন তবে নীচের সংশোধনগুলি এএসপি.নেট এমভিসি ৩ এর জন্য কাজ করছে বলে মনে হচ্ছে 3.. মূল কোডটি কাজ করে নি বলে নির্দেশ দেওয়ার জন্য @ নিতিন এবং @ এনডিকে ধন্যবাদ।

4/11/2011 সম্পাদনা করুন: টেম্পাটাটা এমভিসি 3 আরটিএম হিসাবে সার্ভারের সাথে ট্রান্সফারআরয়েস্ট বিচ্ছেদ করে

একটি ব্যতিক্রম ছুঁড়ে দেওয়ার জন্য নীচের কোডটি সংশোধন করে - তবে এই মুহুর্তে অন্য কোনও সমাধান নেই।


মার্কের স্ট্যানের আসল পোস্টের পরিবর্তিত সংস্করণের উপর ভিত্তি করে এখানে আমার পরিবর্তন। আমি একটি রুট মান অভিধান নিতে একটি অতিরিক্ত নির্মাতা যুক্ত করেছি - এবং এটি এমভিসিটি ট্রান্সফার রিসাল্টের নামকরণ করে বিভ্রান্তি এড়াতে এটি কেবল পুনর্নির্দেশ হতে পারে।

পুনঃনির্দেশের জন্য আমি এখন নিম্নলিখিতগুলি করতে পারি:

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
এটি এমভিসি 3 আরসিতে কাজ করছে না বলে মনে হচ্ছে। HttpHandler.ProcessRequest () এ ব্যর্থ হয়েছে, বলেছেন: 'HttpContext.SetSessionStateBehaviver' কেবলমাত্র 'HttpApplication.AcquireRequestState' ইভেন্ট উত্থাপনের আগেই ডাকা যেতে পারে।
অ্যান্ডি

এমভিসি 3 এ দেখার জন্য আমার এখনও কোনও পরিবর্তন হয়নি। আপনি যদি কোনও সমাধান খুঁজে পান তবে আমাকে জানতে দিন
সাইমন_উইভার

নীটিনের পরামর্শ অনুসারে সার্ভার.টান্সফারকিউয়েস্ট উপরেরটি যা করার চেষ্টা করছে তা কি করে?
পুরাতন গিজার

নাল এবং গণনা> 0 এর জন্য আমাদের কেন টেম্পাটাটা পরীক্ষা করা দরকার?
yurart

আপনি এটি করেন না তবে এটি কেবল একটি সুরক্ষা বৈশিষ্ট্য তাই আপনি যদি ইতিমধ্যে এটি ব্যবহার করে থাকেন এবং এর উপর নির্ভর করেন তবে এটি অদৃশ্য হয়ে গেলে আপনার মাথা আঁচড়ানো ছেড়ে যাবে না
সাইমন_উইভার


12

আমি সম্প্রতি জানতে পেরেছি যে এএসপি.এনইটি এমভিসি সার্ভার.টান্সফার () সমর্থন করে না তাই আমি একটি স্টাব পদ্ধতি তৈরি করেছি (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
না, আপনি যে কন্ট্রোলারটি তৈরি করেছেন তার কাছে অনুরোধ এবং প্রতিক্রিয়া সেটআপের মতো জিনিসগুলি এতে সঠিকভাবে থাকবে না। যা সমস্যার সৃষ্টি করতে পারে।
জেফ ওয়াকার কোড রেঞ্জার

আমি @ জেফওয়ালারকোডরেঞ্জারের সাথে একমত: সম্পত্তি সেট করার পরেও একই জিনিসotherController.ControllerContext = this.ControllerContext;
টি-মোটি

7

আমি অন্য অনুরোধকারী / ক্রিয়ায় বর্তমান অনুরোধটিকে পুনরায় রুট করতে চেয়েছিলাম, মৃত্যুদন্ডের পথটি ঠিক একইরকম রেখে যেমন দ্বিতীয় দ্বিতীয় নিয়ামক / ক্রিয়াকলাপের অনুরোধ করা হয়েছিল। আমার ক্ষেত্রে, সার্ভার.উইকুয়েস্ট কাজ করবে না কারণ আমি আরও ডেটা যুক্ত করতে চেয়েছিলাম। এটি প্রকৃতপক্ষে বর্তমানের হ্যান্ডলারটি অন্য কোনও এইচটিটিপি জিইটি / পোষ্টকে কার্যকর করে তারপরে ক্লায়েন্টের কাছে ফলাফলগুলি স্ট্রিম করে। আমি নিশ্চিত যে এটি অর্জনের আরও ভাল উপায় থাকবে তবে আমার পক্ষে কাজ করে তা এখানে:

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

এবং আমি এটি বিকাশকারীদের ত্রুটিগুলি প্রদর্শনের জন্য ব্যবহার করছি, যখন এটি উত্পাদনে নিয়মিত পুনঃনির্দেশ ব্যবহার করবে। নোট করুন যে আমি এএসপি.নেট সেশন, ডাটাবেস বা অনুরোধের মধ্যে ব্যতিক্রম ডেটা পাস করার জন্য কিছু অন্যান্য উপায় ব্যবহার করতে চাই নি।


7

বরং অনুকরণ একটি সার্ভার স্থানান্তর করার পরিবর্তে, MVC এখনও আসলে একটি কাজ করতে সক্ষম হয় Server.TransferRequest :

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

আরও উত্তরের জন্য আপনার উত্তরে কিছু পাঠ্য নির্বিশেষে সংযুক্ত করুন।
ও্লাদিমির প্যালান্ট

নোট করুন এটির জন্য MVCv3 এবং তার বেশি প্রয়োজন।
Seph

5

কেবলমাত্র অন্য নিয়ামকটিকে উদাহরণস্বরূপ করুন এবং এর ক্রিয়া পদ্ধতিটি কার্যকর করুন।


এটি ঠিকানা বারে পছন্দসই ইউআরএল প্রদর্শন করবে না
arserbin3

@ arserbin3 - সার্ভারও হবে না rans ট্রান্সফার। এই প্রয়োজনীয়তাটি সম্ভবত মূল প্রশ্নটি এমনকি পোস্ট করা হয়েছিল কেন।
রিচার্ড জাজলে

2

আপনি অন্য নিয়ামককে নতুন করতে পারেন এবং ফলাফলটি ফিরিয়ে দেওয়ার জন্য অ্যাকশন পদ্ধতির আবেদন করতে পারেন। এটির জন্য আপনাকে নিজের মতামত ভাগ করা ফোল্ডারে রাখতে হবে।

আমি নিশ্চিত নই যে আপনি এটি নকল দ্বারা বোঝাতে চেয়েছিলেন তবে:

return new HomeController().Index();

সম্পাদন করা

অন্য একটি বিকল্প হতে পারে আপনার নিজের কন্ট্রোলার ফ্যাক্টরি তৈরি করা, আপনি কোন নিয়ামক তৈরি করবেন তা এইভাবে নির্ধারণ করতে পারেন।


এই পদ্ধতির হতে পারে, তবে এটির প্রসঙ্গটি ঠিক মতো বলে মনে হচ্ছে না - এমনকি আমি যদি hc.ControllerContext = this.ControllerContext বলি। প্লাস এটি পরে Views / ভিউজ / গেটওয়ে / 5. এসপিএক্স এর অধীনে দেখুন এবং এটি খুঁজে পাবে না।
সাইমন_উইভার 19

এছাড়াও আপনি সমস্ত অ্যাকশন ফিল্টার হারাবেন। আপনি সম্ভবত আইকন্ট্রোলার ইন্টারফেসে এক্সিকিউট পদ্ধতিটি ব্যবহার করতে চেষ্টা করতে চান যা আপনার নিয়ামকরা অবশ্যই প্রয়োগ করতে পারেন। উদাহরণস্বরূপ: ((আইকন্ট্রোলার) নতুন হোম কন্ট্রোলার ()) কার্যকর করুন (...)। আপনি এখনও অ্যাকশন ইনভোকার পাইপলাইনে অংশ নিচ্ছেন। এক্সিকিউট করতে গেলে কী পাস করতে হবে তা আপনি ঠিকই বুঝতে পারবেন ... প্রতিচ্ছবি সেখানে সহায়তা করতে পারে :)
অ্যান্ড্রু স্ট্যান্টন-নার্স

হ্যাঁ, আমি একটি নিয়ামক স্থাপনের ধারণা পছন্দ করি না, আমি মনে করি আপনার নিজের নিয়ামক কারখানাকে সংজ্ঞায়িত করা আপনার পক্ষে আরও ভাল extension তবে আমি এই কাঠামোর পৃষ্ঠ সবেই আঁচড়েছি যাতে আমি যেতে পারি।
জোশবার্ক

1

রাউটিং কি কেবল আপনার জন্য এই দৃশ্যের যত্ন নেয় না? যেমন উপরে বর্ণিত দৃশ্যের জন্য, আপনি কেবল একটি যুক্ত রুট হ্যান্ডলার তৈরি করতে পারেন যা এই যুক্তিকে বাস্তবায়িত করেছিল implemented


এটি প্রোগ্রামারিক অবস্থার উপর ভিত্তি করে। উদাহরণস্বরূপ, প্রচারাভিযান 100 টি 7 দেখতে যেতে পারে এবং 200 প্রচার প্রচারণা 8 দেখতে পাবে etc. ইত্যাদি ইত্যাদি রাউটিংয়ের জন্য খুব জটিল
সাইমন_উইভার

4
রাউটিংয়ের জন্য কেন এটি খুব জটিল? কাস্টম রুটের সীমাবদ্ধতায় কী সমস্যা? স্টেফেনওয়ালার.
ইয়ান Mercer

1

যে কেউ এক্সপ্রেশন-ভিত্তিক রাউটিং ব্যবহার করছেন, কেবলমাত্র উপরের ট্রান্সফারসেল্ট ক্লাস ব্যবহার করে, এখানে একটি নিয়ামক বর্ধন পদ্ধতি রয়েছে যা কৌশলটি করে এবং টেম্পাটাটা সংরক্ষণ করে। 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);
}

সতর্কতা: এটি ত্রুটির কারণ বলে মনে হচ্ছে 'সেশনস্টেটটিম্পডাটা ডেটাপ্রাইডার শ্রেণীর জন্য সেশন স্টেটটি সক্ষম করা দরকার' যদিও এটি এখনও কাজ করে। আমি কেবল আমার লগগুলিতে এই ত্রুটিটি দেখতে পাচ্ছি। আমি ত্রুটি লগিংয়ের জন্য ELMAH ব্যবহার করছি এবং ইনপ্রোক এবং অ্যাপফ্যাব্রিকের জন্য এই ত্রুটিটি পেয়েছি
সাইমন_উইভার

1

Server.TransferRequestহয় MVC সম্পূর্ণভাবে অপ্রয়োজনীয় । এটি একটি পুরানো বৈশিষ্ট্য যা কেবলমাত্র এএসপি.এনইটি-তে প্রয়োজনীয় ছিল কারণ অনুরোধটি সরাসরি কোনও পৃষ্ঠায় আসে এবং অনুরোধটি অন্য পৃষ্ঠায় স্থানান্তর করার উপায় হওয়া দরকার। এএসপি.এনইটির আধুনিক সংস্করণগুলিতে (এমভিসি সহ) একটি রাউটিং অবকাঠামো রয়েছে যা পছন্দসই সংস্থানটিতে সরাসরি রুটে কাস্টমাইজ করা যায় । আপনি কেবল অনুরোধটিকে সরাসরি নিয়ন্ত্রকের কাছে যেতে চান এবং আপনি যে ক্রিয়াটি চান সেটিকে অনুরোধটি কেবলমাত্র অন্য নিয়ামককে স্থানান্তর করতে কোনও নিয়ামকের কাছে পৌঁছানোর কোনও কারণ নেই।

এর চেয়ে বড় বিষয় হ'ল আপনি যেহেতু মূল অনুরোধটির প্রতিক্রিয়া জানাচ্ছেন TempDataতাই অনুরোধটি সঠিক জায়গায় পৌঁছানোর জন্য কেবল কোনও কিছু বা অন্য সঞ্চয়স্থানে টোকা দেওয়ার দরকার নেই । পরিবর্তে, আপনি মূল অনুরোধ অক্ষত সঙ্গে নিয়ামক ক্রিয়া এ পৌঁছেছেন। আপনিও আশ্বস্ত হতে পারেন যে সার্ভারের দিক থেকে এটি পুরোপুরি ঘটে বলে গুগল এই পদ্ধতির অনুমোদন করবে।

আপনি উভয় থেকে বেশ কিছুটা করতে পারেন IRouteConstraintএবং IRouteHandler, রাউটিংয়ের জন্য সবচেয়ে শক্তিশালী এক্সটেনশন পয়েন্টটি RouteBaseসাবক্লাস। এই শ্রেণিটি আগত রুট এবং বহির্গামী ইউআরএল উভয় প্রকারের উভয়ই সরবরাহ করতে বাড়ানো যেতে পারে, যা ইউআরএল এবং ইউআরএল সম্পাদন করে এমন ক্রিয়াকলাপের সাথে যা কিছু করা যায় তার জন্য এটি স্টপ শপ করে।

সুতরাং, আপনার দ্বিতীয় উদাহরণ অনুসরণ থেকে পেতে, /থেকে /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 }
        );
    }
}

উপরের উদাহরণে নোট করুন, কোনও কুকিটিকে হোম পেজ সংস্করণটি ব্যবহারকারী যে ঘরে এনেছে সেগুলি সংরক্ষণ করার পরেও তারা একই হোম পেজ সংস্করণটি গ্রহণ করবে sense

এছাড়াও নোট করুন যে এই পদ্ধতির সাহায্যে আপনি ক্যোয়ারিং স্ট্রিং প্যারামিটারগুলিকে বিবেচনায় নিতে রুটিংটি কাস্টমাইজ করতে পারেন (এটি তাদের ডিফল্টরূপে সম্পূর্ণভাবে উপেক্ষা করে) এবং তদনুসারে একটি উপযুক্ত নিয়ামক পদক্ষেপের দিকে যেতে পারে।

অতিরিক্ত উদাহরণ


আমি যদি কোনও ক্রিয়াকলাপে প্রবেশের সাথে সাথেই হস্তান্তর করতে চাই না তবে বরং সেই ক্রিয়াটি কিছু কাজ করতে দিন এবং শর্তসাপেক্ষে অন্য ক্রিয়ায় স্থানান্তর করুন। প্রত্যক্ষ স্থানান্তর টার্গেটে যাওয়ার জন্য আমার রুটিং পরিবর্তন করা কার্যকর হবে না, সুতরাং দেখে মনে হচ্ছে Server.TransferRequest, "এমভিসিতে সম্পূর্ণ অপ্রয়োজনীয়" নয়।
অধ্যাপক

0

প্রতি সেউর কোনও উত্তর নয়, তবে স্পষ্টতই প্রয়োজনীয়তা কেবলমাত্র ওয়েবফর্ম সার্ভারের সমতুল কার্যকারিতা "করার" জন্য নয়, ট্রান্সফার (), কিন্তু ইউনিট টেস্টিংয়ের মধ্যে এই সমস্তটির পুরোপুরি সমর্থন করাও প্রয়োজন।

সুতরাং সার্ভার ট্রান্সফারআরসাল্টকে একটি "RedirectToRouteResult" এর মতো দেখতে "ক্লাস হায়ারার্কির ক্ষেত্রে" যথাসম্ভব সমান হওয়া উচিত।

আমি রিফ্লেক্টরটি দেখে এবং রেডাইরেক্টটোরআউটআরসাল্ট ক্লাস এবং বিভিন্ন কন্ট্রোলার বেস ক্লাসের পদ্ধতিগুলি যা কিছু করে তা করার কথা ভাবছি এবং তারপরে এক্সটেনশন পদ্ধতির মাধ্যমে কন্ট্রোলারে "যুক্ত" করছি। ডাউনলোডের স্বাচ্ছন্দ্য / অলসতার জন্য এগুলি একই শ্রেণীর মধ্যে স্থির পদ্ধতি হতে পারে?

যদি আমি এটি করতে দেরি করি তবে আমি এটি পোস্ট করব, নাহলে অন্য কেউ আমাকে মারতে পারে!


0

আমি এই Html.RenderActionদৃশ্যে সাহায্যকারীকে কাজে লাগিয়ে এটি অর্জন করেছি :

@{
    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.