كيف يمكنني تغيير طرق عرض ASP.NET MVC بناءً على نوع الجهاز؟

StackOverflow https://stackoverflow.com/questions/1387354

سؤال

أنا أعمل في طريقي من خلال بعض قراءة ASP.NET MVC ولدي تطبيق ويب في العمل سأقوم بالترحيل من WebForms إلى MVC. أحد طلبات الميزات التي أتوقع الحصول عليها في هذه العملية هو إعادة عرض مبسط إذا كان المستخدم قادمًا من جهاز محمول.

لا أستطيع أن أرى مكان أفضل مكان لتنفيذ هذا النوع من المنطق. أنا متأكد من أن هناك طريقة أفضل من إضافة if/else for browser.ismobileDevice في كل إجراء يعيد وجهة نظر. ما نوع الخيارات التي يجب علي القيام بها؟

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

المحلول

تحديث: هذا الحل له علة خفية. سوف يستدعي إطار عمل MVC FindView/FindPartialView مرتين: مرة واحدة مع useCache=true, ، وإذا لم يرجع ذلك ، مرة واحدة مع useCache=false. نظرًا لوجود ذاكرة التخزين المؤقت واحدة فقط لجميع أنواع المشاهدات ، فقد ينتهي مستخدمو الأجهزة المحمولة بمشاهدة طرق عرض سطح المكتب إذا كان متصفح سطح المكتب أول من يصل.

للراغبين في استخدام محركات العرض المخصصة لحل هذه المشكلة ، قام Scott Hanselman بتحديث حله هنا:

http://www.hanselman.com/blog/abetteraspnetmvcmobileDeviceCapabilityViewEngine.aspx

(أعتذر عن الإجابة ، أنا فقط لا أريد أن يمر أي شخص آخر من خلال هذا!)

حرره روفاماتيك (2010-11-17)


أول شيء تريد القيام به هو تقديم ملف متصفح الجهاز المحمول لمشروعك. باستخدام هذا الملف ، يمكنك استهداف الجهاز الذي تريد دعمه دون الحاجة إلى معرفة تفاصيل ما ترسله تلك الأجهزة في رؤوسها. لقد قام هذا الملف بالفعل بالعمل نيابة عنك. يمكنك بعد ذلك استخدام خاصية request.browser لتخصيص العرض الذي تريد إرجاعه.

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

  • مسكن
    • التليفون المحمول
      • ايفون
        • index.aspx
      • بلاك بيري
        • index.aspx
    • index.aspx

يجب أن أختلف مع mehrdad حول استخدام محرك عرض مخصص. يخدم محرك View أكثر من غرض واحد وأحد هذه الأغراض هو العثور على وجهات نظر لوحدة التحكم. يمكنك القيام بذلك عن طريق تجاوز طريقة FindView. في هذه الطريقة ، يمكنك إجراء الشيكات الخاصة بك في مكان العثور على العرض. بعد أن تعرف الجهاز الذي يستخدم موقعك ، يمكنك استخدام الإستراتيجية التي توصلت إليها لتنظيم وجهات نظرك لإرجاع العرض لهذا الجهاز.

public class CustomViewEngine : WebFormViewEngine
{
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        // Logic for finding views in your project using your strategy for organizing your views under the Views folder.
        ViewEngineResult result = null;
        var request = controllerContext.HttpContext.Request;

        // iPhone Detection
        if (request.UserAgent.IndexOf("iPhone",
   StringComparison.OrdinalIgnoreCase) > 0)
        {
            result = base.FindView(controllerContext, "Mobile/iPhone/" + viewName, masterName, useCache);
        }

        // Blackberry Detection
        if (request.UserAgent.IndexOf("BlackBerry",
   StringComparison.OrdinalIgnoreCase) > 0)
        {
            result = base.FindView(controllerContext, "Mobile/BlackBerry/" + viewName, masterName, useCache);
        }

        // Default Mobile
        if (request.Browser.IsMobileDevice)
        {
            result = base.FindView(controllerContext, "Mobile/" + viewName, masterName, useCache);
        }

        // Desktop
        if (result == null || result.View == null)
        {
            result = base.FindView(controllerContext, viewName, masterName, useCache);
        }

        return result;
    }
}

يتيح لك الرمز أعلاه تعيين العرض بناءً على استراتيجيتك. السقوط هو عرض سطح المكتب ، إذا لم يتم العثور على عرض للجهاز أو إذا لم يكن هناك عرض افتراضي للهاتف المحمول.

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

نصائح أخرى

في نمط السيطرة على عرض الطراز ، فإن وحدة التحكم هي التي تختار العرض ، لذلك ، ليس من السيئ إضافة ملف if بيان وإعادة طريقة عرض مناسبة. يمكنك تغليف if بيان في طريقة واتصل به:

