MUSCHIO / InfoPath Forms Server (InfoPath 2007) prestazioni di elenco a discesa

Categoria supplementare: InfoPath

Riassunto: Un InfoPath 2007 il modulo distribuito a un server MOSS fornisce un elenco a discesa dei fornitori legato a un elenco personalizzato di MOSS. Selezionando un fornitore, regole di assegnano valori di campo per una manciata di campi di testo, quali il nome del rappresentante, Indirizzo, città, stato, zip e telefono. Prestazioni sono orribile. Notiamo che prestazioni peggiora (in modo non lineare) per ogni ulteriore campo che aggiorniamo questo modo. Vale a dire, Se solo aggiornare il nome del rappresentante, ci vuole [x] quantità di tempo. Se aggiorniamo rappresentante vendite, Indirizzo1, Indirizzo2, città, stato, zip, ci vuole 10 volte di più.

Soluzione: Scrivere un servizio web (codice di esempio può essere trovato qui) che viene passato in nome di un venditore e restituisce indietro i dettagli del venditore. Poi, assegnare i campi in questo modo. Anche se questo sembra troppo lento, non ci era differenza percepibile in termini di prestazioni, quando abbiamo assegnato 1 Campo contro 8 campi. Come bonus aggiuntivo, gli utenti di ottenere un fresco "contattare il server" Cylon effetto mentre aspettano la forma a richiamare e consumare il servizio risultati.

MUSCHIO: Eccezione. (Eccezione da HRESULT: 0x 80020009 (DISP_E_EXCEPTION))

AGGIORNAMENTO: Abbiamo mai determinata la causa principale di questo problema e mai superficiale nuovamente.

Notiamo che improvvisamente durante l'implementazione di un sito di sviluppo, due utenti sono in grado di accedere a una raccolta di siti. Tali conti è in grado di autenticare il sito principale, ma quando si tenta di accedere all'insieme un particolare sito, Basta avere una schermata vuota. Nessun errore visualizzato, solo una pagina bianca vuota.

Ci accedere come admin di raccolta un sito e cercare di aggiungere uno di quegli utenti come un admin del sito e questa volta, su premere "OK", si ottiene questo messaggio:

Eccezione. (Eccezione da HRESULT: 0x 80020009 (DISP_E_EXCEPTION))

Abbiamo trascorso qualche tempo alla ricerca di questo e purtroppo, non è venuto con qualcosa di utile. Ci sono stati alcuni messaggi nel Registro di diagnostico, ma è stato duro per correlarli esattamente con questo problema.

Alla fine, abbiamo l'eliminazione della raccolta siti e ricreata e che risolto.

Se io a capire cosa ha causato questo in futuro, Aggiornerò questo post.

MUSCHIO: Scorrimento di elenchi personalizzati e la restituzione dei dati filtrati InfoPath

Scenario business:

Fornire un metodo che consente agli utenti di immettere rapidamente le richieste di acquisto accurato.

Problema aziendale:

Il cliente fa affari con diverse centinaia di venditori.

Fornitori sono di tipo"" specifiche. Questo significa che un fornitore vende attrezzatura informatica (e. g. Dell) o forniture per ufficio (e. g. Staples).

Come consentire agli utenti finali che creare acquisto requisizioni selezionare un fornitore valido?

Soluzione di business:

Differenziare i fornitori del sistema tramite il "tipo".

Consentire agli utenti di selezionare il tipo"" del prodotto e quindi fornire un set filtrato di venditori appropriati.

Soluzione tecnica:

È stato progettato un modulo di InfoPath che permette agli utenti di immettere on-line le richieste di acquisto.

Due elenchi di selezione InfoPath controllano la selezione del fornitore. Primo, l'utente seleziona un tipo di"acquisto". Questo limita un secondo elenco di selezione per contenere solo fornitori che vendono per quel tipo di acquisto. Si tratta di un classico CSS menu a discesa.

Fornitori sono memorizzati in un elenco personalizzato di muschio con colonne personalizzate per gli attributi di vendor come nome, indirizzo e soprattutto "tipo".

Implementare un servizio web per un client InfoPath a consumare che scorre l'elenco personalizzato fornitore, Tornando solo fornitori un "tipo" fornito di corrispondenza.

Richiamare il servizio web tramite il modulo di InfoPath.

