আমি কি এএসপি.নেট এমভিসিতে "দৃশ্যের সন্ধান করতে" কোনও কাস্টম অবস্থান নির্দিষ্ট করতে পারি?


105

আমার এমভিসি প্রকল্পের জন্য আমার নীচের লেআউটটি রয়েছে:

  • / কন্ট্রোলার
    • / ডেমো
    • / ডেমো / DemoArea1Controller
    • / ডেমো / DemoArea2Controller
    • ইত্যাদি ...
  • / দেখেছে
    • / ডেমো
    • /Demo/DemoArea1/Index.aspx
    • /Demo/DemoArea2/Index.aspx

যাইহোক, যখন আমার কাছে এটি রয়েছে DemoArea1Controller:

public class DemoArea1Controller : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

স্বাভাবিক অনুসন্ধানের জায়গাগুলি সহ আমি "ভিউ 'সূচক' বা এর মাস্টারটি পাওয়া যায়নি" ত্রুটি পেয়েছি।

"ডেমো" নেমস্পেস অনুসন্ধানের "ডেমো" ভিউ সাবফোল্ডারটিতে আমি কীভাবে নিয়ন্ত্রণকারীগুলি নির্দিষ্ট করতে পারি?


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

উত্তর:


121

আপনি সন্ধান করতে চান এমন সমস্ত অবস্থান নির্দিষ্ট করতে আপনি সহজেই ওয়েবফর্মভিউইঙ্গাইন প্রসারিত করতে পারেন:

public class CustomViewEngine : WebFormViewEngine
{
    public CustomViewEngine()
    {
        var viewLocations =  new[] {  
            "~/Views/{1}/{0}.aspx",  
            "~/Views/{1}/{0}.ascx",  
            "~/Views/Shared/{0}.aspx",  
            "~/Views/Shared/{0}.ascx",  
            "~/AnotherPath/Views/{0}.ascx"
            // etc
        };

        this.PartialViewLocationFormats = viewLocations;
        this.ViewLocationFormats = viewLocations;
    }
}

আপনার Global.asax.cs এ অ্যাপ্লিকেশন_সার্ট পদ্ধতিটি সংশোধন করে ভিউ ইঞ্জিনটি নিবন্ধভুক্ত করার বিষয়টি নিশ্চিত করেছেন

protected void Application_Start()
{
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new CustomViewEngine());
}

নেস্টেড মাস্টার পৃষ্ঠা থেকে আপনি কীভাবে মাস্টার পৃষ্ঠার পথ অ্যাক্সেস করতে পারেন? কাস্টমভিউজিনগাইনের পথগুলির মধ্যে সন্ধানের জন্য নেস্টেড মাস্টার পৃষ্ঠার বিন্যাসটি সেট করার ক্ষেত্রে
ড্রহচির

6
যদি আমরা ইতিমধ্যে নিবন্ধিত ইঞ্জিনগুলি সাফ না করে কেবল নতুন একটি যুক্ত করি এবং ভিউ লোকেশনে কেবল নতুন একটি থাকে তবে এটি কি ভাল নয়?
প্রসন্ন

3
ViewEngines.Engines.C Clear () ছাড়াই কার্যকরকরণ; সব কাজ ঠিক আছে। আপনি যদি * .cshtml ব্যবহার করতে চান তবে অবশ্যই রেজারভিউজিনি
ক্রিগহেক

নিয়ন্ত্রকদের নতুন ভিউ লোকেশনগুলিতে বিকল্প যুক্ত করতে "ভিউ যোগ করুন" এবং "দেখার জন্য যেতে" বিকল্পগুলি কীভাবে যুক্ত করতে পারি? আমি ভিজ্যুয়াল স্টুডিও 2012 ব্যবহার করছি
নেভিল নাজিরেন

@ প্রসন্ন দ্বারা উল্লিখিত হিসাবে, নতুন অবস্থান যুক্ত করার জন্য বিদ্যমান ইঞ্জিনগুলি সাফ করার দরকার নেই, আরও বিশদের জন্য এই উত্তরটি দেখুন।
হুমান বাহরাইন

44

