ASP.NET MVC ModelBindingContext Class - كيف يتم ملء قيم النماذج الخاصة به؟

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

سؤال

أنا أخدش رأسي قليلاً في كيفية قيام المجلدات النموذجية بعملها في ASP.NET MVC.

لكي نكون محددين ، تحتوي طريقة bindModel () على معلمة modelBindingContext التي تحمل اسم النموذج ونوعها ، لكنني لا أفهم كيف يتلقى ModelBindingContext هذه القيم.

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

يبدو لي أن نموذج bindingContext "يعرف" نوع النموذج الذي يتم تسليمه ، ولست متأكدًا من أين يأتي ذلك أو سير العمل المشارك في ملءه.

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

المحلول

سؤال مهم. فيما يلي نظرة عامة بسيطة لما تفعله MVC. يتم التعامل معها كلها من قبل فئة ControllerActionInovker. هذا ليس بترتيب محدد ، ولكنه قريب.

  1. يحدد ControllerActionInovker نوع المعلمة عبر الانعكاس.
  2. يتم إنشاء ValueProviders التالي من نموذج طلب httpcontext ، والطريق ، والخصائص QueryString ، إلخ. يمكنك أيضًا توفير مقدمي القيمة الخاص بك.
  3. يتم تزويد هذه الثمانيين إلى نموذج bindingContext عبر مجموعة تعمل بمثابة valueprovider الظاهري.
  4. ثم يبحث ControllerActionInovker عن نموذج نموذج للنوع المحدد. إذا لم يجد واحدة ، فإنها تتخلف عن الافتراضات المدمجة في DefaultModelBinder.
  5. في معظم الحالات ، يتم استخدام DefaultModelBinder. تتمثل المهمة في إنشاء نموذج ، واستخدام FalueProviders لتوصيل الخصائص بالقيم باستخدام أسماء خصائص النموذج كمفتاح. عندما يكون لدى Valueproviders قيمة ، فإنهم يعيدون كائن ValueProviderResult المسؤول عن تحويل النوع.

يمكنك أن ترى هذا بنفسك في مصدر ASP.NET MVC الموجود في CodePlex.com. ابحث عن فئة ControllerActionInvoker وطريقة getParametervalue.

نصائح أخرى

يعرف modelBindingContext "نوع النموذج الذي يتم تسليمه لأنه يجب عليك إما:

  • أضف سمة طراز Binder إلى النموذج الخاص بك
  • قم بتسجيل ModelBinder مع النموذج الخاص بك باستخدام طريقة modelBinders.binders.add ().

مثال على سمة النموذج:

[ModelBinder(typeof(ContactBinder))]
public class Contact { ... }

مثال على modelbinders.binders.add ():

void Application_Start()
{
  ModelBinders.Binders[typeof(Contact)] = new ContactBinder();
}

إذا كنت قد قمت بتسجيل طرازك وقمت بتطبيق طريقة bindModel:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ... }
  1. الاستعلام عن modelBindingContext.ModelType يساوي النموذج الخاص بك على سبيل المثال

    if (bindingContext.ModelType == typeof(Contact)) { ... }
    
  2. قم بإعادة ترطيب النموذج الخاص بك من خاصية ModelBindingContext.valueprovider لاسترداد مثيلات ValueProviderResult التي تمثل البيانات من منشورات النموذج وبيانات المسار وسلسلة الاستعلام على سبيل المثال

    bindingContext.ValueProvider["Name"].AttemptedValue;
    

تم استخدام الكتب التاليةASP.NET MVC 2 في العمل وASP.NET MVC 1.0 بسرعة

الطريقة التي أراها هي أن ControllerActionInvoker يستخدم انعكاسًا للحصول على نوع المعلمة ، ثم يتحقق مما إذا كان يتم تعيين أي نموذج للتعامل مع هذا النوع ، إذا كان كذلك ، فإنه يقوم بتنظيم هذا النموذج ويمرره بنص BindingContex الاسم ، نوع النموذج ، مرشح الخصائص) لكائن نوع المعلمة هذا ومجموعة مزود القيمة (ModelBindingContext.valueprovider) لجميع مزودي القيمة الآخرين (النموذج ، سلسلة الاستعلام وما إلى ذلك) ، بصفته موفر قيمة افتراضية واحدة واحدة.

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

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