এমভিসিতে কীভাবে ডিফল্ট রুট (কোনও অঞ্চলে) সেট করবেন


122

ঠিক আছে এটি আগে জিজ্ঞাসা করা হয়েছিল কিন্তু এর কোনও শক্ত সমাধান নেই। সুতরাং আমার এবং অন্যদের উদ্দেশ্যে যারা এই দরকারী হতে পারে।

এমভিসি 2 তে (এএসপি.এনইটি) আমি এটি চাই তাই যখন কেউ ওয়েবসাইটে নেভিগেট করেন, সেখানে একটি ডিফল্ট অঞ্চল নির্দিষ্ট থাকে। সুতরাং আমার সাইটে নেভিগেট করা আপনাকে এরিয়াজেডের কন্ট্রোলারএক্স অ্যাকশনওয়াইতে প্রেরণ করা উচিত।

গ্লোবাল.অ্যাক্সেক্সে নিম্নলিখিত রুটটি ব্যবহার করে

routes.MapRoute(
                "Area",
                "",
                new { area = "AreaZ", controller = "ControllerX ", action = "ActionY " }
            );

এখন এটি যেমন কাজ করে ঠিক পৃষ্ঠাটি পরিবেশন করার চেষ্টা করে না। তবে এমভিসি এরিয়া ফোল্ডারে নয়, সাইটের মূলটিতে ভিউ সন্ধান করতে এগিয়ে যায়।

এটি সমাধান করার কোন উপায় আছে?

সম্পাদনা

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

         public ActionResult ActionY()
        {
            return View("~/Areas/AreaZ/views/ActionY.aspx");
        }

সম্পাদনা:

পৃষ্ঠার এইচটিএমএল অ্যাকশনলিঙ্ক থাকার সময় এটিও একটি সমস্যা হয়ে দাঁড়ায়। যদি অঞ্চলটি সেট না করা হয় তবে অ্যাকশন লিঙ্কটি আউটপুট ফাঁকা।

এসব কি ডিজাইনের মাধ্যমে নাকি কোনও ত্রুটিযুক্ত?

উত্তর:


98

এই একজন আমাকে আগ্রহী এবং অবশেষে আমি এটি সন্ধান করার সুযোগ পেয়েছি। অন্যান্য লোকেরা আপাতদৃষ্টিতে বুঝতে পারেন নি যে এই দৃষ্টিভঙ্গি খুঁজে বের করার একটি সমস্যা, রাউটিংয়ের কোনও সমস্যা নয় নিজেই নয় - এবং এটি সম্ভবত আপনার প্রশ্নের শিরোনাম নির্দেশ করে যে এটি রাউটিং সম্পর্কে।

যাই হোক না কেন, এটি একটি ভিউ-সম্পর্কিত সমস্যা, তাই আপনি যা চান তা পাওয়ার একমাত্র উপায় হ'ল ডিফল্ট ভিউ ইঞ্জিনটিকে ওভাররাইড করে । সাধারণত, আপনি যখন এটি করেন, এটি আপনার ভিউ ইঞ্জিনটি স্যুইচ করার সহজ উদ্দেশ্যে (যেমন স্পার্ক, এনএইচএল ইত্যাদি)। এক্ষেত্রে, আমাদের দেখার প্রয়োজন যুক্তি-নির্মাণের যুক্তিটি নয় , ক্লাসে পদ্ধতি FindPartialViewএবং FindViewপদ্ধতি VirtualPathProviderViewEngine

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

আমি এখানে যা করেছি তা হ'ল প্রথমে একটি বিমূর্ততা তৈরি করা AreaAwareViewEngineযা সরাসরি VirtualPathProviderViewEngineপরিবর্তে থেকে আসে WebFormViewEngine। আমি এটি করেছি যাতে আপনি পরিবর্তে (বা যাই হোক না কেন) স্পার্ক ভিউ তৈরি করতে চান তবে আপনি এখনও এই শ্রেণিকে বেস টাইপ হিসাবে ব্যবহার করতে পারেন।

নীচের কোডটি বেশ দীর্ঘ-বায়ুযুক্ত, সুতরাং এটি আসলে কী করে তা আপনাকে একটি দ্রুত সংক্ষিপ্ত বিবরণ দেওয়ার জন্য: এটি আপনাকে {2}অবস্থান বিন্যাসে একটি স্থান দিতে দেয় যা একইরূপে এলাকার নামের সাথে মিলে যায়{1} নিয়ামকের নামের সাথে মিলে যায়। এটাই! এই জন্য আমাদের এই সমস্ত কোডটি লিখতে হয়েছিল:

BaseAreaAwareViewEngine.cs

public abstract class BaseAreaAwareViewEngine : VirtualPathProviderViewEngine
{
    private static readonly string[] EmptyLocations = { };

