XSLT è molto comodo per la creazione di documenti in qualsiasi formato partendo da un documento XML. Alcune difficoltà si presentano quando all'interno dell'output della trasformazione vogliamo inserire dei server control con i relativi eventi.
Grazie al method "ParseControl" della classe Page, possiamo inserire nella nostra pagina dinamicamente i tag per i controlli.
Nell'esempio allegato a questo script è presente un file XML con questa struttura:
<?xml version="1.0" encoding="utf-8" ?> <controls> <textbox required="true" name="name" description="Name" /> <textbox required="true" name="surname" description="Surame" /> <radiobuttonlist name="sex" description="Sex"> <select>Male</select> <select>Female</select> </radiobuttonlist> <dropdownlist name="age" description="Age"> <select>Under 18</select> <select>18-35</select> <select>35-60</select> <select>Over 60</select> </dropdownlist> </controls>
Ho creato dei tag personalizzati per l'inserimento automatico di TextBox (con l'opzionale controllo RequiredFieldControl), DropDownList e RadioButtonList.
Grazie al file di trasformazione allegato possiamo creare la nostra pagina con i relativi controlli in modo completamente dinamico. Questo codice in C# inserisce il codice prodotto dalla trasformazione all'interno di un controllo PlaceHolder:
XslCompiledTransform transform = new XslCompiledTransform(); transform.Load(Server.MapPath("CreateControlsx.xslt")); XmlWriterSettings ws = transform.OutputSettings.Clone(); ws.CheckCharacters = false; StringWriter stw = new StringWriter(); XmlWriter sw = XmlWriter.Create(stw, ws); transform.Transform(Server.MapPath("ObjectFormx.xml"), sw); string result = stw.ToString(); result = result.Replace("xmlns:asp=\"remove\"", ""); Control ctrl = Page.ParseControl(result); ph1.Controls.Add(ctrl);
Uno dei primi problemi che dobbiamo affrontare è l'impossibilità di inserire direttamente nel file XSLT l'eventuale codice per collegare i controlli ai rispettivi eventi, come, in questo caso, il click sul Button.
Per ovviare a questo, subito dopo l'inserimento nel codice della pagina, ci è sufficiente esaminare tutti i controlli inseriti alla ricerca del nostro button, e solo in quel momento aggiungere l'evento:
foreach (Control c in ph1.Controls[0].Controls) { Button b = c as Button; if (b == null) continue; b.Click += clickeda; } protected void clickeda(object o, EventArgs e) { ProcessForm(); }
Ora che abbiamo risolto il problema dell'inserimento da XSLT dei controlli e la gestione degli eventi, rimane un ultimo problema, l'accesso ai dati dal form visualizzato all'utente. Questo è possibile con questo codice:
private void ProcessForm() { StringBuilder sb=new StringBuilder(); XElement doc = XElement.Load(Request.MapPath("ObjectFormx.xml")); IEnumerable<XElement> controls = doc.Elements(); foreach (XElement x in controls) { string item = x.Attribute("name").Value; object ctrl = FindControl(item); if (ctrl is TextBox) { sb.Append("TextBox '"); sb.Append(item); sb.Append("' value= '"); sb.Append(((TextBox)ctrl).Text); sb.Append("'<br />"); } ... } msg.Text = sb.ToString(); }
Così come abbiamo inserito i controlli, possiamo leggerne la struttura e con il metodo FindControl cercare i controlli appena inseriti.
Vale ovviare la stessa considerazione che si fa quando si inserisce un controllo dinamicamente da codice: anche in questo caso è necessario ricreare tutti i controlli nell'evento "Page_Init" della nostra pagina.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Cache policy su route groups di Minimal API in ASP.NET Core 7
Usare ASP.NET Core dev tunnels per testare le applicazioni su internet
Effettuare il deploy di immagini solo da container registry approvati in Kubernetes
Personalizzare l'errore del rate limiting middleware in ASP.NET Core
Load test di ASP.NET Core con k6
Implementare il throttling in ASP.NET Core
Short-circuiting della Pipeline in ASP.NET Core