سؤال

أنا أفسد فئة التطبيق الخاصة بي التي تستخدم نمط singleton. أريد تخزين مثيلي في HTTPCONTEXT.ITEMS، لأنه يمكن الوصول إليه في جميع أنحاء الطلب. لقد كنت أقرأ عن استخدام HttpContext مع ASP.NET MVC وأحد الآلام الرئيسية هو أنه يقدم تعقيد الاختبار. لقد حاولت إجراء البحث في اختبار استقلال httpcontext.items، ولكن كل ما يمكنني العثور عليه هو الاشياء في الجلسة. واحدة من الأشياء الوحيدة التي عثر عليها هي خارج فصل العينة في كتاب ASP.NET 3.5 المهنية في WROX (رابط PDF هنا). في الصفحة 15 تقول هذا:

شيء لا يمكنك استخدامه: httpccontext.items
أعلاه في هذا القسم، جئنا نظفنا وأخبرك أننا كذبت عليك: HttpContext غير مشترك بين أشكال الويب ASP.NET MVC و ASP.NET Web. نتيجة لذلك، لا يمكنك استخدام مجموعة HTTPCONTEXT.ITEMS لتخزين واسترجاع أجزاء البيانات.

السبب في ذلك لأنه بمجرد إعادة توجيه وحدة تحكم، يصبح HTTPhandler الخاص بك system.web.mvc.mvchandler، الذي يتم إنشاؤه باستخدام HttpContextWrapper، والذي سيكون له تعريف خاص به ل httpcontext.current. لسوء الحظ، خلال هذا المصافحة، لا يتم نقل أشياء مثل httpcontext.items.

ما يغليه هذا هو أن أنواع HttpContext، على الرغم من النظر إليها وتسببت نفس الشيء، ليست هي نفسها، ولا يمكنك تمرير البيانات بهذه الطريقة.

الآن، لقد حاولت اختبار هذا الأمر، وبقدر ما أستطيع أن أقول، إذا قمت بإعادة توجيه وحدة تحكم أخرى باستخدام إعادة التوجيه، فلا تبقى httpcontext.items. أنا أستخدم مشروع ASP.NET MVC الافتراضي لاختبار هذا. ما قمت به هو، إضافة هذه الطريقة إلى global.asax.cs:

protected void Application_BeginRequest()
{
    Context.Items["Test"] = "Hello World";
}

وفي HomeController.cs، لقد غيرت طريقة الفهرس إلى:

public ActionResult Index()
{
    return RedirectToAction("About");
}

وتغيير طريقة حول:

public ActionResult About()
{
    Response.Write(Convert.ToString(HttpContext.Items["Test"]));
    return View();
}

عندما أقوم بتشغيل التطبيق، تعيد الصفحة بشكل صحيح إلى / home / حول and Response.Writes سلسلة "Hello World" الصحيحة الموجودة في Global.asax.cs.

لذلك، يبدو لي كما لو أنني أيضا لا يفهم ما معنى الكتاب عندما يقولون "أشياء مثل httpccontext.Items لا يتم نقلها" أو أنها تقوم بنقل هذه الأشياء وهي بخير لاستخدام httpcontext.items.

إذا أوصت يا رفاق بأن أتجنب httpcontext.Items، هل هناك طريقة بديلة أخرى لتخزين كائن عبر طلب على أساس لكل طلب؟

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

المحلول

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

  1. هل هو بخير للاستخدام Context.Items للتخزين المؤقت على أساس لكل طلب؟ نعم. إذا كنت في العملية، لكل طلب، لكل جهاز في مزرعة الويب هي معاييرك ثم Context.Items يمنحك ذلك.

  2. يكون Context.Items من الصعب اختبار مع؟ بقدر استيعاب، كنت أخفي Context.Items وراء واجهة من نوع ما. بهذه الطريقة تحصل على قدرات اختبار الوحدة دون الرجوع إلى الإشارة Context.Items مباشرة. خلاف ذلك، ماذا تحتاج لاختبار Context.Itemsب أن الإطار سيخزن واسترداد القيم؟ الحفاظ على كودك جيل System.Web وستكون العربة سعيدة.

  3. إرادة Context.Items ينجو RedirectToActionب لا. الاختبار الخاص بك غير صالح. إنه يضع "مرحبا، العالم" على كل طلب ويب، ويمتد الاختبار طلبتين على شبكة الإنترنت. الأول هو عند استدعاء إجراء الفهرس. والثاني هو متى RedirectToAction يسمى الإجراء (إنه http 302). لجعلها تفشل، قم بتعيين قيمة جديدة في إجراء الفهرس ومعرفة ما إذا كانت مرتبطة في الإجراء.

نصائح أخرى

استخدم قاموس Tempdata، وهو أساسا لتخزين الكائنات بين الإجراءات التي يعيد توجيهات:

public ActionResult Index()
{
    TempData.Add("Test", "Hello world");
    return RedirectToAction("About");
}

public ActionResult About()
{
    ViewData["Test"] = TempData["Test"];
    return View();
}

ثم استرجع القيمة في وجهة نظرك:

<%=ViewData["Test"] %>

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

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