خزه / InfoPath و سرور اشکال (InfoPath و 2007) عملکرد کشویی فهرست

طبقه اضافی: InfoPath و

Summary: An InfoPath 2007 form deployed to a MOSS server provides a drop-down list of vendors tied to a custom MOSS list. Upon selecting a vendor, rules assign field values to a handful of text fields such as sales rep name, address, city, state, zip and phone. Performance is horrible. We notice that performance gets worse (in a non-linear fashion) for each additional field we update this way. I.e., if we just update the sales rep name, it takes [X] amount of time. If we update sales rep, address1, address2, city, state, zip, it takes 10 times longer.

راه حل: Write a web service (sample code can be found اینجا) that is passed in the name of a vendor and it returns back the vendor details. سپس, assign the fields this way. Although this too seems slow, there was no discernable difference in performance when we assigned 1 field versus 8 زمینه. As an added bonus, users get a cool "contacting the server" Cylon effect while they wait for the form to invoke and consume the service results.

خزه: استثنا رخ داده است. (جز از داستان: 0x80020009 (DISP_E_EXCEPTION))

تکمیلی: علت ریشه ای این مشکل مشخص و هرگز به آن سطح دیگر هرگز.

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

ما به عنوان یک مدیر مجموعه سایت وارد شوید و سعی کنید برای اضافه کردن یکی از آن دسته از کاربران به عنوان یک مدیر سایت مدیر سایت و این زمان, upon pressing "OK", ما این پیام را دریافت:

استثنا رخ داده است. (جز از داستان: 0x80020009 (DISP_E_EXCEPTION))

ما صرف برخی از زمان تحقیق و متاسفانه, نمی آمد تا با هر چیزی مفید. برخی از پیام ها در ورود تشخیصی وجود دارد, اما سخت بود دقیقا آنها را مرتبط با این موضوع.

در پایان, ما حذف مجموعه سایت و آن را دوباره ایجاد شده و آن را حل.

اگر من کشف کردن آنچه این کار را در آینده ایجاد می شود, من این پست را به روز رسانی کنید.

خزه: تکرار از طریق لیست های سفارشی و بازگشت داده های فیلتر شده را به InfoPath و

سناریوی کسب و کار:

Provide a method that enables users to enter accurate purchase requisitions quickly.

مشکل کسب و کار:

The client does business with several hundred vendors.

Vendors are "type" specific. This means that a vendor sells computer equipment (e.g. Dell) or office supplies (e.g. Staples).

چگونه ما را قادر می سازد کاربران نهایی که ایجاد نیازهای خرید را انتخاب کنید یک فروشنده معتبر?

راه حل کسب و کار:

افتراق فروشندگان در سیستم از طریق "نوع".

کاربران را قادر به انتخاب "نوع" محصول و سپس ارائه مجموعه ای از فیلتر فروشندگان مناسب.

راه حل های فنی:

فرم InfoPath و طراحی شده است که کاربران را قادر می سازد برای ورود به نیازهای خرید آنلاین.

دو InfoPath و انتخاب فروشنده کنترل لیست انتخاب. اولین, که کاربر انتخاب "نوع خرید". این یک لیست انتخاب دوم را محدود به تنها شامل فروشندگان که برای که نوع خرید فروش. این آبشار کلاسیک کشویی است.

فروشندگان در یک لیست سفارشی MOSS با ستون های سفارشی برای فروشنده های ذخیره شده ویژگی های مانند نام, آدرس و به خصوص "نوع".

پیاده سازی یک وب سرویس برای مشتری InfoPath و به مصرف می کند که از طریق لیست فروشنده های سفارشی, برگرداندن فروشندگان تطبیق یک "نوع" عرضه.

فراخوانی سرویس وب از طریق فرم InfoPath.

