سؤال

كنت أحاول أن أكون بارعًا وأن أستخدم VirtualPathProvider للعثور على وجهات نظر محلية. يستغرق مسار العرض المطلوب ويعدله عند التحقق بعد الملف. يرجع ملف افتراضي موضعي إذا تم العثور عليه:

public pseudoclass MyFileProvider : VirtualPathProvider
{

    bool FileExists(string requestedPath)
    {
        if (IsLocalizedView(requestedPath))
          return true;
       return base.FileExists(requestedPath);
    }

    bool IsLocalizedView(string requestedPath)
    {
        var uri = requestedUri.AddLocaleByMagic("sv");
        if (FileExistsInternal(uri))
          return true;
    }

    //some more stuff to return the actual file
}

المشكلة هي أنني أحصل على الاستثناء التالي:

أعاد VirtualPathProvider كائن VirtualFile مع تعيين VirtualPath إلى "/views/shared/_layout.sv.cshtml" بدلاً من المتوقع '/views/shared/_layout.cshtml'.

بالتأكيد ، يمكنني مزيفة مسار الملف ، لكن ذلك من شأنه أن ينتج مشاكل في التخزين المؤقت وتوطين مختلفة. حق؟

هل حصل أي شخص على طريقة أفضل لتكون قادرًا على إنشاء وجهات نظر محلية؟ لا أريد استخدام نفس العرض ولكن مع سلاسل الموارد بدلاً من ذلك. مثل هذه الآراء مروعة لدرجة أنها تجعلني أبكي لأنها يصعب قراءتها.

إذا كنت لا تزال لم تفهم ما أبحث عنه:

/views/user/details.sv.cshtml

Hejsan @Model.FirstName

Detta är en lite rolig text på svenska.

/views/user/details.en.cshtml

Hello @Model.FirstName

This is a test on english.

مراقب

public ActionResult Details()
{
  return View(new User()); //should automagically use a swedish or english view
}

أريد أن أكون قادرًا على تبديل المشاهدات (إلى واحدة محلية باستخدام CurrentCulture) دون الحاجة إلى القيام بأي شيء يدويًا في كل طلب.

هل كانت مفيدة؟

المحلول

يمكنك كتابة ViewEngine مخصص يعيد المشاهدات اعتمادًا على الثقافة الحالية. مثال لطيف على ذلك يمكن العثور عليه في منشور مدونة سكوت هانسلمان, ، والتي تقوم بإرجاع طرق عرض الأجهزة المحمولة إذا تم تقديم الطلب بواسطة جهاز محمول

نصائح أخرى

ها هو تنفيذي. يمكن أن يكون أكثر عاما ، لكنه يفي بجميع متطلباتي.

أنا أبحث عن العرض الأكثر تخصصًا أولاً وأحاول دون مواصفات اللغة.

عرض عملية البحث:

  1. التفاصيل. sv-fi.cshtml
  2. التفاصيل. sv.cshtml
  3. التفاصيل. en.cshtml
  4. التفاصيل

    public class LocalizedRazorViewEngine : RazorViewEngine
    {
        public LocalizedRazorViewEngine()
        {
            DefaultLanguageCode = "en";
        }
        public string DefaultLanguageCode { get; set; }

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            var controllerName = (string)controllerContext.RouteData.Values["controller"];
            var language = GetLanguage(controllerName, viewName);
            if (language != "") language = "." + language;

            var masterPath = string.Format("~/Views/Shared/_Layout{0}.cshtml", language);
            var uri = string.Format("~/Views/{0}/{1}{2}.cshtml", controllerName, viewName, language);
            if (VirtualPathProvider.FileExists(uri))
                return new ViewEngineResult(CreateView(controllerContext, uri, masterPath), this);


            return base.FindView(controllerContext, viewName, masterName, useCache);
        }

        private string GetLanguage(string controllerName, string actionName)
        {
            string format = "~/Views/{0}/{1}.{2}.cshtml";
            if (VirtualPathProvider.FileExists(string.Format(format, controllerName, actionName, Thread.CurrentThread.CurrentCulture.Name)))
                return Thread.CurrentThread.CurrentCulture.Name;
            if (VirtualPathProvider.FileExists(string.Format(format, controllerName, actionName, Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName)))
                return Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;
            if (VirtualPathProvider.FileExists(string.Format(format, controllerName, actionName, DefaultLanguageCode)))
                return DefaultLanguageCode;
            return string.Empty;
        }



    }

لاحظ أنه يتم تعطيل التخزين المؤقت باستخدام هذا النهج وقد تحتاج إلى إنشاء ذاكرة التخزين المؤقت الخاصة بك (للحصول على اللغة الصحيحة)

فيما يلي أبسط مثال (على ما أظن) على التبديل بين طرق العرض باستخدام الاتفاقية التالية:

  1. myview.cshtml - افتراضي واحد
  2. myview.pl.cshtml - لغة البولندية

.. وهلم جرا

    public class LocalizedRazor : RazorViewEngine
    {
    public LocalizedRazor()
        : base()
    {
    }

    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        var controllerName = (string)controllerContext.RouteData.Values["controller"];
        var format = "~/Views/{0}/{1}.{2}.cshtml";
        var lang = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;
        if (VirtualPathProvider.FileExists(string.Format(format, controllerName, viewName, lang)))
            return base.FindView(controllerContext, viewName + "." + lang, masterName, useCache);

        return base.FindView(controllerContext, viewName, masterName, useCache);
    }
    }

وفي Global.asax:

   protected void Application_Start()
    {
        ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new LocalizedRazor());
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top