এখন এমভিসি 6 এ আপনি IViewLocationExpanderভিউ ইঞ্জিনগুলির সাথে গোলমাল না করে ইন্টারফেসটি প্রয়োগ করতে পারেন :

public class MyViewLocationExpander : IViewLocationExpander
{
    public void PopulateValues(ViewLocationExpanderContext context) {}

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        return new[]
        {
            "/AnotherPath/Views/{1}/{0}.cshtml",
            "/AnotherPath/Views/Shared/{0}.cshtml"
        }; // add `.Union(viewLocations)` to add default locations
    }
}

যেখানে {0}লক্ষ্য নাম, হয় {1}নিয়ামক নাম এবং - {2}- এলাকা নাম।

আপনি নিজের অবস্থানের তালিকাটি ফিরিয়ে আনতে পারেন, এটি ডিফল্ট viewLocations( .Union(viewLocations)) এর সাথে একত্রীকরণ করতে পারেন বা কেবল তাদের ( viewLocations.Select(path => "/AnotherPath" + path)) পরিবর্তন করতে পারেন ।

এমভিসিতে আপনার কাস্টম দর্শন অবস্থানের সম্প্রসারণকারীকে রেজিস্টার করতে ফাইলের ConfigureServicesপদ্ধতিতে পরবর্তী লাইন যুক্ত Startup.csকরুন:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.ViewLocationExpanders.Add(new MyViewLocationExpander());
    });
}

3
আমি আশা করি আমি এটি 10 ​​টি ভোটে ভোট দিতে পারতাম। Asp.net 5 / MVC 6. এ যা দরকার তা ঠিক Beautiful আমার ক্ষেত্রে (এবং অন্যদের) খুব কার্যকর যখন আপনি কোনও বৃহত্তর সাইট বা লজিকাল গ্রুপিংয়ের জন্য সুপার অঞ্চলগুলিতে দলবদ্ধ করতে চান।
ড্রুইড

স্টার্টআপ.সি অংশটি হ'ল: পরিষেবাদি.কমফিগার <রজারভিউ ইঞ্জিনিওপশনস> এটি এই পদ্ধতিতে চলেছে: সর্বজনীন শূন্য কনফিগার সার্ভিসেস (আইএসসিওর কালেকশন পরিষেবা)
অরেঞ্জকিং 89

42

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

public class ExtendedRazorViewEngine : RazorViewEngine
{
    public void AddViewLocationFormat(string paths)
    {
        List<string> existingPaths = new List<string>(ViewLocationFormats);
        existingPaths.Add(paths);

        ViewLocationFormats = existingPaths.ToArray();
    }

    public void AddPartialViewLocationFormat(string paths)
    {
        List<string> existingPaths = new List<string>(PartialViewLocationFormats);
        existingPaths.Add(paths);

        PartialViewLocationFormats = existingPaths.ToArray();
    }
}

এবং আপনার Global.asax.cs

protected void Application_Start()
{
    ViewEngines.Engines.Clear();

    ExtendedRazorViewEngine engine = new ExtendedRazorViewEngine();
    engine.AddViewLocationFormat("~/MyThemes/{1}/{0}.cshtml");
    engine.AddViewLocationFormat("~/MyThemes/{1}/{0}.vbhtml");

    // Add a shared location too, as the lines above are controller specific
    engine.AddPartialViewLocationFormat("~/MyThemes/{0}.cshtml");
    engine.AddPartialViewLocationFormat("~/MyThemes/{0}.vbhtml");

    ViewEngines.Engines.Add(engine);

    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
}

একটি বিষয় লক্ষণীয়: আপনার কাস্টম অবস্থানের রুটটিতে ভিউস্টার্ট। সিএসটিএমএল ফাইলের প্রয়োজন হবে।


23

আপনি যদি কেবল নতুন পথ যোগ করতে চান তবে আপনি ডিফল্ট ভিউ ইঞ্জিনগুলিতে যুক্ত করতে পারেন এবং কোডের কয়েকটি লাইন ছাড়িয়ে দিতে পারেন:

ViewEngines.Engines.Clear();
var razorEngine = new RazorViewEngine();
razorEngine.MasterLocationFormats = razorEngine.MasterLocationFormats
      .Concat(new[] { 
          "~/custom/path/{0}.cshtml" 
      }).ToArray();

