MOSS / InfoPath Forms Server (InfoPath 2007) listrutan prestanda

Ytterligare en kategori: InfoPath

Sammanfattning: En InfoPath 2007 formuläret distribueras till en MOSS server ger en drop-down lista över leverantörer knuten till en anpassad lista som MOSS. På att välja en leverantör, regler tilldela värden till en handfull textfält som säljare namn, Adress, staden, staten, zip och telefon. Prestanda är hemsk. Vi märker att prestanda blir värre (icke-linjärt) för varje ytterligare fält uppdatera vi detta sätt. Dvs., om vi bara uppdatera namnet säljare, Det tar [x] tid. Om vi uppdaterar säljare, Adress1, Adress2, staden, staten, zip, Det tar 10 gånger längre.

Lösning: Skriva en webbtjänst (exempelkod kan hittas Här) som skickas i en leverantör och det återgår tillbaka till leverantörsinformation. Sedan, tilldela fält detta sätt. Även om detta verkar alltför långsam, Det fanns inga märkbara skillnader i prestanda när vi tilldelats 1 fältet kontra 8 fält. Som en extra bonus, användare få en cool "att kontakta servern" Cylon effekt medan de väntar på formuläret att åberopa och konsumera tjänsten resultat.

MOSS: Undantag uppstod. (Undantag från HRESULT: 0x 80020009 (DISP_E_EXCEPTION))

UPPDATERING: Vi fastställt aldrig orsaken till problemet och det aldrig ytan igen.

Vi märker under genomförandet av en utveckling som plötsligt, två användare kan inte komma åt en webbplatssamling. Dessa konton kan autentisera till huvudsidan, men när jag försöker komma åt en viss webbplatssamling, de får bara en blank skärm. Inga fel visas, bara en vit tom sida.

Vi logga in som en webbplats samling admin och försöker lägga till en av de användarna som en webbplats admin och den här gången, på att trycka på "OK", Vi får detta meddelande:

Undantag uppstod. (Undantag från HRESULT: 0x 80020009 (DISP_E_EXCEPTION))

Vi tillbringade en tid forska detta och tyvärr, kom inte upp med något användbart. Det fanns vissa meddelanden i diagnostiklogg, men det var svårt att exakt korrelera dem med denna fråga.

I slutet, Vi tar bort webbplatssamlingen och återskapas det och som löste det.

Om jag lista ut vad som orsakade detta i framtiden, Jag kommer uppdatera detta inlägg.

MOSS: Iterera genom anpassade listor och återvänder filtrerade data till InfoPath

Affärsscenario:

En metod som möjliggör för användare att ange korrekt inköpsrekvisitioner snabbt.

Affärsproblem:

Klienten gör affärer med flera hundra leverantörer.

Leverantörer är "typ" särskilda. Detta innebär att en leverantör säljer datorutrustning (t.ex. Dell) eller kontorsmateriel (t.ex. Staples).

Hur vi aktiverar slutanvändare som skapar inköpsrekvisitioner Välj en giltig leverantör?

Affärslösning:

Skilja leverantörer i systemet via "typ".

Möjligt för användare att välja vilken "typ" av produkten och sedan ge en filtrerad uppsättning lämpliga leverantörer.

Teknisk lösning:

Ett InfoPath-formulär har utformats att kan användare ange online inköpsrekvisitioner.

Två InfoPath listorna styra säljaren urval. Första, användaren väljer en "Köp typ". Detta begränsar en andra lista innehåller endast leverantörer som säljer för att köpa typ. Detta är en klassisk CSS nedrullningsbar.

Leverantörer lagras i en anpassad lista som MOSS med anpassade kolumner för leverantör attribut som namn, adress och särskilt "typ".

Genomföra en webbtjänst för en InfoPath klient att konsumera som itererar igenom leverantörslistan anpassade, återvänder bara leverantörer på en medföljande "typ".

Anropa webbtjänsten via InfoPath-formuläret.