درس های آموخته شده:

  • اولین, لازم به نظر می رسد این مسیر برای رفتن. من ترجیح داده اند برای انجام فیلترینگ به طور کامل در InfoPath و و هر قابلیت وب سرویس ایجاد کنید در اینجا. اما, اشکال سرور از قابلیت فیلتر مورد نیاز را فراهم نمی کند. ما می توانیم یک قانون را بر روی یک "نوع قرار" لیست انتخاب در فرم را به مرتب کردن بر اساس دوباره باز پرس و جو فروشنده, اما ما نمی توانیم آن را به کار درستی. بنابراین, لازم بود به پیاده سازی وب سرویس.
  • این یک "لیست انتخاب آبشاری کلاسیک است" مشکل در InfoPath و به شکل سرور جهان و بسیاری از نمونه های خوبی وجود دارد که توضیح دهد که چگونه برای حل این وجود دارد.
  • یک مقدار خالی برای یک ستون در وندور لیست می کند یک رشته خالی که مثل این اشاره نمی گرداند: initItem["نام فروشنده"]. در عوض, آن را می گرداند مقدار null.

برخی از یادداشت های دیگر:

  • من یک آرایه بازگشت[] از فروشندگان چون تا به حال برخی از مشکلات بازگشت یک ArrayList. InfoPath و شکایت در مورد آن و من در مورد زمان و تمایل به مبارزه با بیش از آن را ندارد. این, البته, قرار می دهد حد مصنوعی در تعداد کل فروشندگان. همچنین مرا وادار به پیاده سازی یک تر و تمیز() روش در آرایه چون من ایده بازگشت تماس 100 از فروشندگان null را نفرت. InfoPath و مراقبت می کند, اما آن را در من nagged. (دوباره, این آسان تر از مبارزه با InfoPath و بیش از ArrayLists بود).
  • من اجرا GetSpecificVendorByName() تابع و همچنین, که ممکن است آموزنده.

کد:

با استفاده از سیستم;
با استفاده از System.Web;
با استفاده از System.Web.Services;
با استفاده از System.Web.Services.Protocols;
با استفاده از Microsoft.Sharepoint در;
با استفاده از System.Configuration;