razorEngine.PartialViewLocationFormats = razorEngine.PartialViewLocationFormats
      .Concat(new[] { 
          "~/custom/path/{1}/{0}.cshtml",   // {1} = controller name
          "~/custom/path/Shared/{0}.cshtml" 
      }).ToArray();

ViewEngines.Engines.Add(razorEngine);

একই প্রযোজ্য WebFormEngine


2
দর্শনগুলির জন্য: রেজারইঙ্গাইন.ভিউলোকেশনফর্ম্যাট ব্যবহার করুন।
আলডেন্তেভ

13

রেজারভিউইনগাইন সাবক্লাসিংয়ের পরিবর্তে বা একে একে পুরোপুরি প্রতিস্থাপনের পরিবর্তে আপনি কেবল বিদ্যমান রেজারভিউইঙ্গিনের আংশিকভিউ লোকেশন ফর্ম্যাট বৈশিষ্ট্য পরিবর্তন করতে পারেন। এই কোডটি অ্যাপ্লিকেশন_স্টার্টে যায়:

System.Web.Mvc.RazorViewEngine rve = (RazorViewEngine)ViewEngines.Engines
  .Where(e=>e.GetType()==typeof(RazorViewEngine))
  .FirstOrDefault();

string[] additionalPartialViewLocations = new[] { 
  "~/Views/[YourCustomPathHere]"
};

if(rve!=null)
{
  rve.PartialViewLocationFormats = rve.PartialViewLocationFormats
    .Union( additionalPartialViewLocations )
    .ToArray();
}

2
এটি রেজার ইঞ্জিনের ধরণটি 'রেজারভিউজিনি'র পরিবর্তে' ফিক্সডরাজারভিউজিনি 'ছিল exception এছাড়াও ইঞ্জিনটি পাওয়া না গেলে আমি ব্যতিক্রম ছুঁড়ে ফেলি কারণ এটি আমার অ্যাপ্লিকেশনটিকে সফলভাবে শুরু করতে বাধা দেয়।
রব

3

সর্বশেষে আমি চেক করেছি, এর জন্য আপনাকে নিজের ভিউজাইন তৈরি করতে হবে। যদিও তারা আরসি 1 এ এটিকে আরও সহজ করেছেন কিনা আমি জানি না।

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

সম্পাদনা করুন:

ফিরে গিয়ে কোডটি খুঁজে পেয়েছি। এখানে সাধারণ ধারণা।

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName)
{
    string ns = controllerContext.Controller.GetType().Namespace;
    string controller = controllerContext.Controller.GetType().Name.Replace("Controller", "");

    //try to find the view
    string rel = "~/Views/" +
        (
            ns == baseControllerNamespace ? "" :
            ns.Substring(baseControllerNamespace.Length + 1).Replace(".", "/") + "/"
        )
        + controller;
    string[] pathsToSearch = new string[]{
        rel+"/"+viewName+".aspx",
        rel+"/"+viewName+".ascx"
    };

    string viewPath = null;
    foreach (var path in pathsToSearch)
    {
        if (this.VirtualPathProvider.FileExists(path))
        {
            viewPath = path;
            break;
        }
    }

    if (viewPath != null)
    {
        string masterPath = null;

        //try find the master
        if (!string.IsNullOrEmpty(masterName))
        {

            string[] masterPathsToSearch = new string[]{
                rel+"/"+masterName+".master",
                "~/Views/"+ controller +"/"+ masterName+".master",
                "~/Views/Shared/"+ masterName+".master"
            };


            foreach (var path in masterPathsToSearch)
            {
                if (this.VirtualPathProvider.FileExists(path))
                {
                    masterPath = path;
                    break;
                }
            }
        }

        if (string.IsNullOrEmpty(masterName) || masterPath != null)
        {
            return new ViewEngineResult(
                this.CreateView(controllerContext, viewPath, masterPath), this);
        }
    }

    //try default implementation
    var result = base.FindView(controllerContext, viewName, masterName);
    if (result.View == null)
    {
        //add the location searched
        return new ViewEngineResult(pathsToSearch);
    }
    return result;
}