    public override ViewEngineResult FindView(
        ControllerContext controllerContext, string viewName,
        string masterName, bool useCache)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }
        if (string.IsNullOrEmpty(viewName))
        {
            throw new ArgumentNullException(viewName,
                "Value cannot be null or empty.");
        }

        string area = getArea(controllerContext);
        return FindAreaView(controllerContext, area, viewName,
            masterName, useCache);
    }

    public override ViewEngineResult FindPartialView(
        ControllerContext controllerContext, string partialViewName,
        bool useCache)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }
        if (string.IsNullOrEmpty(partialViewName))
        {
            throw new ArgumentNullException(partialViewName,
                "Value cannot be null or empty.");
        }

        string area = getArea(controllerContext);
        return FindAreaPartialView(controllerContext, area,
            partialViewName, useCache);
    }

    protected virtual ViewEngineResult FindAreaView(
        ControllerContext controllerContext, string areaName, string viewName,
        string masterName, bool useCache)
    {
        string controllerName =
            controllerContext.RouteData.GetRequiredString("controller");
        string[] searchedViewPaths;
        string viewPath = GetPath(controllerContext, ViewLocationFormats,
            "ViewLocationFormats", viewName, controllerName, areaName, "View",
            useCache, out searchedViewPaths);
        string[] searchedMasterPaths;
        string masterPath = GetPath(controllerContext, MasterLocationFormats,
            "MasterLocationFormats", masterName, controllerName, areaName,
            "Master", useCache, out searchedMasterPaths);
        if (!string.IsNullOrEmpty(viewPath) &&
            (!string.IsNullOrEmpty(masterPath) || 
              string.IsNullOrEmpty(masterName)))
        {
            return new ViewEngineResult(CreateView(controllerContext, viewPath,
                masterPath), this);
        }
        return new ViewEngineResult(
            searchedViewPaths.Union<string>(searchedMasterPaths));
    }

    protected virtual ViewEngineResult FindAreaPartialView(
        ControllerContext controllerContext, string areaName,
        string viewName, bool useCache)
    {
        string controllerName =
            controllerContext.RouteData.GetRequiredString("controller");
        string[] searchedViewPaths;
        string partialViewPath = GetPath(controllerContext,
            ViewLocationFormats, "PartialViewLocationFormats", viewName,
            controllerName, areaName, "Partial", useCache,
            out searchedViewPaths);
        if (!string.IsNullOrEmpty(partialViewPath))
        {
            return new ViewEngineResult(CreatePartialView(controllerContext,
                partialViewPath), this);
        }
        return new ViewEngineResult(searchedViewPaths);
    }

    protected string CreateCacheKey(string prefix, string name,
        string controller, string area)
    {
        return string.Format(CultureInfo.InvariantCulture,
            ":ViewCacheEntry:{0}:{1}:{2}:{3}:{4}:",
            base.GetType().AssemblyQualifiedName,
            prefix, name, controller, area);
    }

    protected string GetPath(ControllerContext controllerContext,
        string[] locations, string locationsPropertyName, string name,
        string controllerName, string areaName, string cacheKeyPrefix,
        bool useCache, out string[] searchedLocations)
    {
        searchedLocations = EmptyLocations;
        if (string.IsNullOrEmpty(name))
        {
            return string.Empty;
        }
        if ((locations == null) || (locations.Length == 0))
        {
            throw new InvalidOperationException(string.Format("The property " +
                "'{0}' cannot be null or empty.", locationsPropertyName));
        }
        bool isSpecificPath = IsSpecificPath(name);
        string key = CreateCacheKey(cacheKeyPrefix, name,
            isSpecificPath ? string.Empty : controllerName,
            isSpecificPath ? string.Empty : areaName);
        if (useCache)
        {
            string viewLocation = ViewLocationCache.GetViewLocation(
                controllerContext.HttpContext, key);
            if (viewLocation != null)
            {
                return viewLocation;
            }
        }
        if (!isSpecificPath)
        {
            return GetPathFromGeneralName(controllerContext, locations, name,
                controllerName, areaName, key, ref searchedLocations);
        }
        return GetPathFromSpecificName(controllerContext, name, key,
            ref searchedLocations);
    }

    protected string GetPathFromGeneralName(ControllerContext controllerContext,
        string[] locations, string name, string controllerName,
        string areaName, string cacheKey, ref string[] searchedLocations)
    {
        string virtualPath = string.Empty;
        searchedLocations = new string[locations.Length];
        for (int i = 0; i < locations.Length; i++)
        {
            if (string.IsNullOrEmpty(areaName) && locations[i].Contains("{2}"))
            {
                continue;
            }
            string testPath = string.Format(CultureInfo.InvariantCulture,
                locations[i], name, controllerName, areaName);
            if (FileExists(controllerContext, testPath))
            {
                searchedLocations = EmptyLocations;
                virtualPath = testPath;
                ViewLocationCache.InsertViewLocation(
                    controllerContext.HttpContext, cacheKey, virtualPath);
                return virtualPath;
            }
            searchedLocations[i] = testPath;
        }
        return virtualPath;
    }

    protected string GetPathFromSpecificName(
        ControllerContext controllerContext, string name, string cacheKey,
        ref string[] searchedLocations)
    {
        string virtualPath = name;
        if (!FileExists(controllerContext, name))
        {
            virtualPath = string.Empty;
            searchedLocations = new string[] { name };
        }
        ViewLocationCache.InsertViewLocation(controllerContext.HttpContext,
            cacheKey, virtualPath);
        return virtualPath;
    }


    protected string getArea(ControllerContext controllerContext)
    {
        // First try to get area from a RouteValue override, like one specified in the Defaults arg to a Route.
        object areaO;
        controllerContext.RouteData.Values.TryGetValue("area", out areaO);

        // If not specified, try to get it from the Controller's namespace
        if (areaO != null)
            return (string)areaO;

        string namespa = controllerContext.Controller.GetType().Namespace;
        int areaStart = namespa.IndexOf("Areas.");
        if (areaStart == -1)
            return null;

        areaStart += 6;
        int areaEnd = namespa.IndexOf('.', areaStart + 1);
        string area = namespa.Substring(areaStart, areaEnd - areaStart);
        return area;
    }

    protected static bool IsSpecificPath(string name)
    {
        char ch = name[0];
        if (ch != '~')
        {
            return (ch == '/');
        }
        return true;
    }
}

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

