MOSS / InfoPath Forms Server (InfoPath 2007) rullelisten ydeevne

Ekstra kategori: InfoPath

Resumé: En InfoPath 2007 form indsat til en server, MOSS giver en drop-down listen af leverandører er bundet til en brugerdefineret liste, der mos. Ved valg af leverandør, regler tildeler feltværdier til en håndfuld tekstfelter som salgsrep navn, adresse, City, staten, zip og telefon. Performance er forfærdeligt. Vi bemærker, at ydeevnen bliver værre (i en ikke-lineær mode) for hver yderligere felt opdatere vi denne måde. Dvs., Hvis vi bare opdatere navnet salg rep, det tager [x] mængden af tid. Hvis vi opdatere salg rep, Address1, Adresse2, City, staten, zip, det tager 10 gange længere.

Løsning: Skrive en webservice (eksempelkode kan findes Her) der er gået i en kreditor og det returnerer tilbage kreditor detaljer. Derefter, knytte felterne på denne måde. Selv om dette også virker langsom, der var ingen mærkbar forskel i ydelse, når vi tildelt 1 feltet versus 8 felter. Som en ekstra bonus, brugere får en cool "kontakter serveren" Cylon effekt, mens de venter på formen at påberåbe sig og forbruge service resultater.

MOSS: Der opstod en undtagelse. (Undtagelse fra HRESULT: 0x 80020009 (DISP_E_EXCEPTION))

OPDATERING: Vi fastslået aldrig årsag til dette problem, og det aldrig overflade igen.

Vi bemærker under gennemførelsen af et udvikling websted så pludselig, to brugere kan ikke få adgang en webstedssamling. Disse konti kan godkende til det vigtigste websted, Men når du forsøger at få adgang til en bestemt gruppe af websteder, de får bare en blank skærm. Nogen fejl, vises, bare en hvid tom side.

Vi log på som et websted samling admin og forsøge at tilføje en af disse brugere som et websted admin og denne gang, ved at trykke på "OK", Vi får denne meddelelse:

Der opstod en undtagelse. (Undtagelse fra HRESULT: 0x 80020009 (DISP_E_EXCEPTION))

Vi brugt tid på at forske dette og desværre, ikke komme med noget nyttigt. Der var nogle meddelelser i den diagnosticeringslogfil, men det var svært at nøjagtigt korrelere dem med dette problem.

I sidste ende, Vi gruppen af websteder slettes og genoprettes og at løst det.

Hvis jeg regne ud, skyldes hvad dette i fremtiden, Jeg opdaterer denne post.

MOSS: Iterere gennem brugerdefinerede lister og returnere filtrerede data til InfoPath

Forretningsscenario:

Levere en metode, der gør det muligt for brugere at angive præcise indkøbsrekvisitioner hurtigt.

Business problem:

Klienten gør forretning med flere hundrede leverandører.

Sælgere er "type" specifikke. Det betyder, at en leverandør sælger edb-udstyr (strømsparetilstand. Dell) eller kontorartikler (strømsparetilstand. Hæfteklammer).

Hvordan vi aktiverer slutbrugerne, der skaber Køb pålæg Vælg en gyldig leverandør?

Business løsning:

Differentiere leverandører i systemet via "type".

Give brugerne mulighed at vælge typen"" af produkt og derefter give et filtreret sæt af relevante leverandører.

Tekniske løsning:

En InfoPath-formular er udformet, kan brugere angive online indkøbsrekvisitioner.

To InfoPath valglister styre leverandør udvælgelse. Første, brugeren vælger typen"køb". Dette begrænser en anden valglisten indeholder kun sælgere, der sælger for den pågældende køb. Dette er en klassisk overlappende drop-down.

Sælgere er gemt i en Mos brugerdefineret liste med brugerdefinerede kolonner for kreditor attributter som navn, adresse og især "type".

Gennemføre en webservice til en InfoPath-klienten til at forbruge, gennemløber listen Brugerdefineret kreditorer, returnerer kun leverandører matchende en medfølgende "type".

Påberåbe sig web service via InfoPath-formularen.