return AdaptedView(Browser.IsMobileDevice, "MyView.aspx", model);

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

أعتقد أن المكان المناسب لتوصيل هذه الوظيفة هو عرض مخصص. لكن يجب أن تكون على دراية بكيفية IViewEngine.FindView الطريقة تسمى من قبل ViewEngineCollection (ابحث عن المزيد حول هذا هنا).

محدث المحلول اقترح Scott Hanselman لا يعمل بشكل صحيح. يمكنك العثور على تنفيذ نموذجي لهذا النهج هنا. تحقق من ملف ReadMe الذي يصف كيف يمكنك تكرار السلوك غير الصحيح.

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

إنه لأمر معقد للغاية أن تضع كل التعليمات البرمجية هنا ولكن يمكنك العثور على النهج المقترح الذي تم تنفيذه في ملعب المصدر المفتوح الخاص بي هنا. الشيك MobileViewEngine فئة واختبارات الوحدة.

بعض ميزات MobileViewEngine:

  • يعمل بشكل صحيح مع عرض التخزين المؤقت ويستخدم ذاكرة التخزين المؤقت للمحرك الأصلي.
  • يدعم كلاهما: أسماء عرض اللقطة ومسارات العرض النسبية (~/view/index) المستخدمة بواسطة قالب MVCContrib T4.
  • يحل عرض "الفهرس" على النحو التالي:
    • Mobile/Platform/Index - في حالة وجود عرض ويتم تجنيد منصة الأجهزة المحمولة (iPhone و Android وما إلى ذلك) في القائمة المدعومة.
    • Mobile/Index - عرض لجميع الأجهزة المحمولة الأخرى. إذا لم يكن العرض موجودًا ، فيمكنك اختياريًا إلى إصدار عرض سطح المكتب.
    • Index - لإصدار عرض سطح المكتب.
  • يمكنك تخصيص التسلسل الهرمي عرض الجوال (على سبيل المثال Mobile/ Platform/Manufacturer) أو تخصيص دقة مسار عرض الجوال عن طريق إضافة/تغيير قواعد الجهاز (انظر MobileDeviceRule و PlatformSpecificRule).

نأمل ، هذا سوف يساعد

هذا إصدار يعمل بالفعل ، سواء مع T4MVC أو في وضع الإصدار (حيث يتم تمكين التخزين المؤقت للمسافات). إنه يعتني بعناوين UserControls وعنوان URL المطلقة/النسبية أيضًا. يتطلب ملف متصفح الجهاز المحمول.

public class MobileCapableWebFormViewEngine : WebFormViewEngine
{

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        if (viewPath.EndsWith(".ascx"))
            masterPath = "";
        return base.CreateView(controllerContext, viewPath, masterPath);
    }
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        useCache = false;
        ViewEngineResult result = null;
        var request = controllerContext.HttpContext.Request;

        if (request.Browser.IsMobileDevice || request["mobile"] != null || request.Url.Host.StartsWith("m."))
        {
            var mobileViewName = GetMobileViewName(viewName);

            result = base.FindView(controllerContext, mobileViewName, masterName, useCache);
            if (result == null || result.View == null)
            {
                result = base.FindView(controllerContext, viewName, "Mobile", useCache);
            }
        }

        if (result == null || result.View == null)
        {
            result = base.FindView(controllerContext, viewName, masterName, useCache);
        }

        return result;
    }

    private static string GetMobileViewName(string partialViewName)
    {
        var i = partialViewName.LastIndexOf('/');
        return i > 0
                   ? partialViewName.Remove(i) + "/Mobile" + partialViewName.Substring(i)
                   : "Mobile/" + partialViewName;
    }
}

يجب أن يكون منطقك الأساسي هو نفسه في وحدات التحكم ، وسيتم تغيير العرض الذي تحتاجه فقط ، لذا فإن وحدة التحكم هي المكان الذي تحتاج فيه إلى عبارة if/else لخدمة العرض الصحيح لكل إجراء تحكم كما ذكرت.

سيكون البديل هو لف منطق تحكم في DLL منفصل ثم يكون لديك وحدات تحكم / مسارات مختلفة لإصدار الهاتف المحمول. إذا استقبلت وحدة تحكم منتظمة طلبًا من جهاز محمول ، فيمكنك إعادة توجيهه إلى منطقة الهاتف المحمول التي تحتوي على جميع وحدات التحكم في الهاتف المحمول التي تستخدم منطق وحدة التحكم المشتركة. سيسمح لك هذا الحل أيضًا بالقيام بـ "Tweeks" محددة لوحدات التحكم في الأجهزة المحمولة ولا يؤثر على وحدات التحكم العادية الخاصة بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top