AreaAwareViewEngine.cs

public class AreaAwareViewEngine : BaseAreaAwareViewEngine
{
    public AreaAwareViewEngine()
    {
        MasterLocationFormats = new string[]
        {
            "~/Areas/{2}/Views/{1}/{0}.master",
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.master",
            "~/Areas/{2}/Views/Shared/{0}.cshtml",
            "~/Views/{1}/{0}.master",
            "~/Views/{1}/{0}.cshtml",
            "~/Views/Shared/{0}.master"
            "~/Views/Shared/{0}.cshtml"
        };
        ViewLocationFormats = new string[]
        {
            "~/Areas/{2}/Views/{1}/{0}.aspx",
            "~/Areas/{2}/Views/{1}/{0}.ascx",
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.aspx",
            "~/Areas/{2}/Views/Shared/{0}.ascx",
            "~/Areas/{2}/Views/Shared/{0}.cshtml",
            "~/Views/{1}/{0}.aspx",
            "~/Views/{1}/{0}.ascx",
            "~/Views/{1}/{0}.cshtml",
            "~/Views/Shared/{0}.aspx"
            "~/Views/Shared/{0}.ascx"
            "~/Views/Shared/{0}.cshtml"
        };
        PartialViewLocationFormats = ViewLocationFormats;
    }

    protected override IView CreatePartialView(
        ControllerContext controllerContext, string partialPath)
    {
        if (partialPath.EndsWith(".cshtml"))
            return new System.Web.Mvc.RazorView(controllerContext, partialPath, null, false, null);
        else
            return new WebFormView(controllerContext, partialPath);
    }

    protected override IView CreateView(ControllerContext controllerContext,
        string viewPath, string masterPath)
    {
        if (viewPath.EndsWith(".cshtml"))
            return new RazorView(controllerContext, viewPath, masterPath, false, null);
        else
            return new WebFormView(controllerContext, viewPath, masterPath);
    }
}

নোট করুন যে আমরা স্ট্যান্ডার্ডটিতে কয়েকটি এন্ট্রি যুক্ত করেছি ViewLocationFormats। এগুলি {2}হ'ল নতুন এন্ট্রি, যেখানে আমরা যে {2}নথিটি রেখেছি তা ম্যাপ করা হবে । আমি একা রেখেছি , তবে আপনি চাইলে আপনি তা পরিবর্তন করতে পারেন।areaRouteDataMasterLocationFormats

global.asaxএই ভিউ ইঞ্জিনটি নিবন্ধ করার জন্য এখন আপনার সংশোধন করুন :

Global.asax.cs

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new AreaAwareViewEngine());
}

... এবং ডিফল্ট রুটটি নিবন্ধ করুন:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapRoute(
        "Area",
        "",
        new { area = "AreaZ", controller = "Default", action = "ActionY" }
    );
    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = "" }
    );
}

এখন AreaControllerআমরা কেবল উল্লেখ করা তৈরি করুন :

DefaultController.cs (~ / নিয়ন্ত্রণকারী / এ)

public class DefaultController : Controller
{
    public ActionResult ActionY()
    {
        return View("TestView");
    }
}

স্পষ্টতই আমাদের ডিরেক্টরি কাঠামো এবং এটির সাথে দেখতে প্রয়োজন - আমরা এটি অতি সাধারণ রাখব:

টেস্টভিউ.এএসপিএক্স (~ / অঞ্চলসমূহ / এরিয়াজেড / ভিউ / ডিফল্ট / বা ~ / অঞ্চল / অঞ্চলজ / দর্শন / ভাগ করা /)

<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<h2>TestView</h2>
This is a test view in AreaZ.

এবং এটাই. অবশেষে, আমরা শেষ করেছি

বেশিরভাগ ক্ষেত্রে, আপনার কেবলমাত্র নেওয়া BaseAreaAwareViewEngineএবং AreaAwareViewEngineএটি কোনও এমভিসি প্রকল্পে ফেলতে সক্ষম হওয়া উচিত , সুতরাং এটি সম্পন্ন করতে প্রচুর কোড লাগলেও, আপনাকে কেবল একবার এটি লিখতে হবে। এর পরে, এটি global.asax.csআপনার সাইটের কাঠামোটি কয়েক লাইন সম্পাদনা এবং তৈরি করার বিষয় just