Indhøstede erfaringer:

  • Første, Det synes nødvendigt at gå denne rute. Jeg ville have foretrukket at gøre filtrering helt inden for InfoPath og ikke oprette hvilken som helst web service funktioner her. Dog, Forms server giver ikke den nødvendige filterfunktion. Vi kan sætte en regel på et "type" valglisten i formen slags åbne forespørgslen leverandør, men vi kan ikke få det til at virke ordentligt. Derfor, Det var nødvendigt at gennemføre webtjenesten.
  • Dette er en klassisk "overlappende selection list" problemet i InfoPath danner server verden og der er mange gode eksempler derude, der forklarer hvordan man kan løse dette.
  • En tom værdi for en kolonne i listen over kreditorer returnerer ikke en tom streng, når der refereres til som dette: initItem["Kreditornavnet"]. I stedet, den returnerer en null-værdi.

Nogle andre noter:

  • Jeg returnere et array[] af leverandører, fordi jeg havde nogle svært ved at vende tilbage en ArrayList. InfoPath klagede over det og jeg har ikke tid eller lyst til at kæmpe over det.. Dette, Selvfølgelig, sætter en kunstig grænse på det samlede antal af leverandører. Det også tvunget mig til at gennemføre en trim() metoden på matrixen fordi jeg hader tanken om at vende tilbage tilbage 100's af null leverandører. InfoPath er ligeglad, men det nagged på mig. (Igen, Det var nemmere end at kæmpe InfoPath over ArrayLists).
  • Jeg har gennemført en GetSpecificVendorByName() funktion samt, der kan være lærerigt.

Koden:

ved hjælp af System;
ved hjælp af Sektionsgruppen;
ved hjælp af System.Web.Services;
ved hjælp af System.Web.Services.Protocols;
ved hjælp af Microsoft.SharePoint;
ved hjælp af System.Configuration;