Lezioni apprese:

  • Primo, sembra necessario andare questo itinerario. Avrei preferito fare il filtraggio interamente all'interno di InfoPath e non creare alcuna funzionalità di servizio web qui. Tuttavia, Form server non fornisce la necessaria capacità filtrante. Possiamo mettere una regola su un tipo"" lista di selezione sotto forma di sorta di riaprire la query vendor, ma noi non possiamo farlo funzionare correttamente. Pertanto, era necessario implementare il servizio web.
  • Questo è un classico "CSS selezione elenco" problema nel InfoPath forma mondo server e ci sono molti buoni esempi là fuori che spiegano come risolvere questo problema.
  • Un valore vuoto per una colonna nell'elenco fornitori non restituisce una stringa vuota quando fa riferimento a come questo: initItem["Nome del fornitore"]. Invece, Restituisce un valore null.

Alcune altre note:

  • Restituire una matrice[] di venditori perché ho avuto qualche difficoltà restituendo un ArrayList. InfoPath si lamentava e non ho avuto il tempo o l'inclinazione a combattere su di esso. Questo, Naturalmente, mette un limite artificiale al numero totale di fornitori. Esso costretto anche me a implementare un assetto() Metodo sull'array perché io odio l'idea di tornare indietro 100 di fornitori null. Non si cura di InfoPath, ma tormentava me. (Ancora una volta, Questo è stato più facile di combattimento InfoPath sopra ArrayLists).
  • Ho implementato un GetSpecificVendorByName() funzione pure, che può essere istruttivo.

Il codice:

utilizzando Sistema;
utilizzando System. Web;
utilizzando System.Web.Services;
utilizzando Protocols;
utilizzando Microsoft. SharePoint;
utilizzando System. Configuration;