এটি সাদাসিধে সেরা বর্তমান সমাধান তবে আদর্শ থেকে অনেক দূরে। উপরে যেমন আপনি একবার অ্যাকশনলিঙ্ক যুক্ত করেন বা এ জাতীয় সমস্যা উপস্থিত থাকে।
LiamB

1
@ পিনো: আমি মনে করি আপনার "ডিফল্ট" রুট ম্যাপিংয়ে একইটি ActionLinkযুক্ত করে সমস্যাটি সমাধান করতে সক্ষম হওয়া উচিত । যদিও আমি ইতিবাচক নই; এটি চেষ্টা করুন এবং দেখুন। area = "AreaZ"global.asax.cs
অ্যারোনআউট

এমভিসি 4-তে "ডিফল্ট" রুট ডিক্লারটন গ্লোবাল.অ্যাসাক্স থেকে ~ / App_Start / RouteConfig.cs / RegisterRoutes ()
এন্ড্রি এফ।

3
আমি ডাউনওয়েটকে ঘৃণা করি, তবে @ ক্রিস অলডারসনের নীচের উত্তরটি আমি বেশি বিশ্বাস করতে পারি না বলে সত্যই আমি বিশ্বাস করতে পারি না। এটি এর চেয়ে অনেক সহজ সমাধান এবং প্রান্তের কেসগুলি (অ্যাকশনলিঙ্কস, ইত্যাদি) সমাধান করার জন্য মনে হচ্ছে।
jdmcnair

এখানে একটি বাগ রয়েছে বলে মনে হচ্ছে। উদাহরণস্বরূপ "রে" নামের একটি অঞ্চলের দর্শনগুলি ~ / অঞ্চল / রে / ভিউ / সিটিআরএল / ব্লাহ.এএসপিএক্সে হবে তবে এখানে কোডটি ~ / {2} / {1} / {0 uses ব্যবহার করবে যা ~ /Re/Ctrl/blah.aspx, পথে গুরুত্বপূর্ণ অঞ্চল ডিরেক্টরি অনুপস্থিত। এটি "~ / অঞ্চল / {2} / ভিউ / {1} / {0}।
এসপিএক্স

100

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

var route = routes.MapRoute(
                "Home_Default", 
                "", 
                new {controller = "Home", action = "index" },
                new[] { "IPC.Web.Core.Controllers" }
               );
route.DataTokens["area"] = area;

সম্পাদনা করুন: আপনি নিজের এরিয়া রেজিস্ট্রেশনটিতেও এটি চেষ্টা করতে পারেন the ব্যবহারকারী আপনি যে অঞ্চলে ডিফল্টরূপে যেতে চান সে জন্য রেজিস্টারআরিয়া। আমি এটি পরীক্ষা করে দেখছি না তবে এরিয়া রেজিস্ট্রেশন কনটেক্সট.ম্যাপরোট route.DataTokens["area"] = this.AreaName;আপনাকে সেট করে ।

context.MapRoute(
                    "Home_Default", 
                    "", 
                    new {controller = "Home", action = "index" },
                    new[] { "IPC.Web.Core.Controllers" }
                   );

এটা কাজ করে। নতুন ওয়েব কোডসিগ ফাইলটি সম্পর্কে সাবধান থাকুন, এটি আপনার পুরানো বৈশ্বিক কনফিগারেশনগুলিকে ওভাররাইড করতে পারে।
Mert Akcakaya

56

এমনকি এটি ইতিমধ্যে উত্তর দেওয়া হয়েছিল - এটি সংক্ষিপ্ত বাক্য গঠন (এএসপি নেট 3, 4, 5):

routes.MapRoute("redirect all other requests", "{*url}",
    new {
        controller = "UnderConstruction",
        action = "Index"
        }).DataTokens = new RouteValueDictionary(new { area = "Shop" });

6
এটি আমার পক্ষে দুর্দান্ত কাজ করে। আমার মূলে কোনও নিয়ামক নেই এবং কেবল অঞ্চলগুলি ব্যবহার করি। এমভিসি 4 এর জন্য আমার কাছে এই রুটকনফিগ। ধন্যবাদ!
মার্ক

2
আমি এমভিসি 4 ব্যবহার করছি এবং এটি ছিল আমার পক্ষে সহজ সমাধান। অ্যাপ্লিকেশনটিকে সাইটের 'হোম পেজ' হিসাবে কোনও নির্দিষ্ট অঞ্চলের সূচী দর্শনটি ব্যবহার করার অনুমতি দেয়।
জেটেক

2
এই সমাধানটি ভবিষ্যতে কাজ করবে না (Asp.Net MVC6 এবং উপরের থেকে)
প্যাট্রিক দেশজার্ডিনস

@ পেট্রিকডিজার্ডিনস: উপরের সমাধানটিকে সমর্থন না করার কোনও কারণ?
আকাশ কেসি

@ সিরিয়াসএম আপনার উত্তরটি চিরসবুজ। এটি এখনও সহায়ক। তুমি আমাকে একটি রাত বাঁচিয়েছ
skpaul

16

এটির দৃষ্টিভঙ্গি চিহ্নিত করার বিষয়ে অ্যারনকে ধন্যবাদ জানাতে আমি এটি ভুল বুঝেছি।

[আপডেট] আমি সবেমাত্র একটি প্রকল্প তৈরি করেছি যা কোড বা অনুসন্ধানের কোনও পথের সাথে গোলযোগ না করে ব্যবহারকারীকে ডিফল্ট হিসাবে একটি অঞ্চলে প্রেরণ করে:

Global.asax এ, যথারীতি নিবন্ধন করুন:

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

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = ""}  // Parameter defaults,
        );
    }