/// <Resumé>
///
Kreditor Service: Giver kreditor relaterede tjenester, som i dag forbruges af en infopath-formular, klient.
///
/// Historie:
/// ——–
/// 07/24/07: Indledende kodning, Paul J. Gavin af Conchango.
///
/// </Resumé>
[WebService(Namespace = "http://www.conchango.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
offentlige klasse VendorService : System.Web.Services.WebService
{

/// <Resumé>
/// Repræsenterer en kreditor fra en custom sharepoint liste vedligeholdes af MSUSA.
/// </Resumé>
offentlige klasse Kreditor
{
offentlige Kreditor() { }

offentlige Kreditor(SPItem initItem)
{
Hvis (! (initItem["Kreditornavnet"] == Null)) Producentnavn = initItem["Kreditornavnet"].ToString();
Hvis (! (initItem["Løse 1"] == Null)) VendorAddress1 = initItem["Løse 1"].ToString();
Hvis (! (initItem["Adresse 2"] == Null)) VendorAddress2 = initItem["Adresse 2"].ToString();
Hvis (! (initItem["City"] == Null)) VendorCity = initItem["City"].ToString();
Hvis (! (initItem["VendorPhone"] == Null)) VendorPhone = initItem["VendorPhone"].ToString();
Hvis (! (initItem["PurchaseType"] == Null)) VendorType = initItem["PurchaseType"].ToString();
Hvis (! (initItem["Staten"] == Null)) VendorState = initItem["Staten"].ToString();
Hvis (! (initItem["Zip"] == Null)) VendorZip = initItem["Zip"].ToString();
Hvis (!(initItem["Fax"] == Null)) VendorFax = initItem["Fax"].ToString();
Hvis (!(initItem["SalesRepName"] == Null)) VendorSalesRepName = initItem["SalesRepName"].ToString();

VendorItemId = initItem.ID; // Unikke ID opretholdes via MOSS.
}

offentlige int VendorItemId;
offentlige streng Producentnavn;
offentlige streng VendorAddress1;
offentlige streng VendorAddress2;
offentlige streng VendorCity;
offentlige streng VendorState;
offentlige streng VendorZip;
offentlige streng VendorPhone;
offentlige streng VendorType;
offentlige streng VendorSalesRepName;
offentlige streng VendorFax;
}

offentlige VendorService () {

//Ualmindelig den følgende linje hvis bruger designede komponenter
//InitializeComponent();
}

privat Kreditor[] GenerateTestVendors()
{
Kreditor[] resultList;
resultList = nye Kreditor[100];

Kreditor v;
v = nye Kreditor();
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 = nye Kreditor();

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 = nye Kreditor();
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;

tilbagevenden resultList;

}

[WebMethod]
offentlige Kreditor GetSpecificVendorById(int vendorId)
{
streng SpVendorSiteName; // Navnet på den faktiske MOSS websted, der hoster brugerdefinerede kreditorliste.
streng SpVendorListName; // Navnet på den faktiske MOSS liste indeholdende leverandører.

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

ved hjælp af (SPSite site = nye SPSite(SpVendorSiteName))
{

ved hjælp af (SPWeb Web = site. OpenWeb())
{

SPList.Update() currentList = web. Lister[SpVendorListName];

SPItem specificItem = currentList.Items[vendorId];

tilbagevenden nye Kreditor(specificItem);

} // ved hjælp af spweb web = site.openweb()
} // ved hjælp af spsite site = ny spsite("http://localhost/mizuho")

}

[WebMethod]
// Antager, at kreditornavnet er unik, fra et business perspektiv
offentlige Kreditor GetSpecificVendorByVendorName(streng være)
{
streng SpVendorSiteName; // Navnet på den faktiske MOSS websted, der hoster brugerdefinerede kreditorliste.
streng SpVendorListName; // Navnet på den faktiske MOSS liste indeholdende leverandører.

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

ved hjælp af (SPSite site = nye SPSite(SpVendorSiteName))
{
ved hjælp af (SPWeb Web = site. OpenWeb())
{

SPList.Update() currentList = web. Lister[SpVendorListName];

foreach (SPItem vendorItem i currentList.Items)
{
Hvis (vendorItem["Kreditornavnet"] == Null) «««;

Hvis (vendorItem["Kreditornavnet"].ToString().Er lig med(være))
tilbagevenden nye Kreditor(vendorItem);
}

Kreditor v = nye Kreditor();
v.VendorPhone = "blev ikke fundet: " + være;

tilbagevenden v;

tilbagevenden Null;

} // ved hjælp af spweb web = site.openweb()
} // ved hjælp af spsite site = ny spsite("http://localhost/mizuho")

} // metode

[WebMethod]
offentlige Kreditor[] GetVendorsOfType (streng filterType)
{

streng SpVendorSiteName; // Navnet på den faktiske MOSS websted, der hoster t
han sælger brugerdefineret liste.
streng SpVendorListName; // Navnet på den faktiske MOSS liste indeholdende leverandører.

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

Kreditor[] resultList;
int vendorIndex = 0;
resultList = nye Kreditor[1000];

// Initialisere listen med en venlig standardmeddelelse.
Kreditor v = nye Kreditor();
v.VendorName = "Skal du vælge en kreditortype til at udfylde denne liste.";
resultList[0] = v;

// Konvertere filteret til lavere tilfældet for lettere strengsammenligning senere.
filterType = filterType.ToLower();

// Hvis filtertypen bestået er "test", generere nogle simple data.
#regionen Filtrer type = "test"
Hvis (filterType. er lig med("test"))
tilbagevenden GenerateTestVendors();
#endregion

Hvis (True)
{
ved hjælp af (SPSite site = nye SPSite(SpVendorSiteName))
{
ved hjælp af (SPWeb Web = site. OpenWeb())
{

v = Null;

SPList.Update() currentList = web. Lister[SpVendorListName];

// Iterere gennem alle elementerne på listen over kreditorer.
foreach (SPItem vendorItem i currentList.Items)
{

streng lowerVendorType;

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

Hvis (lowerVendorType. er lig med(filterType))
{
resultList[vendorIndex ] = nye Kreditor(vendorItem);
}
} // iterere gennem alle leverandører i listen


tilbagevenden TrimVendorArray(vendorIndex, resultList);
// tilbage resultList;

} // ved hjælp af spweb web = site.openweb()
} // ved hjælp af spsite site = ny spsite("http://localhost/mizuho")

} // Hvis det er sandt

tilbagevenden Null;
}

privat Kreditor[] TrimVendorArray(int newsize, Kreditor[] originalVendorArray)
{
Kreditor[] trimmedArray;

Hvis (newsize == 0) newsize = 1;
trimmedArray = nye Kreditor[newsize];

int currentCounter = 0;

for (currentCounter = 0; currentCounter < newsize; currentCounter )
{
trimmedArray[currentCounter] = originalVendorArray[currentCounter];
}

tilbagevenden trimmedArray;

}
}

MOSS: Bemærkninger om InfoPath debugging

InfoPath form server fejlmeddelelser er vildledende.

Under udviklingen af en InfoPath-formular, Jeg ville sende det til mos server og få adgang til formen. Formen vil begynde at indlæse og derefter generere en vildledende fejl besked peger mig til windows-hændelseslogfilen for detaljer. Faktisk, ingen besked blev skrevet til windows-hændelseslogfilen. Snarere, meddelelsen blev sendt til MOSS ascii diagnosticeringslogfil. Du kan opspore der via centrale services administration.

Du skal være hurtig på fødderne. MOS kan lide at skrive i logfilen, ofte og maksimalisme. Dette kan være trimmet men standard loggen skriver adfærd er "alt så hurtigt som muligt".

MOSS: Opdatering af en brugerdefineret liste

Der er mange gode eksempler på opdatere brugerdefinerede lister via SDK. Her er endnu en.

Business problem: InfoPath-formular er udformet, kan brugere angive online indkøbsrekvisitioner. PO rekvisition tal bør være traditionelle sekvens baseret heltalsværdier og beregnes automatisk.

Business løsning: Oprette en brugerdefineret MOSS liste med to kolonner: "ControlField" og "ControlValue". Kolonnen værdi indeholder den næste indkøb-rekvisitionsnummer. Bemærk, at generiske "kontrol" navngivningskonventionen giver for fremtidige kontrol felter, der kan anvendes efter behov.

Tekniske løsning: Oprette en webservice adgang til InfoPath-klienten. Webtjenesten returnerer tilbage den næste indkøb-rekvisitionsnummer og opdateres værdien for listen.

Indhøstede erfaringer:

  • Når du tilføjer denne webtjeneste som datakilde til InfoPath-formularen, Jeg fandt det nødvendigt at konvertere det til en udc og gemme det i et dataforbindelsesbibliotek.
  • Jeg har også fundet det nødvendigt at aktivere cross domain scripting via centrale services administration // programadministration // form serverkonfiguration.
  • Første gang formen forsøgt hen til adgang web service, det tager et stykke tid og lejlighed, Det ville timeout. Jeg pillede ved indstillingerne i form serverkonfiguration at udvide indstillingerne timeout og som syntes at hjælpe.

Koden:

ved hjælp af System;
ved hjælp af Sektionsgruppen;
ved hjælp af System.Web.Services;
ved hjælp af System.Web.Services.Protocols;
ved hjælp af Microsoft.SharePoint;
ved hjælp af System.Configuration;

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

//Ualmindelig den følgende linje hvis bruger designede komponenter
//InitializeComponent();
}

/// <Resumé>
/// Få den næste PO-nummer fra sharepoint po nummer kontrol liste.
/// Øg PO-nummer i denne liste.
/// </Resumé>
/// <Returnerer></Returnerer>
[WebMethod]
offentlige streng GetNextPoNumber()
{
streng SpPoControlSiteName; // Navnet på den faktiske MOSS websted, der hoster PO Control list.
streng SpPoControlListName; // Navnet på den faktiske MOSS liste der indeholder kontrolelementet Po.

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

streng nextPoReqNumber = "xyzzy";

ved hjælp af (SPSite site = nye SPSite(SpPoControlSiteName))
{
ved hjælp af (SPWeb Web = site. OpenWeb())
{

SPList.Update() currentList = web. Lister[SpPoControlListName];

foreach (SPItem controlItem i currentList.Items)
{

Hvis (((streng)controlItem["ControlField"]).Er lig med("NextPoNumber"))
{
nextPoReqNumber = (streng)controlItem["ControlValue"];

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

int_nextPoReqNumber ;

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

} // Lokalisering, læsning og ajourføring PO-nummer på listen.


} // ved hjælp af spweb web = site.openweb()
} // ved hjælp af spsite site = ny spsite("http://localhost/mizuho")

tilbagevenden nextPoReqNumber;

}
}