/// <Riassunto>
///
Servizio fornitore: Fornisce il fornitore dei servizi che oggi sono consumati da un modulo di infopath client.
///
/// Storia:
/// ——–
/// 07/24/07: Iniziale di codifica, Paul J. Gavin di Conchango.
///
/// </Riassunto>
[WebService(Namespace = "http://www.Conchango.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
pubblica classe VendorService : System.Web.Services.WebService
{

/// <Riassunto>
/// Rappresenta un fornitore da un elenco sharepoint personalizzato gestito da e.
/// </Riassunto>
pubblica classe Fornitore
{
pubblica Fornitore() { }

pubblica Fornitore(SPItem initItem)
{
Se (! (initItem["Nome del fornitore"] == null)) VendorName = initItem["Nome del fornitore"].ToString();
Se (! (initItem["Indirizzo 1"] == null)) VendorAddress1 = initItem["Indirizzo 1"].ToString();
Se (! (initItem["Indirizzo 2"] == null)) VendorAddress2 = initItem["Indirizzo 2"].ToString();
Se (! (initItem["Città"] == null)) VendorCity = initItem["Città"].ToString();
Se (! (initItem["VendorPhone"] == null)) VendorPhone = initItem["VendorPhone"].ToString();
Se (! (initItem["PurchaseType"] == null)) VendorType = initItem["PurchaseType"].ToString();
Se (! (initItem["Stato"] == null)) VendorState = initItem["Stato"].ToString();
Se (! (initItem["Zip"] == null)) VendorZip = initItem["Zip"].ToString();
Se (!(initItem["Fax"] == null)) VendorFax = initItem["Fax"].ToString();
Se (!(initItem["SalesRepName"] == null)) VendorSalesRepName = initItem["SalesRepName"].ToString();

VendorItemId = initItem.ID; // ID univoco mantenuto via MOSS.
}

pubblica int VendorItemId;
pubblica stringa VendorName;
pubblica stringa VendorAddress1;
pubblica stringa VendorAddress2;
pubblica stringa VendorCity;
pubblica stringa VendorState;
pubblica stringa VendorZip;
pubblica stringa VendorPhone;
pubblica stringa VendorType;
pubblica stringa VendorSalesRepName;
pubblica stringa VendorFax;
}

pubblica VendorService () {

//Decommentare la seguente riga se utilizza componenti progettati
//InitializeComponent();
}

privato Fornitore[] GenerateTestVendors()
{
Fornitore[] Risultati;
Risultati = Nuovo Fornitore[100];

Fornitore v;
v = Nuovo Fornitore();
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";

Risultati[0] = v;

v = Nuovo Fornitore();

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

Risultati[1] = v;

v = Nuovo Fornitore();
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";

Risultati[2] = v;

ritorno Risultati;

}

[WebMethod]
pubblica Fornitore GetSpecificVendorById(int vendorId)
{
stringa SpVendorSiteName; // Nome del sito MOSS effettivo che ospita l'elenco personalizzato fornitore.
stringa SpVendorListName; // Nome dell'elenco effettivo MOSS contenente fornitori.

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

utilizzando (SPSite sito = Nuovo SPSite(SpVendorSiteName))
{

utilizzando (SPWeb Web = site. OpenWeb())
{

SPList currentList = web. Elenchi[SpVendorListName];

SPItem specificItem = currentList.Items[vendorId];

ritorno Nuovo Fornitore(specificItem);

} // utilizzando spweb web = site.openweb()
} // utilizzando il sito spsite = nuovo spsite("http://localhost/mizuho")

}

[WebMethod]
// Si presuppone che il nome del fornitore è unico, da una prospettiva di business
pubblica Fornitore GetSpecificVendorByVendorName(stringa essere)
{
stringa SpVendorSiteName; // Nome del sito MOSS effettivo che ospita l'elenco personalizzato fornitore.
stringa SpVendorListName; // Nome dell'elenco effettivo MOSS contenente fornitori.

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

utilizzando (SPSite sito = Nuovo SPSite(SpVendorSiteName))
{
utilizzando (SPWeb Web = site. OpenWeb())
{

SPList currentList = web. Elenchi[SpVendorListName];

foreach (SPItem vendorItem in currentList.Items)
{
Se (vendorItem["Nome del fornitore"] == null) continuare;

Se (vendorItem["Nome del fornitore"].ToString().È uguale a(essere))
ritorno Nuovo Fornitore(vendorItem);
}

Fornitore v = Nuovo Fornitore();
v.VendorPhone = "non trovato: " + essere;

ritorno v;

ritorno null;

} // utilizzando spweb web = site.openweb()
} // utilizzando il sito spsite = nuovo spsite("http://localhost/mizuho")

} // Metodo.

[WebMethod]
pubblica Fornitore[] GetVendorsOfType (stringa filterType)
{

stringa SpVendorSiteName; // Nome del sito MOSS effettivo che ospita t
elenco personalizzato di lui fornitore.
stringa SpVendorListName; // Nome dell'elenco effettivo MOSS contenente fornitori.

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

Fornitore[] Risultati;
int vendorIndex = 0;
Risultati = Nuovo Fornitore[1000];

// Inizializzare l'elenco con un messaggio predefinito.
Fornitore v = Nuovo Fornitore();
v.VendorName = "Selezionare un tipo di fornitore per compilare questa lista.";
Risultati[0] = v;

// Convertire il filtro in lettere minuscole per più facile confronto di stringhe più tardi.
filterType = filterType.ToLower();

// Se il tipo di filtro passato è "test", generare alcuni semplici dati.
#regione Tipo di filtro = "test"
Se (filterType. Equals("prova"))
ritorno GenerateTestVendors();
#endregion

Se (true)
{
utilizzando (SPSite sito = Nuovo SPSite(SpVendorSiteName))
{
utilizzando (SPWeb Web = site. OpenWeb())
{

v = null;

SPList currentList = web. Elenchi[SpVendorListName];

// Scorrere tutti gli elementi nell'elenco Fornitore.
foreach (SPItem vendorItem in currentList.Items)
{

stringa lowerVendorType;

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

Se (lowerVendorType. Equals(filterType))
{
Risultati[vendorIndex ] = Nuovo Fornitore(vendorItem);
}
} // l'iterazione attraverso tutti i fornitori in elenco


ritorno TrimVendorArray(vendorIndex, Risultati);
// restituire risultati;

} // utilizzando spweb web = site.openweb()
} // utilizzando il sito spsite = nuovo spsite("http://localhost/mizuho")

} // Se true

ritorno null;
}

privato Fornitore[] TrimVendorArray(int newSize, Fornitore[] originalVendorArray)
{
Fornitore[] trimmedArray;

Se (newSize = = 0) newSize = 1;
trimmedArray = Nuovo Fornitore[newSize];

int currentCounter = 0;

per (currentCounter = 0; currentCounter < newSize; currentCounter )
{
trimmedArray[currentCounter] = originalVendorArray[currentCounter];
}

ritorno trimmedArray;

}
}

MUSCHIO: Osservazioni sul debug di InfoPath

Messaggi di errore di InfoPath form server sono fuorvianti.

Durante lo sviluppo di un modulo di InfoPath, Vorrei postarlo per server MOSS e accedere al modulo. La forma avrebbe cominciato a caricare e quindi generare un messaggio di errore fuorviante indicando me nel registro eventi di windows per i dettagli. Infatti, nessun messaggio è stato scritto nel registro eventi di windows. Piuttosto, il messaggio è stato inviato il log diagnostico MOSS ascii. Che può rintracciare tramite Amministrazione centrale servizi.

Devi essere veloce in piedi. MOSS piace scrivere nel file di log, frequentemente e prolissa. Questo può essere tagliato, ma il registro predefinito scrivendo il comportamento è "tutto il più velocemente possibile".

MUSCHIO: L'aggiornamento di un elenco personalizzato

Ci sono molti buoni esempi di aggiornamento elenchi personalizzati tramite il SDK. Qui è ancora un altro.

Problema aziendale: Modulo di InfoPath è stato progettato che permette agli utenti di immettere online acquistano requisizioni. Requisizione PO numeri dovrebbero essere la sequenza tradizionale basato su valori integer e calcolati automaticamente.

Soluzione di business: Creare un elenco personalizzato di MOSS contenente due colonne: "ControlField" e "ControlValue". Colonna valore contiene il numero della richiesta di acquisto successivo. Si noti che il generico "controllo" Convenzione di denominazione fornisce i campi di controllo futuro che possono essere utilizzati come necessario.

Soluzione tecnica: Creare un servizio web accessibile dal client InfoPath. Il servizio web restituisce indietro il successivo numero della richiesta di acquisto e aggiorna il valore della lista.

Lezioni apprese:

  • Quando si aggiunge questo servizio web come origine dati per il modulo di InfoPath, Ritenuto necessario convertirlo in un udc e memorizzarlo in una raccolta connessioni dati.
  • Anche trovato necessario attivare tra domini scripting tramite Amministrazione centrale servizi // gestione applicazioni // configurazione del server di forma.
  • La prima volta il modulo provato ad accedere al servizio web, ci vuole un po' di tempo e in occasione, sarebbe tempo fuori. I giocherellava con le impostazioni nella configurazione del server di forma per espandere le impostazioni di timeout e che sembrava di aiutare.

Il codice:

utilizzando Sistema;
utilizzando System. Web;
utilizzando System.Web.Services;
utilizzando Protocols;
utilizzando Microsoft. SharePoint;
utilizzando System. Configuration;

[WebService(Namespace = "http://www.Conchango.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
pubblica classe PoService : System.Web.Services.WebService
{
pubblica PoService () {

//Decommentare la seguente riga se utilizza componenti progettati
//InitializeComponent();
}

/// <Riassunto>
/// Ottenere il numero di PO successivo dall'elenco sharepoint po numero controllo.
/// Incrementare il numero di PO in quella lista.
/// </Riassunto>
/// <restituisce></restituisce>
[WebMethod]
pubblica stringa GetNextPoNumber()
{
stringa SpPoControlSiteName; // Nome del sito MOSS effettivo che ospita l'elenco di controllo di PO.
stringa SpPoControlListName; // Nome dell'elenco effettivo di MOSS che contiene il controllo di Po.

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

stringa nextPoReqNumber = "xyzzy";

utilizzando (SPSite sito = Nuovo SPSite(SpPoControlSiteName))
{
utilizzando (SPWeb Web = site. OpenWeb())
{

SPList currentList = web. Elenchi[SpPoControlListName];

foreach (SPItem controlItem in currentList.Items)
{

Se (((stringa)controlItem["ControlField"]).È uguale a("NextPoNumber"))
{
nextPoReqNumber = (stringa)controlItem["ControlValue"];

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

int_nextPoReqNumber ;

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

} // Individuazione, lettura e l'aggiornamento il numero di PO nell'elenco.


} // utilizzando spweb web = site.openweb()
} // utilizzando il sito spsite = nuovo spsite("http://localhost/mizuho")

ritorno nextPoReqNumber;

}
}