/// <خلاصه>
///
خدمات فروشنده: ارائه خدمات مربوط فروشنده که امروز توسط یک فرم مشتری InfoPath و مصرف.
///
/// تاریخ:
/// ——–
/// 07/24/07: برنامه نویسی اولیه, پل J. گاوین از Conchango.
///
/// </خلاصه>
[WebService(Namespace = "http://www.conchango.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
عمومی کلاس VendorService : System.Web.Services.WebService
{

/// <خلاصه>
/// نشان دهنده یک فروشنده از یک لیست شیرپوینت سفارشی که توسط MSUSA.
/// </خلاصه>
عمومی کلاس فروشنده
{
عمومی فروشنده() { }

عمومی فروشنده(SPItem initItem)
{
اگر (! (initItem["نام فروشنده"] == صفر)) VendorName = initItem["نام فروشنده"].ToString();
اگر (! (initItem["آدرس 1"] == صفر)) VendorAddress1 = initItem["آدرس 1"].ToString();
اگر (! (initItem["آدرس 2"] == صفر)) VendorAddress2 = initItem["آدرس 2"].ToString();
اگر (! (initItem["شهر"] == صفر)) VendorCity = initItem["شهر"].ToString();
اگر (! (initItem["VendorPhone"] == صفر)) VendorPhone = initItem["VendorPhone"].ToString();
اگر (! (initItem["PurchaseType"] == صفر)) VendorType = initItem["PurchaseType"].ToString();
اگر (! (initItem["دولت"] == صفر)) VendorState = initItem["دولت"].ToString();
اگر (! (initItem["پستی"] == صفر)) VendorZip = initItem["پستی"].ToString();
اگر (!(initItem["فکس"] == صفر)) VendorFax = initItem["فکس"].ToString();
اگر (!(initItem["SalesRepName"] == صفر)) VendorSalesRepName = initItem["SalesRepName"].ToString();

VendorItemId = initItem.ID; // شناسه منحصر به فرد حفظ طریق MOSS.
}

عمومی اعضای هیات VendorItemId;
عمومی رشته VendorName;
عمومی رشته VendorAddress1;
عمومی رشته VendorAddress2;
عمومی رشته VendorCity;
عمومی رشته VendorState;
عمومی رشته VendorZip;
عمومی رشته VendorPhone;
عمومی رشته VendorType;
عمومی رشته VendorSalesRepName;
عمومی رشته VendorFax;
}

عمومی VendorService () {

//Uncomment the following line if using designed components
//InitializeComponent();
}

خصوصی فروشنده[] GenerateTestVendors()
{
فروشنده[] resultList;
resultList = جدید فروشنده[100];

فروشنده V;
V = جدید فروشنده();
v.VendorAddress1 = "v1_address1";
v.VendorAddress2 = "v1_address2";
v.VendorCity = "v1_city";
v.VendorName = "v1_vendorname";
v.VendorPhone = "v1_vendorphone";
v.VendorState = "v1_st";
v.VendorType = "v1_type";
v.VendorZip = "v1_zip";

resultList[0] = V;

V = جدید فروشنده();

v.VendorAddress1 = "v2_address1";
v.VendorAddress2 = "v2_address2";
v.VendorCity = "v2_city";
v.VendorName = "v2_vendorname";
v.VendorPhone = "v2_vendorphone";
v.VendorState = "v2_st";
v.VendorType = "v2_type";
v.VendorZip = "v2_zip";

resultList[1] = V;

V = جدید فروشنده();
v.VendorAddress1 = "v3_address1";
v.VendorAddress2 = "v3_address2";
v.VendorCity = "v3_city";
v.VendorName = "v3_vendorname";
v.VendorPhone = "v3_vendorphone";
v.VendorState = "v3_st";
v.VendorType = "v3_type";
v.VendorZip = "v3_zip";

resultList[2] = V;

برگشت resultList;

}

[WebMethod]
عمومی فروشنده GetSpecificVendorById(اعضای هیات vendorId)
{
رشته SpVendorSiteName; // نام سایت واقعی MOSS که میزبان لیست های سفارشی فروشنده.
رشته SpVendorListName; // نام واقعی لیست حاوی فروشندگان MOSS.

SpVendorSiteName = ConfigurationSettings.AppSettings["VendorListHostingSite"].ToString();
SpVendorListName = ConfigurationSettings.AppSettings["فناوری اطلاعات"].ToString();

با استفاده از (SPSite site = جدید SPSite(SpVendorSiteName))
{

با استفاده از (SPWeb web = site.OpenWeb())
{

SPList currentList = web.Lists[SpVendorListName];

SPItem specificItem = currentList.Items[vendorId];

برگشت جدید فروشنده(specificItem);

} // using spweb web = site.openweb()
} // using spsite site = new spsite("http://localhost/mizuho")

}

[WebMethod]
// فرض می شود که نام فروشنده منحصر به فرد است, از دیدگاه کسب و کار
عمومی فروشنده GetSpecificVendorByVendorName(رشته vendorName)
{
رشته SpVendorSiteName; // نام سایت واقعی MOSS که میزبان لیست های سفارشی فروشنده.
رشته SpVendorListName; // نام واقعی لیست حاوی فروشندگان MOSS.

SpVendorSiteName = ConfigurationSettings.AppSettings["VendorListHostingSite"].ToString();
SpVendorListName = ConfigurationSettings.AppSettings["فناوری اطلاعات"].ToString();

با استفاده از (SPSite site = جدید SPSite(SpVendorSiteName))
{
با استفاده از (SPWeb web = site.OpenWeb())
{

SPList currentList = web.Lists[SpVendorListName];

حلقه foreach (SPItem vendorItem به currentList.Items)
{
اگر (vendorItem["نام فروشنده"] == صفر) ادامه;

اگر (vendorItem["نام فروشنده"].ToString().برابر(vendorName))
برگشت جدید فروشنده(vendorItem);
}

فروشنده V = جدید فروشنده();
v.VendorPhone = "پیدا نشد: " + vendorName;

برگشت V;

برگشت صفر;

} // using spweb web = site.openweb()
} // using spsite site = new spsite("http://localhost/mizuho")

} // روش

[WebMethod]
عمومی فروشنده[] GetVendorsOfType (رشته filterType)
{

رشته SpVendorSiteName; // نام سایت واقعی MOSS که میزبان تی
او فروشنده لیست های سفارشی.
رشته SpVendorListName; // نام واقعی لیست حاوی فروشندگان MOSS.

SpVendorSiteName = ConfigurationSettings.AppSettings["VendorListHostingSite"].ToString();
SpVendorListName = ConfigurationSettings.AppSettings["فناوری اطلاعات"].ToString();

فروشنده[] resultList;
اعضای هیات vendorIndex = 0;
resultList = جدید فروشنده[1000];

// مقداردهی اولیه لیست با یک پیام به طور پیش فرض دوستانه.
فروشنده V = جدید فروشنده();
v.VendorName = "یک نوع فروشنده به جمعیت این لیست انتخاب کنید.";
resultList[0] = V;

// تبدیل فیلتر به صورت پایین تر برای مقایسه رشته آسان تر بعد.
filterType = filterType.ToLower();

// اگر نوع فیلتر منتقل "آزمون" است, تولید برخی از داده های ساده.
#منطقه نوع فیلتر = "آزمون"
اگر (filterType.Equals("test"))
برگشت GenerateTestVendors();
#endregion قسمت

اگر (درست)
{
با استفاده از (SPSite site = جدید SPSite(SpVendorSiteName))
{
با استفاده از (SPWeb web = site.OpenWeb())
{

V = صفر;

SPList currentList = web.Lists[SpVendorListName];

// تکرار از طریق تمام اقلام در لیست فروشنده.
حلقه foreach (SPItem vendorItem به currentList.Items)
{

رشته lowerVendorType;

lowerVendorType = vendorItem["PurchaseType"].ToString().ToLower();
lowerVendorType = lowerVendorType.Substring(3);

اگر (lowerVendorType.Equals(filterType))
{
resultList[vendorIndex ] = جدید فروشنده(vendorItem);
}
} // تکرار از طریق تمام فروشندگان در لیست


برگشت TrimVendorArray(vendorIndex, resultList);
// بازگشت resultList;

} // using spweb web = site.openweb()
} // using spsite site = new spsite("http://localhost/mizuho")

} // اگر درست باشد

برگشت صفر;
}

خصوصی فروشنده[] TrimVendorArray(اعضای هیات اخبار در, فروشنده[] originalVendorArray)
{
فروشنده[] trimmedArray;

اگر (اخبار، == 0) اخبار در = 1;
trimmedArray = جدید فروشنده[اخبار در];

اعضای هیات currentCounter = 0;

برای (currentCounter = 0; currentCounter < اخبار در; currentCounter )
{
trimmedArray[currentCounter] = originalVendorArray[currentCounter];
}

برگشت trimmedArray;

}
}

خزه: مشاهدات در اشکال زدایی InfoPath و

InfoPath form server error messages are misleading.

During development of an InfoPath form, I would post it to MOSS server and access the form. The form would start to load and then generate a misleading error message pointing me to the windows event log for details. در واقع, no message was written to the windows event log. Rather, the message was sent to the MOSS ascii diagnostic log. You can track that down via central services administration.

You need to be quick on your feet. MOSS likes to write to the log file, frequently and verbosely. This can be trimmed but the default log writing behavior is "everything as quickly as possible".

خزه: به روز رسانی یک لیست سفارشی

بسیاری از نمونه های خوبی از به روز رسانی لیست سفارشی از طریق SDK وجود دارد. در اینجا است که هنوز یکی دیگر از.

مشکل کسب و کار: فرم InfoPath و طراحی شده است که کاربران را قادر می سازد تا وارد نیازهای خرید آنلاین. شماره PO مصادره باید سنتی ترتیب بر اساس مقادیر صحیح محاسبه و به صورت خودکار.

راه حل کسب و کار: ایجاد یک لیست خزه های سفارشی شامل دو ستون: "ControlField" and "ControlValue". مقدار ستون شامل درخواست خرید شماره بعدی. Note that the generic "control" نامگذاری کنوانسیون را فراهم می کند برای زمینه کنترل آینده ای است که ممکن است مورد استفاده قرار گیرد در صورت نیاز.

راه حل های فنی: ایجاد یک وب سرویس در دسترس مشتری InfoPath و. وب سرویس را برمی گرداند به خرید شماره بعدی مصادره و به روز رسانی ارزش از لیست.

درس های آموخته شده:

  • در هنگامی که اضافه کردن این خدمات وب سایت به عنوان یک منبع داده ها به فرم InfoPath از, که من پیدا کردم آن را لازم را برای آن را تبدیل به یک UDC و ذخیره آن را به یک کتابخانه اتصال داده ها.
  • من همچنین آن را در بر داشت لازم است به قادر می سازد صلیب دامنه برنامه نویسی از طریق دولت خدمات مرکزی // نرم افزار مدیریت // فرم سرور پیکربندی.
  • اولین بار است که فرم سعی برای دسترسی به وب سرویس, در آن طول می کشد یک در حالی که و بر روی مناسبت, این امر می مدت زمان کردن. من با تنظیمات در فرم سرور پیکربندی fiddled به گسترش تنظیمات های ایست و که به نظر می رسید برای کمک به.

کد:

با استفاده از سیستم;
با استفاده از System.Web;
با استفاده از System.Web.Services;
با استفاده از System.Web.Services.Protocols;
با استفاده از Microsoft.Sharepoint در;
با استفاده از System.Configuration;

[WebService(Namespace = "http://www.conchango.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
عمومی کلاس PoService : System.Web.Services.WebService
{
عمومی PoService () {

//Uncomment the following line if using designed components
//InitializeComponent();
}

/// <خلاصه>
/// Obtain the next PO number from the sharepoint po number control list.
/// Increment the PO number in that list.
/// </خلاصه>
/// <بازده></بازده>
[WebMethod]
عمومی رشته GetNextPoNumber()
{
رشته SpPoControlSiteName; // Name of the actual MOSS site that hosts the PO Control list.
رشته SpPoControlListName; // Name of the actual MOSS list containing the Po control.

SpPoControlSiteName = ConfigurationSettings.AppSettings["PoControlListHostingSite"].ToString();
SpPoControlListName = ConfigurationSettings.AppSettings["PoControlList"].ToString();

رشته nextPoReqNumber = "xyzzy";

با استفاده از (SPSite site = جدید SPSite(SpPoControlSiteName))
{
با استفاده از (SPWeb web = site.OpenWeb())
{

SPList currentList = web.Lists[SpPoControlListName];

حلقه foreach (SPItem controlItem به currentList.Items)
{

اگر (((رشته)controlItem["ControlField"]).برابر("NextPoNumber"))
{
nextPoReqNumber = (رشته)controlItem["ControlValue"];

اعضای هیات int_nextPoReqNumber;
int_nextPoReqNumber = تبدیل.ToInt32(nextPoReqNumber);

int_nextPoReqNumber ;

controlItem["ControlValue"] = int_nextPoReqNumber;
controlItem.Update();
}

} // Locating, reading and updating the PO number in the list.


} // using spweb web = site.openweb()
} // using spsite site = new spsite("http://localhost/mizuho")

برگشت nextPoReqNumber;

}
}