ইন Application_Start(), নিম্নলিখিত আদেশ ব্যবহার নিশ্চিত করুন;

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);
    }

আপনার ক্ষেত্রে অঞ্চল নিবন্ধন, ব্যবহার

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "ShopArea_default",
            "{controller}/{action}/{id}",
            new { action = "Index", id = "", controller = "MyRoute" },
            new { controller = "MyRoute" }
        );
    }

একটি উদাহরণ পাওয়া যায় http://www.emphess.net/2010/01/31/areas-routes-and-defaults-in-mvc-2-rc/

আমি সত্যিই আশা করি আপনি এটিই চেয়েছিলেন ...

////

আমি মনে করি না যে ছদ্ম লেখাই ViewEngineএই ক্ষেত্রে সবচেয়ে ভাল সমাধান। (খ্যাতির অভাব, আমি মন্তব্য করতে পারি না)। WebFormsViewEngineফোন সচেতন এবং ধারণ করে AreaViewLocationFormatsযা ডিফল্ট অনুসারে সংজ্ঞায়িত করা হয়

AreaViewLocationFormats = new[] {
        "~/Areas/{2}/Views/{1}/{0}.aspx",
        "~/Areas/{2}/Views/{1}/{0}.ascx",
        "~/Areas/{2}/Views/Shared/{0}.aspx",
        "~/Areas/{2}/Views/Shared/{0}.ascx",
    };

আমি বিশ্বাস করি আপনি এই সম্মেলনে মেনে চলেন না। আপনি পোস্ট করেছেন

public ActionResult ActionY() 
{ 
    return View("~/Areas/AreaZ/views/ActionY.aspx"); 
} 

একটি ওয়ার্কিং হ্যাক হিসাবে, কিন্তু যে হওয়া উচিত

   return View("~/Areas/AreaZ/views/ControllerX/ActionY.aspx"); 

যদি আপনি কনভেনশনটি অনুসরণ করতে না চান তবে আপনি সম্ভবত WebFormViewEngine(যেটি এমভিসিকন্ট্রিবিতে সম্পন্ন হয়েছে) থেকে প্রাপ্ত হয়ে সংক্ষিপ্ত পথ অবলম্বন করতে চাইতে পারেন যেখানে আপনি নির্মাণকারীর মধ্যে অনুসন্ধানের পথ নির্ধারণ করতে পারেন, বা -এ সামান্য হ্যাকি- আপনার কনভেনশনটিকে এভাবে নির্দিষ্ট করে Application_Start:

((VirtualPathProviderViewEngine)ViewEngines.Engines[0]).AreaViewLocationFormats = ...;

এটি অবশ্যই আরও কিছুটা যত্ন সহকারে করা উচিত তবে আমি মনে করি এটি ধারণাটি দেখায়। এই ক্ষেত্র publicমধ্যে VirtualPathProviderViewEngineMVC 2 রেসিন হবে।


এটি লক্ষণীয় যে এটি কেবল এমভিসি 2 আরসিতে প্রযোজ্য - এমভিসি 1 এর VirtualPathProviderViewEngineএই সম্পত্তি নেই এবং এটি অঞ্চল-সচেতন নয়। যদিও এই প্রশ্নটি এমভিসি 2 সম্পর্কে প্রকৃতপক্ষে বলা হয়েছিল, এখনও প্রচুর লোকজন এটি ব্যবহার করছে না (এবং কিছু সময়ের জন্য হবে না)। সুতরাং, নির্দিষ্ট প্রশ্নের জন্য আপনার উত্তরটি আরও সহজ, তবে আমার একমাত্র এমভিসি 1 ব্যবহারকারীদের পক্ষে কাজ করবে যারা এই প্রশ্নটিতে হোঁচট খায়। আমি এমন উত্তর সরবরাহ করতে চাই যা সম্ভাব্য পরিবর্তনের সাপেক্ষে প্রাক-প্রকাশের কার্যকারিতার উপর নির্ভর করে না।
অ্যারোনআউট

এছাড়াও এটি কোনও "সিউডো ভিউ ইঞ্জিন" নয় - ভিউ ইঞ্জিন শ্রেণিগুলি ইচ্ছাকৃতভাবে এক্সটেনসিবল তৈরি করা হয়েছিল যাতে বিভিন্ন ধরণের ভিউ ব্যবহার করা যায়।
অ্যারোনআউট

এটি আপনাকে অপমান করার উদ্দেশ্যে নয়, আমি দুঃখিত। এটি 'সিউডো' যাতে ভিউগুলি পরিচালনা করার পদ্ধতিতে তা উল্লেখযোগ্যভাবে পরিবর্তন করে না, তবে কেবলমাত্র কিছু মান প্রতিস্থাপন করে।
মেনিমসিন

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

