آی تی نرد

اشتراک اطلاعات و تجربیات در زمینه ی توسعه ی دات نت و البته شیرپوینت

متد استخراج یا یافتن لیست و فیلد توسط مقادیر مختلف در شرپوینت

یکی از مشکلاتی که یک برنامه نویس شرپوینت باهاش زیاد مواجه میشه دسترسی و استخراج یا یافتن یک آبجکت شرپوینتی مانند لیست یا فیلد هست.
یه مفهومی که همیشه وجود داره این هست که اضافه کردن لایه های مختلف و دور کردن برنامه نویس از لایه های پایین هم باعث راحتی برنامه نویس و هم سختی بیش از حد اون خواهد شد.
برای مثال در Asp.Net Web Forms وجود لایه های بسیار برای راحتی کار برنامه نویس مثل داشتن کنترل های سروری به قیمت سختی یافتن مشکل و همچنین سنگین شدن برنامه ی نهایی تمام خواهد شد.

در این مورد برای دسترسی به یک لیست شرپوینت و عملیات برروی آن نیاز هست تا برنامه نویس مشخصاتی از قبیل نام نمایشی(DisplayName) یا نام ثابت(StaticName) و یا نام داخلی(InternalName) و یا شناسه ی لیست(ID or Guid) را داشته باشد.

وجود این موارد مطمئنا برای راحتی کار برنامه نویس بوده است اما به قیمت سختی کار برنامه نویس در جنبه های دیگر تمام میشود. برای مثال فرض کنید برنامه نویس راهکاری می نویسد که در آن می بایست کاربر نهایی نام لیست را برای کارهای بعدی در اینترفیس وارد نماید، خب کاربر نام نمایشی را می بیند و همان را هم وارد خواهد کرد. اما امکان دارد برنامه نویس دیگری در قسمتی از برنامه با نام داخلی کار کند(به دلیل غیرقابل تغییر بودن آن) و به آن نیاز داشته باشد و در صورتی که همین مقدار به کد این برنامه نویس دیگر ارسال شود برنامه متوقف خواهد شد زیرا این لیست را پیدا نخواهد کرد.

برای راحت کردن این سختی میتوان از متد زیر استفاده کرد:

      public static SPList TryGetByAnything(this SPListCollection coll, string nameOrGuidOrIndex)
      {
         SPList list = null;
         int byIndex = nameOrGuidOrIndex.IsNumeric() ? int.Parse(nameOrGuidOrIndex) : -1;
         GeneralHelpers.Try(() => list = byIndex != -1 ? coll[byIndex] : coll[nameOrGuidOrIndex]);
         if (list == null)
            GeneralHelpers.Try(() => list = coll.GetList(new Guid(nameOrGuidOrIndex), true));
         if (list == null)
            list = coll.TryGetList(nameOrGuidOrIndex);
         if (list == null)
         {
            GeneralHelpers.Try(() => list = (from SPList lst in coll
                                            where lst.RootFolder.Name.Equals(nameOrGuidOrIndex, StringComparison.OrdinalIgnoreCase)
                                            select lst).FirstOrDefault());
         }
         return list;
      }

در متد بالا ابندا بررسی میشود، آیا مقدار وارده عددی هست در این صورت شناسه ی لیست فرض خواهد شد و در همان مرحله ی اول لیست یافته و برمی گردد، در غیر اینصورت از تمامی روش های استخراج لیست به ترتیب استفاده خواهد شد و در هر مرحله در صورت یافتن، لیست برگردانده میشود و از متد خارج خواهد شد. در صورتی که لیستی از این طریق یافت نشود مطمئن شوید که مقدار وارده مشکل دارد.

مانند همین متد رو هم میشه برای استخراج فیلد یا ستون نوشت:

      /// <summary>
      /// استخراج فیلد توسط هر مقدار پراپرتی ممکن مانند نام یا شناسه یا عنوان نمایشی یا ...
      /// </summary>
      /// <param name="coll">مجموعه فیلدها</param>
      /// <param name="nameOrGuidOrIndex">شناسه یا جی یو ایدی یا نام نمایشی یا نام داخلی یا نام ثابت</param>
      /// <returns>در صورت نبودن نول برمیگردد</returns>
      public static SPField TryGetByAnything(this SPFieldCollection coll, string nameOrGuidOrIndex)
      {
         SPField field = null;
         int byIndex = nameOrGuidOrIndex.IsNumeric() ? int.Parse(nameOrGuidOrIndex) : -1;
         GeneralHelpers.Try(() => field = byIndex != -1 ? coll[byIndex] : coll[new Guid(nameOrGuidOrIndex)]);
         if (field == null)
            GeneralHelpers.Try(() => field = coll[nameOrGuidOrIndex]);
         if (field == null)
            GeneralHelpers.Try(() => field = coll.GetField(nameOrGuidOrIndex));
         if (field == null)
            field = coll.TryGetFieldByStaticName(nameOrGuidOrIndex);
         if (field == null)
            GeneralHelpers.Try(() => field = coll.GetFieldByInternalName(nameOrGuidOrIndex));

         return field;
      }

تمامی متدهایی که Tryدر نام آن استفاده شده باشد در صورت عدم موفقیت در انجام عملیات که در این مورد یافتن لیست یا فیلد می باشد، به خطا نخواهد خورد و در عوض مقدار نول برمیگرداند.

نحوه ی استفاده ی این متد ها هم به صورت زیر می باشد:

   SPList targetList = web.Lists.TryGetByAnything("listName");
   SPField targetField = targetList.Fields.TryGetByAnything("fieldName");

در این متدها از متدهای دیگری نیز استفاده شده است که در زیر آمده است:

      /// <summary>
      /// تعیین عددی بودن آبجکت
      /// </summary>
      /// <param name="Expression"></param>
      /// <returns></returns>
      public static System.Boolean IsNumeric(this System.Object Expression)
      {
         if (Expression == null || Expression is DateTime)
            return false;

         if (Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
            return true;

         try
         {
            if (Expression is string)
               Double.Parse(Expression as string);
            else
               Double.Parse(Expression.ToString());
            return true;
         }
         catch { }
         return false;
      }

در متد بالا عددی بودن آبجکت بررسی خواهد شد.

      /// <summary>
      /// در حالتی که امکان خطا خوردن هست و می توان آن را نادیده گرفت و نمیخواهید برنامه بلاک شود
      /// </summary>
      /// <param name="v"></param>
      public static void Try(Action v)
      {
         try { v(); }
         catch { }
      }

متد بالا هم یک try catch یک خطی هست.

امیدوارم این متدهای کاربردی که حداقل برای من کاربردی بوده برخی از مشکلات و نگرانی های شما رو رفع کند.

نظرات (3) -

  • mghorbani

    6/13/1392 08:27:15 ق.ظ | پاسخ به این نظر

    این متدها خیلی کاربردی هستند و برای برنامه نویسی که خیلی با لیست و ستون سرو کار داره میتونه کمک خوبی براش باشه.
    فقط یه مطلبی که هست اینه که یک کلاس با نام GeneralHelpers در دو متد اول وجود داره که فکر میکنم نام کلاسی هست که متد try catch یک خطی رو باید توش تعریف کنیم درسته؟

    • حمید

      6/13/1392 05:03:16 ب.ظ | پاسخ به این نظر

      دقیقا درسته.
      ممنون از نکته ی تکمیلیت.
      ضمن اینکه خود متد هم Extension نیست پس کلاس هم، نیازی نیست حتما static باشه.

Loading