Lärdomar:

  • Första, Det verkar nödvändigt att gå denna väg. Jag skulle ha föredragit att göra filtreringen i InfoPath och inte skapa någon web service funktionalitet här. Men, Forms server ger inte de nödvändiga filtreringsfunktionen. Vi kan sätta en regel på en "type" listan i formuläret för att åter öppna typ av leverantör frågan, men vi kan inte få det att fungera ordentligt. Därför, Det var nödvändigt att genomföra webbtjänsten.
  • Detta är en klassisk "cascading urvalslista" problem i InfoPath bildar server världen och det finns många goda exempel där ute som kan förklara hur man löser detta.
  • Ett tomt värde för en kolumn i leverantörslistan returnerar inte en tom sträng när de refereras som denna: initItem["Leverantörens namn"]. I stället, den returnerar ett null-värde.

Några andra anteckningar:

  • Jag returnerar en matris[] leverantörer eftersom jag hade vissa svårigheter att återvända en ArrayList. InfoPath klagar på det och jag hade inte tid eller lust att slåss om det. Detta, Självklart, sätter en konstlad gräns på det totala antalet leverantörer. Det också tvingade mig att genomföra en trim() metod på matrisen eftersom jag hatar tanken på att återvända tillbaka 100-tals null leverantörer. InfoPath inte bryr sig, men det tjatade på mig. (Igen, Detta var enklare än att bekämpa InfoPath över ArrayLists).
  • Jag genomfört en GetSpecificVendorByName() funktion samt, som kan vara lärorikt.

Koden:

med hjälp av System;
med hjälp av System.Web;
med hjälp av System.Web.Services;
med hjälp av System.Web.Services.Protocols;
med hjälp av Microsoft.SharePoint;
med hjälp av System.Configuration;