2
RegisterAreasআগে যাবার সম্পর্কে দুর্দান্ত টিপ RegisterRoutes। আমার কোডটি হঠাৎ কেন কাজ বন্ধ করে দিয়েছে এবং সেই রিফ্যাক্টরটি লক্ষ্য করেছে কেন তা ভাবছিলাম;)
ওয়েবনুব

6

আমার ধারণা আপনি ~/AreaZএকবারে ~/ইউআরএল পরিদর্শন করেছেন এমন ব্যবহারকারীদের URL- এ পুনঃনির্দেশিত করা উচিত । আমি আপনার মূলের মধ্যে নিম্নলিখিত কোডের মাধ্যমে অর্জন করব HomeController

public class HomeController
{
    public ActionResult Index()
    {
        return RedirectToAction("ActionY", "ControllerX", new { Area = "AreaZ" });
    }
}

এবং নিম্নলিখিত রুট Global.asax

routes.MapRoute(
    "Redirection to AreaZ",
    String.Empty,
    new { controller = "Home ", action = "Index" }
);

এটি কাজ করে তবে এটি ব্যবহারকারীদের ব্রাউজারে URL এ পরিবর্তিত হয়। সত্যিই আদর্শ নয়।
LiamB

2

প্রথমত, আপনি এমভিসি 2 এর কোন সংস্করণ ব্যবহার করছেন? পূর্বরূপ 2 থেকে আরসিতে উল্লেখযোগ্য পরিবর্তন হয়েছে।

ধরে নিলাম আপনি আরসি ব্যবহার করেন, আমি মনে করি আপনার রুট-ম্যাপিংটি অন্যরকম দেখতে হবে। ইন AreaRegistration.csআপনার এলাকায়, আপনি ডিফল্ট রুট, যেমন কোন ধরণের নিবন্ধন করতে পারেন

        context.MapRoute(
            "ShopArea_default",
            "{controller}/{action}/{id}",
            new { action = "Index", id = "", controller="MyRoute" }
        );

উপরের কোডটি MyRouteControllerআমাদের ShopAreaপ্রতি ডিফল্ট ব্যবহারকারীকে প্রেরণ করবে ।

দ্বিতীয় প্যারামিটার হিসাবে খালি স্ট্রিং ব্যবহার করা একটি ব্যতিক্রম ছুঁড়ে ফেলা উচিত, কারণ একটি নিয়ামক নির্দিষ্ট করা আবশ্যক।

অবশ্যই আপনাকে ডিফল্ট রুটটি পরিবর্তন করতে হবে Global.asaxযাতে এটি এই ডিফল্ট রুটের সাথে হস্তক্ষেপ করে না, যেমন মূল সাইটের জন্য একটি উপসর্গ ব্যবহার করে।

এছাড়াও এই থ্রেড এবং হ্যাকের উত্তর দেখুন: এমভিসি 2 এরিয়া রেজিস্ট্রেশন রুটস অর্ডার

আশাকরি এটা সাহায্য করবে.


ধন্যবাদ, তবে আমি নিশ্চিত নই যে এটি প্রশ্নের সমাধানে থাকা সমস্যার সমাধান করে। এবং এর এমভিসি আরসি
লায়ামবি

2

আমার অ্যাপ্লিকেশন_সার্টে নিম্নলিখিতগুলি যুক্ত করা আমার পক্ষে কাজ করে, যদিও আমি নিশ্চিত না যে আপনার কাছে আরসিতে এই সেটিং রয়েছে কিনা:

var engine = (WebFormViewEngine)ViewEngines.Engines.First();

// These additions allow me to route default requests for "/" to the home area
engine.ViewLocationFormats = new string[] { 
    "~/Views/{1}/{0}.aspx",
    "~/Views/{1}/{0}.ascx",
    "~/Areas/{1}/Views/{1}/{0}.aspx", // new
    "~/Areas/{1}/Views/{1}/{0}.ascx", // new
    "~/Areas/{1}/Views/{0}.aspx", // new
    "~/Areas/{1}/Views/{0}.ascx", // new
    "~/Views/{1}/{0}.ascx",
    "~/Views/Shared/{0}.aspx",
    "~/Views/Shared/{0}.ascx"
};

1

এটি কাজ করতে আমি যা করেছি তা হ'ল:

  1. আমি রুট / কন্ট্রোলার ফোল্ডারে একটি ডিফল্ট নিয়ামক তৈরি করেছি। আমি আমার নিয়ামকটির নাম ডিফল্টকন্ট্রোলার রেখেছি।
  2. নিয়ামকটিতে আমি নিম্নলিখিত কোডটি যুক্ত করেছি:

    namespace MyNameSpace.Controllers {
    public class DefaultController : Controller {
        // GET: Default
        public ActionResult Index() {
            return RedirectToAction("Index", "ControllerName", new {area = "FolderName"});
        }
    } }
  3. আমার রাউটার কনফিগ.সিগুলিতে আমি নিম্নলিখিতগুলি যুক্ত করেছি:

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