1
এটি আসলে অনেক সহজ। সাবক্লাস ওয়েবফোর্সমভিউজাইন এবং তারপরে এটি ইতিমধ্যে আপনার নির্মাতাকে অনুসন্ধান করে এমন পাথের অ্যারেটিতে যুক্ত করুন।
ক্রেগ স্টান্টজ

জানা ভাল. সর্বশেষে যখন আমার সংগ্রহটি সংশোধন করার দরকার হয়েছিল, তখন সেভাবে সম্ভব ছিল না।
জোয়েল

আপনার বেস কন্ট্রোলার নেমস্পেসে (যেমন "প্রজেক্ট.কন্ট্রোলারস") আপনার "বেসকন্ট্রোলার নেমস্পেস" ভেরিয়েবল সেট করতে হবে তা উল্লেখযোগ্য, তবে অন্যথায় পোস্ট করার 7 বছর পরে আমার যা প্রয়োজন ঠিক তা-ই করেছেন।
প্রোটোটাইপ 14

3

এরকম কিছু চেষ্টা করুন:

private static void RegisterViewEngines(ICollection<IViewEngine> engines)
{
    engines.Add(new WebFormViewEngine
    {
        MasterLocationFormats = new[] {"~/App/Views/Admin/{0}.master"},
        PartialViewLocationFormats = new[] {"~/App/Views/Admin//{1}/{0}.ascx"},
        ViewLocationFormats = new[] {"~/App/Views/Admin//{1}/{0}.aspx"}
    });
}

protected void Application_Start()
{
    RegisterViewEngines(ViewEngines.Engines);
}

3

দ্রষ্টব্য: এএসপি.নেট এমভিসি 2 এর জন্য তাদের অতিরিক্ত অবস্থানের পথ রয়েছে যা আপনাকে 'অঞ্চলগুলিতে' দেখার জন্য নির্ধারণ করতে হবে।

 AreaViewLocationFormats
 AreaPartialViewLocationFormats
 AreaMasterLocationFormats

ফিলের ব্লগে কোনও অঞ্চলের জন্য একটি ভিউ ইঞ্জিন তৈরি করা বর্ণনা করা হয়েছে

দ্রষ্টব্য: এটি পূর্বরূপ রিলিজ 1 এর জন্য তাই পরিবর্তনের সাপেক্ষে।


1

এখানে বেশিরভাগ উত্তর, কল করে বিদ্যমান অবস্থানগুলি সাফ করুনViewEngines.Engines.Clear() এবং তারপরে এগুলি আবার যুক্ত করুন ... এটি করার দরকার নেই।

নীচে দেখানো হয়েছে এমনভাবে আমরা কেবল বিদ্যমান অবস্থানে নতুন অবস্থানগুলি যুক্ত করতে পারি:

// note that the base class is RazorViewEngine, NOT WebFormViewEngine
public class ExpandedViewEngine : RazorViewEngine
{
    public ExpandedViewEngine()
    {
        var customViewSubfolders = new[] 
        {
            // {1} is conroller name, {0} is action name
            "~/Areas/AreaName/Views/Subfolder1/{1}/{0}.cshtml",
            "~/Areas/AreaName/Views/Subfolder1/Shared/{0}.cshtml"
        };

        var customPartialViewSubfolders = new[] 
        {
            "~/Areas/MyAreaName/Views/Subfolder1/{1}/Partials/{0}.cshtml",
            "~/Areas/MyAreaName/Views/Subfolder1/Shared/Partials/{0}.cshtml"
        };

        ViewLocationFormats = ViewLocationFormats.Union(customViewSubfolders).ToArray();
        PartialViewLocationFormats = PartialViewLocationFormats.Union(customPartialViewSubfolders).ToArray();

        // use the following if you want to extend the master locations
        // MasterLocationFormats = MasterLocationFormats.Union(new[] { "new master location" }).ToArray();   
    }
}

RazorViewEngineগ্লোবাল.এক্সএক্সে উপরের ব্যবহারের জন্য আপনি এখন আপনার প্রকল্পটি কনফিগার করতে পারেন :

protected void Application_Start()
{
    ViewEngines.Engines.Add(new ExpandedViewEngine());
    // more configurations
}

আরও তথ্যের জন্য এই টিউটোরাল দেখুন ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.