/// <Sammanfattning>
///
Leverantörens Service: Ger leverantören med tjänster som idag konsumeras av formulär infopath klient.
///
/// Historia:
/// ——–
/// 07/24/07: Ursprungliga kodning, Paul J. Gavin av Conchango.
///
/// </Sammanfattning>
[WebService(Namespace = "http://www.conchango.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
offentliga klass VendorService : System.Web.Services.WebService
{

/// <Sammanfattning>
/// Representerar en leverantör från en anpassad sharepoint-lista som underhålls av MSUSA.
/// </Sammanfattning>
offentliga klass Leverantör
{
offentliga Leverantör() { }

offentliga Leverantör(SPItem initItem)
{
om (! (initItem["Leverantörens namn"] == null)) Leverantörsnamn = initItem["Leverantörens namn"].ToString();
om (! (initItem["Adress 1"] == null)) VendorAddress1 = initItem["Adress 1"].ToString();
om (! (initItem["Adress 2"] == null)) VendorAddress2 = initItem["Adress 2"].ToString();
om (! (initItem["City"] == null)) VendorCity = initItem["City"].ToString();
om (! (initItem["VendorPhone"] == null)) VendorPhone = initItem["VendorPhone"].ToString();
om (! (initItem["PurchaseType"] == null)) VendorType = initItem["PurchaseType"].ToString();
om (! (initItem["Staten"] == null)) VendorState = initItem["Staten"].ToString();
om (! (initItem["Zip"] == null)) VendorZip = initItem["Zip"].ToString();
om (!(initItem["Fax"] == null)) VendorFax = initItem["Fax"].ToString();
om (!(initItem["SalesRepName"] == null)) VendorSalesRepName = initItem["SalesRepName"].ToString();

VendorItemId = initItem.ID; // Unikt ID underhålls via MOSS.
}

offentliga int VendorItemId;
offentliga sträng Leverantörsnamn;
offentliga sträng VendorAddress1;
offentliga sträng VendorAddress2;
offentliga sträng VendorCity;
offentliga sträng VendorState;
offentliga sträng VendorZip;
offentliga sträng VendorPhone;
offentliga sträng VendorType;
offentliga sträng VendorSalesRepName;
offentliga sträng VendorFax;
}

offentliga VendorService () {

//Avkommentera följande rad om du använder komponenter för
//InitializeComponent();
}

privat Leverantör[] GenerateTestVendors()
{
Leverantör[] Tabellen;
Tabellen = nya Leverantör[100];

Leverantör v;
v = nya Leverantör();
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";

Tabellen[0] = v;

v = nya Leverantör();

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";

Tabellen[1] = v;

v = nya Leverantör();
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";

Tabellen[2] = v;

återvändande Tabellen;

}

[WebMethod]
offentliga Leverantör GetSpecificVendorById(int vendorId)
{
sträng SpVendorSiteName; // Namnet på den faktiska MOSS webbplats som är värd för den anpassade listan för leverantör.
sträng SpVendorListName; // Namnet på den faktiska MOSS lista som innehåller leverantörer.

SpVendorSiteName = ConfigurationSettings.AppSettings["VendorListHostingSite"].ToString();
SpVendorListName = ConfigurationSettings.AppSettings["VendorList"].ToString();

med hjälp av (SPSite plats = nya SPSite(SpVendorSiteName))
{

med hjälp av (SPWeb Web = webbplats. OpenWeb())
{

SPList currentList = web. Listor[SpVendorListName];

SPItem specificItem = currentList.Items[vendorId];

återvändande nya Leverantör(specificItem);

} // med hjälp av spweb web = site.openweb()
} // webbplatsen för spsite = nya spsite("http://localhost/mizuho")

}

[WebMethod]
// Antar att leverantörens namn är unik, från ett affärsperspektiv
offentliga Leverantör GetSpecificVendorByVendorName(sträng vara)
{
sträng SpVendorSiteName; // Namnet på den faktiska MOSS webbplats som är värd för den anpassade listan för leverantör.
sträng SpVendorListName; // Namnet på den faktiska MOSS lista som innehåller leverantörer.

SpVendorSiteName = ConfigurationSettings.AppSettings["VendorListHostingSite"].ToString();
SpVendorListName = ConfigurationSettings.AppSettings["VendorList"].ToString();

med hjälp av (SPSite plats = nya SPSite(SpVendorSiteName))
{
med hjälp av (SPWeb Web = webbplats. OpenWeb())
{

SPList currentList = web. Listor[SpVendorListName];

foreach (SPItem vendorItem i currentList.Items)
{
om (vendorItem["Leverantörens namn"] == null) «««;

om (vendorItem["Leverantörens namn"].ToString().Är lika med(vara))
återvändande nya Leverantör(vendorItem);
}

Leverantör v = nya Leverantör();
v.VendorPhone = "kunde inte hittas: " + vara;

återvändande v;

återvändande null;

} // med hjälp av spweb web = site.openweb()
} // webbplatsen för spsite = nya spsite("http://localhost/mizuho")

} // metoden

[WebMethod]
offentliga Leverantör[] GetVendorsOfType (sträng filterType)
{

sträng SpVendorSiteName; // Namnet på den faktiska MOSS webbplats som är värd t
Han anpassade leverantörslista.
sträng SpVendorListName; // Namnet på den faktiska MOSS lista som innehåller leverantörer.

SpVendorSiteName = ConfigurationSettings.AppSettings["VendorListHostingSite"].ToString();
SpVendorListName = ConfigurationSettings.AppSettings["VendorList"].ToString();

Leverantör[] Tabellen;
int vendorIndex = 0;
Tabellen = nya Leverantör[1000];

// Initiera listan med ett vänligt meddelande som standard.
Leverantör v = nya Leverantör();
v.VendorName = "Välja en leverantör att fylla denna listan.";
Tabellen[0] = v;

// Filtret Konvertera till gemener för lättare strängjämförelse senare.
filterType = filterType.ToLower();

// Om filtertypen passerade är "test", generera några enkla data.
#regionen Filtertypen = "test"
om (filterType. lika med("test"))
återvändande GenerateTestVendors();
#endregion

om (sant)
{
med hjälp av (SPSite plats = nya SPSite(SpVendorSiteName))
{
med hjälp av (SPWeb Web = webbplats. OpenWeb())
{

v = null;

SPList currentList = web. Listor[SpVendorListName];

// Iterera genom alla objekt i leverantörslistan.
foreach (SPItem vendorItem i currentList.Items)
{

sträng lowerVendorType;

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

om (lika med lowerVendorType.(filterType))
{
Tabellen[vendorIndex ] = nya Leverantör(vendorItem);
}
} // iterera genom alla leverantörer i listan


återvändande TrimVendorArray(vendorIndex, Tabellen);
// Returnera tabellen;

} // med hjälp av spweb web = site.openweb()
} // webbplatsen för spsite = nya spsite("http://localhost/mizuho")

} // om värdet är true

återvändande null;
}

privat Leverantör[] TrimVendorArray(int newsize, Leverantör[] originalVendorArray)
{
Leverantör[] trimmedArray;

om (newsize == 0) newsize = 1;
trimmedArray = nya Leverantör[newsize];

int currentCounter = 0;

för (currentCounter = 0; currentCounter < newsize; currentCounter )
{
trimmedArray[currentCounter] = originalVendorArray[currentCounter];
}

återvändande trimmedArray;

}
}

MOSS: Synpunkter på InfoPath felsökning

InfoPath form server-felmeddelanden är missvisande.

Under utvecklingen av ett InfoPath-formulär, Jag skulle skicka den till MOSS servern och komma åt formuläret. Form skulle börja att ladda och sedan skapa en missvisande felmeddelande peka mig till händelseloggen i windows för Detaljer. I själva verket, inget meddelande var skrivs till händelseloggen i windows. Snarare, meddelandet skickades till MOSS ascii diagnostiklogg. Du kan spåra som via centrala tjänster administration.

Du måste vara snabb på fötterna. MOSS gillar att skriva till loggfilen, ofta och uppstartsprocess. Detta kan trimmas men Standardloggen skriva beteende är "allt så snabbt som möjligt".

MOSS: Uppdatera en anpassad lista

Det finns många goda exempel på uppdatera anpassade listor via SDK. Här är ännu en.

Affärsproblem: InfoPath-formuläret har utformats kan användare ange online inköpsrekvisitioner. PO rekvisitionen nummer ska vara traditionella sekvens baserade heltalsvärden och beräknas automatiskt.

Affärslösning: Skapa en anpassad MOSS-lista som innehåller två kolumner: "ControlField" och "ControlValue". Värdekolumnen innehåller nästa inköpsrekvisition nummer. Observera att generiskt "kontroll" namnkonvention ger för framtida kontrollfält som kan användas som behövs.

Teknisk lösning: Skapa en webbtjänst som InfoPath klient tillgång. Webbtjänsten returnerar tillbaka nästa inköpsrekvisition och uppdateras värdet i listan.

Lärdomar:

  • När du lägger till denna webbtjänst som en datakälla i InfoPath-formuläret, Jag fann det nödvändigt att konvertera den till en udc och lagra det i ett dataanslutningsbibliotek.
  • Jag också funnit det nödvändigt att skriptstöd cross-domän via centrala tjänster administration // programhantering // formuläret konfiguration.
  • Första gången form försökte få tillgång till webbtjänsten, Det tar ett tag och ibland, Det skulle vara tid. Fingrade jag med inställningar i formuläret konfiguration att expandera timeout-inställningar och som verkade för att hjälpa.

Koden:

med hjälp av System;
med hjälp av System.Web;
med hjälp av System.Web.Services;
med hjälp av System.Web.Services.Protocols;
med hjälp av Microsoft.SharePoint;
med hjälp av System.Configuration;

[WebService(Namespace = "http://www.conchango.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
offentliga klass PoService : System.Web.Services.WebService
{
offentliga PoService () {

//Avkommentera följande rad om du använder komponenter för
//InitializeComponent();
}

/// <Sammanfattning>
/// Få nästa PO nummer från sharepoint po kontroll listan.
/// Öka antalet PO i listan.
/// </Sammanfattning>
/// <Returnerar></Returnerar>
[WebMethod]
offentliga sträng GetNextPoNumber()
{
sträng SpPoControlSiteName; // Namnet på den faktiska MOSS webbplats som är värd för IO-kontroll listan.
sträng SpPoControlListName; // Namnet på den faktiska MOSS lista som innehåller kontrollen Po.

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

sträng nextPoReqNumber = "xyzzy";

med hjälp av (SPSite plats = nya SPSite(SpPoControlSiteName))
{
med hjälp av (SPWeb Web = webbplats. OpenWeb())
{

SPList currentList = web. Listor[SpPoControlListName];

foreach (SPItem controlItem i currentList.Items)
{

om (((sträng)controlItem["ControlField"]).Är lika med("NextPoNumber"))
{
nextPoReqNumber = (sträng)controlItem["ControlValue"];

int int_nextPoReqNumber;
int_nextPoReqNumber = Konvertera.ToInt32(nextPoReqNumber);

int_nextPoReqNumber ;

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

} // Att lokalisera, läsa och uppdatera PO numret i listan.


} // med hjälp av spweb web = site.openweb()
} // webbplatsen för spsite = nya spsite("http://localhost/mizuho")

återvändande nextPoReqNumber;

}
}