এই সমস্ত কিছুর পিছনে কৌশলটি হ'ল আমি একটি ডিফল্ট কনস্ট্রাক্টর তৈরি করেছি যা আমার অ্যাপ্লিকেশনটি শুরু হওয়ার সাথে সাথে সর্বদা স্টার্টআপ নিয়ামক হবে। এটি যখন ডিফল্ট নিয়ামককে আঘাত করে এটি ডিফল্ট সূচক ক্রিয়ায় আমি নির্দিষ্ট করা কোনও নিয়ামকের কাছে পুনর্নির্দেশ করবে। যা আমার ক্ষেত্রে হয়

www.myurl.com/FolderName/ControllerName


0
routes.MapRoute(
                "Area",
                "{area}/",
                new { area = "AreaZ", controller = "ControlerX ", action = "ActionY " }
            );

আপনি কি চেষ্টা করেছেন?


হ্যাঁ, সমস্যাটি এখন সত্য যে এখন সাইটটি মূলের মতামতগুলি অনুসন্ধান করে। 'অ্যাকশনওয়াই' বা এর কর্তাটি পাওয়া যায়নি। নিম্নলিখিত অবস্থানগুলি অনুসন্ধান করা হয়েছিল: ~ / ভিউজ / অ্যাকশনওয়াই / অ্যাকশনওয়াই.এএসপিএক্স Views / ভিউ / অ্যাকশনওয়াই / অ্যাকশনওয়াই.এক্সএক্স ~ / ভিউ / শেয়ার্ড / অ্যাকশনওয়াই.এএসপিএক্স Views / ভিউ / শেয়ার্ড / অ্যাকশনওয়াই.এক্সএক্স
লায়ামবি

2
আমি বুঝেছি. আমি একটি সমাধান খুঁজতে চেষ্টা করতে যাচ্ছি। প্রশ্নের জন্য +1
বারবারোস আল্প

0

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

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing;

namespace MvcApplication1 {

   public class GlobalApplication : System.Web.HttpApplication
   {
       public static void RegisterRoutes(RouteCollection routes)
       {
           routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

           routes.MapRoute(
               "Default",                                          // Route name
               "{controller}/{action}/{id}",                       // URL with parameters
               new { controller = "Home", action = "Index",
                     id = "" }  // Parameter defaults
           );

       }

       protected void Application_Start()
       {
           RegisterRoutes(RouteTable.Routes);
       }
   }

}

অ্যাপ্লিকেশন_সার্ট () ইভেন্ট হ্যান্ডলারটিতে, যখনই অ্যাপ্লিকেশনটি সংকলন করা হয় বা ওয়েব সার্ভারটি পুনরায় চালু করা হয় তখনই তা বরখাস্ত করা হয়, একটি রুট টেবিলটি নিবন্ধিত হয়। ডিফল্ট রুটটির নাম ডিফল্ট রাখা হয়েছে এবং http://www.example.com/ {নিয়ামক} / {ক্রিয়া} / {id of আকারে একটি URL এ সাড়া দেয় } URL এবং between এর মধ্যে ভেরিয়েবলগুলি অনুরোধ URL থেকে আসল মানগুলি বা URL এ কোনও ওভাররাইড উপস্থিত না থাকলে ডিফল্ট মান সহ পপুলেট হয়। এই ডিফল্ট রুটটি ডিফল্ট রাউটিং পরামিতি অনুসারে হোম কন্ট্রোলার এবং সূচক ক্রিয়া পদ্ধতিতে মানচিত্র করবে। এই রাউটিং মানচিত্রের সাথে আমাদের অন্য কোনও ক্রিয়া হবে না।

ডিফল্টরূপে, সমস্ত সম্ভাব্য URL টি এই ডিফল্ট রুটের মাধ্যমে ম্যাপ করা যায়। আমাদের নিজস্ব রুট তৈরি করাও সম্ভব। উদাহরণস্বরূপ, আসুন কর্মচারী নিয়ন্ত্রক, শো ক্রিয়া এবং প্রথম নাম প্যারামিটারে http://www.example.com/Employee/Marten- এর URL টি ম্যাপ করুন । নিম্নলিখিত স্নিপেটটি সবেমাত্র গ্লোবাল.অ্যাক্সেস ফাইলটিতে সন্নিবেশ করা যেতে পারে। কারণ এএসপি.নেট এমভিসি ফ্রেমওয়ার্কটি প্রথম ম্যাচের রুট ব্যবহার করে, এই কোড স্নিপেটটি ডিফল্ট রুটের উপরে সন্নিবেশ করাতে হবে; অন্যথায় রুটটি কখনই ব্যবহার করা হবে না।

routes.MapRoute(

   "EmployeeShow",                    // Route name
   "Employee/{firstname}",            // URL with parameters
    new {                             // Parameter defaults
       controller = "Employee",
       action = "Show", 
       firstname = "" 
   }  

);

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

