ASP.NET MVC: تجنب اقتران ضيق عند الربط شكل POST إلى المعلمة

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

سؤال

ودعونا نقول لدي واجهة مثل:

interface IThing {
   int Id { get; set; }
   string Title { get; set; }
}

وفي ASP.NET MVC لدي شكل مشاركات لعمل تحكم مثل هذا:

 [AcceptVerbs(HttpVerbs.Post)]
 public ActionResult NewThing([Bind(Exclude = "Id")] SimpleThing thing) {

    // code to validate and persist the thing can go here            
 }

وأين <م> SimpleThing هي فئة الملموسة التي بالكاد تنفذ <م> IThing .

ولكن، أود جميع طرق للتعامل مع واجهة. لدي تجميع البيانات التي تستخدم NHiberate وتلقاء نفسها <م> IThing التنفيذ (دعنا نسميها <م> RealThing ). أنا لا يمكن تمرير SimpleThing إليها لأنها سوف يشكو "كيان غير معروف".

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

وشكرا!

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

المحلول 3

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

وأبسط من ذلك بكثير، وأنه يتيح لي الفرصة لالتقاط البيانات التي ليست جزءا من نموذج نطاقي (أي مثل حقل "التعليقات").

نصائح أخرى

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

وخطرت لي نهجين في هذا.

والأول هو إضافة رمز إلى صفي NHibernate مستودع لترجمة نوع POCO بسيط المستخدمة من قبل وحدة تحكم MVC (<م> SimpleThing ) إلى نوع من كيان NHibernate أراد (<م> RealThing ):

/// <summary>
/// A NHibernate generic repository.  Provides base of common 
/// methods to retrieve and update data.
/// </summary>
/// <typeparam name="T">The base type to expose 
/// repository methods for.</typeparam>
/// <typeparam name="K">The concrete type used by NHibernate</typeparam>
public class NHRepositoryBase<T, K> 
    : IRepository<T>
    where T : class
    where K : T, new()
{
    // repository methods ...

    /// <summary>
    /// Return T item as a type of K, converting it if necessary
    /// </summary>        
    protected static K GetKnownEntity(T item) {
        if (typeof(T) != typeof(K)) {
            K knownEntity = new K();

            foreach (var prop in typeof(T).GetProperties()) { 
                object value = prop.GetValue(item, null);
                prop.SetValue(knownEntity, value, null);
            }

            return knownEntity;
        } else {

            return (K)item;
        }            
    }

وهكذا، أي الأسلوب في مستودع يمكن استدعاء GetKnownEntity (T البند)، وسوف نسخ خصائص العنصر الذي يمر في لمن النوع الذي يريد NHibernate. ومن الواضح أن هذا شعر عالي الكعب قليلا، لذلك كنت قد بحثت في لتجليد نموذج مخصص.


في النهج الثاني، أنا خلق الموثق نموذج مخصص مثل هذا:

public class FactoryModelBinder<T> 
    : DefaultModelBinder 
    where T : new() 
{

    protected override object CreateModel(ControllerContext controllerContext, 
                                          ModelBindingContext bindingContext, 
                                          Type modelType) {

        return new T();                       
    }

}

وبعد ذلك لقد سجلت ذلك في Global.asax.cs مع:

ModelBinders.Binders.Add(typeof(IThing), 
            new FactoryModelBinder<RealThing>());

وأنه يعمل بشكل جيد مع عمل المراقب المالي الذي يبدو مثل هذا:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] IThing thing) {
    // code to process the thing goes here
}

وأنا أحب النهج الثاني، ولكن معظم أشيائي حقن التبعية هو في الدرجة المراقب المالي. أنا لا أحب أن يكون لإضافة كل هذه التعيينات ModelBinder في Global.asax.cs.

وهذا ليس dirrect unswer على سؤالك.

ونحن نستخدم طريقة مختلفة قليلا للتعامل مع نفس المشكلة لديك. لدينا تحكم تقبل DTOs التي تطابق الحقل كيان المستمر من قبل المجال. ثم نحن المستعمل AutoMapper لخلق كيانات persisten التي سوف تذهب إلى قاعدة البيانات. هذا يلغي اجهات unnessesery وأقفال أسفل API تواجه العام (يعني أن إعادة تسمية بيرسيستانسي حقل كائن لن كسر رمز العميل لدينا).

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