سؤال

أريد أن أتجنب وجود الكثير من if Request.IsAjaxRequest() في وحدات التحكم الخاصة بي. كنت أفكر في أنه إذا كان بإمكاني تكوين هذا المنطق إلى ActionFilter، فسيكون من السهل تبني اتفاقية في طلبي لتوفير إجراء ثان لأي طلب مايو استخدم AJAX، مع توفير السقوط إذا تم تعطيل JavaScript.

public ActionResult Details(int id)
{
  // called normally, show full page
}

public ActionResult Details_Ajax(int id)
{
  // called through ajax, return a partial view
}

اعتقدت في البداية أنني أستطيع أن أفعل شيئا مثل هذا:

public class AjaxRenameAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RouteData.Values["action"] = filterContext.RouteData.Values["action"] + "_Ajax";

    }

ولكن هذا لن يعمل لأن الإجراء الذي يجب استدعاءه يقرر ثم يتم معالجة المرشحات الموجودة عليه.

لا أريد حقا إرجاع إعادة التوجيه في كل مرة، شخص ما يدعو إلى إجراء، يبدو بلا رائحة بعض الشيء لمضاعفة مقدار طلبات HTTP.

هل هناك طريقة مختلفة للتوجيه من خلال الطلب إلى إجراء مختلف؟ أم ما أفعله بشكل غير قابل للحل ويجب أن أبحث عن طريقة أفضل للقيام بالأشياء؟

هتافات

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

المحلول

AcceptAjaxAttribute ربما هو ما هو مطلوب هنا؛ ومع ذلك، أود أن أقترح طريقة مختلفة للتفكير في هذه المشكلة.

ليس كل طلبات AJAX متساوية. يمكن أن يحاول طلب AJAX لإنجاز أيا من الأشياء التالية:

  • ملزمة بيانات JSON إلى شبكة غنية (مثل JqGrid)؛
  • تحليل / تحويل بيانات XML، مثل تغذية RSS؛
  • تحميل HTML الجزئي في منطقة الصفحة؛
  • تحميل بشكل غير متزامن نصي (google.load تستطيع فعلها)؛
  • التعامل مع رسالة واحدة في اتجاه واحد من العميل؛
  • وربما عدد قليل من نسيت.

عند "تحديد" إجراء بديل محدد "بناء فقط على IsAjaxRequest الطريقة، أنت تربط شيئا عامة للغاية - طلب غير متزامن - وظيفة محددة على الخادم. في نهاية المطاف، فإن التصميم الخاص بك أكثر هشاشة وأيضا جعل وحدة تحكم أكثر صعوبة اختبار الوحدة (على الرغم من وجود طرق للقيام بذلك، يمكنك أن تسخر من السياق).

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

الوصول إلى النقطة هنا، الهدف المذكور في السؤال هو جيد؛ يجب بالتااكيد لديهم طرق مختلفة لما وصفه بشكل صحيح بأنها إجراءات مختلفة:

public ActionResult Details(int id)
{
    return View("Details", GetDetails(id));
}

public ActionResult JsonDetails(int id)
{
    return Json(GetDetails(id));
}

public ActionResult PartialDetails(int id)
{
    return PartialView("DetailTable", GetDetails(id));
}

وما إلى ذلك وهلم جرا. ومع ذلك، فإن استخدام محدد عمل AJAX لاختيار بين هذه الأساليب يتبعم ممارسة "تدهور رشيقة", ، الذي تم استبداله بشكل أساسي (على الأقل من IMO) تحسين تدريجي.

هذا هو السبب، على الرغم من أنني أحب ASP.NET MVC، إلا أنني في الغالب AjaxHelper, لأنني لا أجد أنه يعبر عن هذا المفهوم جيدا؛ يحاول إخفاء الكثير منك. بدلا من وجود مفهوم "نموذج AJAX" أو "إجراء AJAX"، دعنا نفعل بعيدا عن التمييز والتمسك ب HTML مستقيم، ثم ضخ وظيفة AJAX بشكل منفصل بمجرد أن نتأكد من أن العميل يمكنه التعامل معه.

إليك مثال في JQuery - على الرغم من أنه يمكنك القيام بذلك في MS AJAX أيضا:

$(function() {
    $("#showdetails").click(function() {
        $("#details").load("PartialDetails", { id: <%= Record.ID %> });
        return false;
    }
});

هذا هو كل ما يلزم لحقن أجاكس في صفحة MVC. ابدأ بارتفاع HTML القديم عادي وتجاوزه باستخدام مكالمة AJAX التي تذهب إلى إجراء تحكم مختلف.

الآن، إذا كنت في مكان آخر على موقعك، فإنك تقرر أنك ترغب في استخدام شبكة بدلا من ذلك، ولكن لا ترغب في كسر الصفحات باستخدام التقديم الجزئي، يمكنك كتابة شيء مثل هذا (دعنا نقول أن لديك صفحة ماجستير واحدة مع قائمة "الطلبات" على الجانب الأيسر وجدول التفاصيل على اليمين):

$(".detaillink").click(function() {
    $('#detailGrid').setGridParam({
        url: $(this).attr("href").replace(/\/order\/details/i,
            "/order/jsondetails")
    }); 
    $("#detailGrid").trigger("reloadGrid");  
});

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

هذا ليس النهج الوحيد. من الواضح، فصول مثل AcceptAjaxAttribute موجودة لأنها توقعت بعض المطورين استخدام طريقة الكشف عن الطلب. ولكن بعد أن جربت قليلا مع حد سواء، أجد بهذه الطريقة كثير أسهل في السبب، وبالتالي أسهل في التصميم / الرمز بشكل صحيح.

نصائح أخرى

ماذا عن acceptajaxattribute في mvcfutures؟

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