কর্মচারী নিয়ন্ত্রণকারী শ্রেণি কোনও কর্মচারী বস্তুকে এই দৃষ্টিতে পাস করবে। এই কর্মচারী শ্রেণিটি মডেল ফোল্ডারে যুক্ত করা উচিত (এই ফোল্ডারে ডান ক্লিক করুন এবং তারপরে প্রসঙ্গ মেনু থেকে অ্যাড | ক্লাস নির্বাচন করুন)। কর্মচারী শ্রেণীর কোড এখানে:

namespace MvcApplication1.Models {

   public class Employee
   {
       public string FirstName { get; set; }
       public string LastName { get; set; }
       public string Email { get; set; }
   }

} 

1
ধন্যবাদ, যদিও আমি এটি ডিফল্ট এআআআআআআরএ নির্ধারণের সাথে কীভাবে সম্পর্কিত তা আমি নিশ্চিত নই। : - /
লিয়ামবি

0

ভাল, একটি কাস্টম ভিউ ইঞ্জিন তৈরি করার সময় এটি এর জন্য কাজ করতে পারে, তবুও আপনার বিকল্প থাকতে পারে:

  • আপনাকে ডিফল্টরূপে কী দেখাতে হবে তা সিদ্ধান্ত নিন।
  • কিছু যে নিয়ামক এবং কর্ম (এবং অঞ্চল) আছে, তাই না?
  • অঞ্চলটি নিবন্ধকরণটি খুলুন এবং এর মতো কিছু যুক্ত করুন:
public override void RegisterArea(AreaRegistrationContext context)
{
    //this makes it work for the empty url (just domain) to act as current Area.
    context.MapRoute(
        "Area_empty",
        "",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new string[] { "Area controller namespace" }
    );
        //other routes of the area
}

চিয়ার্স!


একমত। যদিও আমি মনে করি এই রুটের সংজ্ঞাটির জন্য আরও উপযুক্ত জায়গাটি গ্লোবাল.এক্স্যাক্স ফাইলে।
nuhusky2003

এমন ক্ষেত্রে আপনার গ্লোবাল.এক্স্যাক্স সংজ্ঞাগুলি কোনও অঞ্চল নিয়ামক নেমস্পেসের অস্তিত্ব সম্পর্কে জানতে পারে, যা আমার মনে হয় সঠিক নয়। অঞ্চলগুলি একটি অতিরিক্ত ক্রিয়াকলাপ, যার অর্থ আপনি অবশ্যই গ্লোবাল.এক্স্যাক্স সংজ্ঞাগুলিকে স্পর্শ না করে কোনও একটি যুক্ত / সরাতে সক্ষম হবেন। এই প্রশ্নে আমার দৃষ্টিভঙ্গিতে আমি অনুরোধটিকে "হ্যান্ড-ওভার" করার পরিবর্তে একটি [বিশ্বব্যাপী] ওয়েবসাইটের পরিবর্তে অনুরোধটিকে "টেক-ওভার" করতে পছন্দ করি।
টেঙ্গিজ

0

এই প্রশ্নের গৃহীত সমাধান হ'ল কাস্টম ভিউ ইঞ্জিন কীভাবে তৈরি করা যায় তা সংক্ষিপ্ত করে সঠিকভাবে প্রশ্নের উত্তর দেয় না। এখানে সমস্যাটি হ'ল পিনো ভুলভাবে তার ডিফল্ট রুটটি নির্দিষ্ট করে দিচ্ছে । বিশেষত তাঁর "অঞ্চল" সংজ্ঞাটি ভুল। "এরিয়া" ডেটা টোকেন সংগ্রহের মাধ্যমে চেক করা হয় এবং এটি যুক্ত করা উচিত:

var defaultRoute = new Route("",new RouteValueDictionary(){{"controller","Default"},{"action","Index"}},null/*constraints*/,new RouteValueDictionary(){{"area","Admin"}},new MvcRouteHandler());
defaultRoute.DataTokens.Add("Namespaces","MyProject.Web.Admin.Controller"); 
routes.Add(defaultRoute);

ডিফল্ট অবজেক্টে নির্দিষ্ট "অঞ্চল" উপেক্ষা করা হবে । উপরের কোডটি একটি ডিফল্ট রুট তৈরি করে, যা আপনার সাইটের মূলের অনুরোধগুলি ধরে এবং তারপরে অ্যাডমিন অঞ্চলে ডিফল্ট নিয়ন্ত্রক, সূচক ক্রিয়াকলাপটিকে ডেকে আনে। দয়া করে নোটস্পেনগুলিতে "নেমস্পেসগুলি" কী যুক্ত করা আছে তাও নোট করুন, এটি কেবল তখনই প্রয়োজন যখন আপনার একই নামের একাধিক নিয়ামক রয়েছে have এই সমাধানটি এমভিসি 2 এবং এমভিসি 3। নেট 3.5 / 4.0 এর সাথে যাচাই করা হয়েছে


-1

উম্মম, আমি জানি না কেন এই সমস্ত প্রোগ্রামিং, আমি মনে করি এই ডিফল্ট রুটটি নির্দিষ্ট করে মূল সমস্যাটি সহজেই সমাধান করা হয়েছে ...

routes.MapRoute("Default", "{*id}", 
                 new { controller = "Home"
                     , action = "Index"
                     , id = UrlParameter.Optional 
                     }
              );
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.