420 messaggi dal 23 marzo 2010
Contributi
Ciao a tutti, ho il seguente problema. Nel mio scenario sto sviluppando dei template utilizzando il RazorEngine https://github.com/Antaris/RazorEngine

Quello che voglio ottenere é creare delle view razor a runtime, magari salvando la path, titolo e altri campi su database e fare in modo che sia utilizzabile come template.

Esempio: Sono nella pagina crea template cliente, inserisco nome della pagina, path e descrizione e quando premo crea viene generata una view razor popolata con determinati @Model.Name, @Model,Surname perchè fa riferimento ad un determinato model. Non so se questo sia possibile

In aggiunta ho un'altro problema. La modifica del template. Questo é un problema separato dalla fase di creazione che ho spiegato prima.

Se ipoteticamente con il razorengine renderizzo una view razor e volessi ipoteticamente cambiare il nome di un campo che non faccia parte di @Model, come potrei fare? Grazie

Per ora ho trovato questi due riferimenti

http://www.west-wind.com/weblog/posts/2012/May/30/Rendering-ASPNET-MVC-Views-to-String

questo non riesco a farlo funzionare

http://www.west-wind.com/weblog/posts/2013/Jul/15/Rendering-ASPNET-MVC-Razor-Views-outside-of-MVC-revisited
11.862 messaggi dal 09 febbraio 2002
Contributi
Ciao Mirko,


quando premo crea viene generata una view razor popolata con determinati @Model.Name, @Model,Surname perchè fa riferimento ad un determinato model. Non so se questo sia possibile

Beh, sì, usando la reflection puoi estrarti l'elenco di tutte le proprietà pubbliche del tipo che hai scelto (es. Cliente) ed usare i loro nomi per generarti la view.

Tuttavia, come mai vuoi crearla automaticamente? Io mi immagino un editor WYSIWYG in cui l'utente sia libero di creare il suo contenuto HTML e poi, da una DropDownList, possa selezionare e aggiungere nell'editor i soli campi dinamici di cui ha bisogno.

Al salvataggio, raccogli il valore stringa dell'editor e lo salvi nel DB (o su un file di testo, se preferisci).


volessi ipoteticamente cambiare il nome di un campo che non faccia parte di @Model, come potrei fare?

Fai un esempio. Una view dovrebbe solo limitarsi a presentare il model che le viene fornito e non dovrebbe conoscere altro. Se ti servono dei campi accessori, allora non passargli direttamente un oggetto di tipo Cliente ma magari un DTO o qualche altro tipo che, ad esempio, deriva da Cliente e che espone delle proprietà aggiuntive.


Per ora ho trovato questi due riferimenti

Penso che non ti servano perché, dato che stai usando il progetto di Antaris, renderizzare un template Razor è molto semplice:
//questa è la stringa che hai ottenuto dal database o dal file di testo su cui l'avevi salvata
string template = "Hello @Model.Name, welcome to RazorEngine!";
//renderizzi il template fornendogli un oggetto come Model.
string result = Razor.Parse(template, new { Name = "World" });
//poi usi la stringa result per produrre un documento o come corpo di un'email (ad esempio).


ciao,
Moreno
Modificato da BrightSoul il 27 ottobre 2013 22.47 -

Enjoy learning and just keep making
420 messaggi dal 23 marzo 2010
Contributi
Tuttavia, come mai vuoi crearla automaticamente? Io mi immagino un editor WYSIWYG in cui l'utente sia libero di creare il suo contenuto HTML e poi, da una DropDownList, possa selezionare e aggiungere nell'editor i soli campi dinamici di cui ha bisogno.

Al salvataggio, raccogli il valore stringa dell'editor e lo salvi nel DB (o su un file di testo, se preferisci).


Non ho capito il passaggio della dropdownlist. Ipoteticamente l'utente se seleziona dalla selectlist un modello Studente e poi come fa a generare del contenuto automatico? (Metti caso che ci sia un modello studente e un modello professore con campi differenti)

La creazione della view, comunque, spetterebbe al razor engine, giusto?

Per quanto riguarda i dto, non ho mai provato ad utilizzarli, ma provo a fare un esempio concreto

    public class Studente
    {
        [Key]
        public int ID { get; set; }

        [Required]
        public string Nome { get; set; }

        [Required]
        public string Cognome { get; set; }
    }


Io ho la necessità di editare i nomi di queste proprietà, ma qui non potrei farlo perchè su db hanno questo nome. Di conseguenza risolverei usando il modello sotto? grazie

    public class StudenteDTO : Studente
    {
        public int ID { get; set; }

        public string Nome { get; set; }

        public string Cognome { get; set; }
    }

Modificato da Mirko Pastorelli il 27 ottobre 2013 23.04 -
Modificato da Mirko Pastorelli il 27 ottobre 2013 23.05 -
11.862 messaggi dal 09 febbraio 2002
Contributi
ciao Mirko,

Mirko Pastorelli ha scritto:

come fa a generare del contenuto automatico?

spiega cosa deve fare l'applicazione, non mi è chiaro cosa intendi con "contenuto automatico".

Dunque, abbiamo detto che l'utente (es. il segretario di una scuola) va a selezionare "Studente" come Model perché deve inviare una lettera a tutti gli studenti. Dunque gli si presenta una casella di testo in cui comincerà a digitare:
Gentile @Model.Name @Model.Surname,
ti informiamo che entro il 13/12 dovrai presentare la documentazione ...



Non ho capito il passaggio della dropdownlist

I campi @Model.Name e @Model.Surname, anziché digitarli, potrebbe anche prenderli da un menu a tendina apposito, che si è popolato dopo la scelta del tipo "Studente".

Se avesse scelto "Professore", si sarebbero resi disponibili dei campi diversi.

A questo punto l'utente clicca il bottone Salva e il template viene persistito o nel database o su un file di testo. In seguito avvierà la procedura che gli permette di stampare un foglio (o inviare una mail) per ogni studente.


La creazione della view, comunque, spetterebbe al razor engine, giusto?

Sì, anche se userei questa terminologia: l'engine si occupa di renderizzare il Template, cioè di unirlo al Model per produrre una stringa. In questo caso non possiamo parlare di View perché non siamo all'interno del pattern MVC. L'engine è un servizio fine a sé stesso.


Io ho la necessità di editare i nomi di queste proprietà, ma qui non potrei farlo perchè su db hanno questo nome.

Ok, se stai usando Entity Framework (o altro ORM) puoi dare un nome diverso alle proprietà della classe Studente. Grazie al mapping, non sei costretto a rispettare i nomi dei campi del database.

Comunque, se non puoi modificare la classe Studente, crea uno StudenteDTO (non farlo derivare da Studente) e creare in esso delle proprietà con nomi diversi. A quel punto puoi fare o una proiezione mentre fai la tua query Linq oppure usare Automapper per convertire gli oggetti già residenti in memoria da un tipo all'altro.

ciao,
Moreno

Enjoy learning and just keep making
420 messaggi dal 23 marzo 2010
Contributi
Fondamentalmente é così. Lo studente compila una form e la salva.

Lui può vedere il template della sua form compilata(attraverso il razor engine) e fin qui non ci sono problemi

Il problema si crea quando, per esempio, da back-end voglio modificare il nome della proprietà. Esempio

NOME: TEXTBOX

Io ho la necessità di modificare l'html contenuto in nome e non posso di conseguenza usare le labelfor perchè sarebbe stronglytyped e andrebbe a modificare il nome del campo nel database.

Oltretutto, la modifica di quella proprietà, deve riflettersi nel template generato, quindi se prima nel template avevo

Nome: Pallino

e io vado a modificare la proprietà, nella pagina di compilazione della form invece di NOME potrei metterci NOME2 e di conseguenza anche nel template dovrà essere scritto NOME2: PALLINO

Questo sinceramente non so come farlo, finchè si tratta di semplice html in una pagina sola si può fare, quando deve riflettere sia nella view create che nel template non so come intervenire.

Creazione

Questo é un'altro problema: Dovrei fare in modo che l'utente crei un template razor semplicemente inserendo questi dati

Titolo pagina : tag title

path : il nome che verrà visualizzato nell'URL

Model: questo permetterebbe di decidere a quale model deve fare riferimento il template. Se selezionassi studente da una dropdownlist, nel template renderizzato dovrei vedere @model.nome, model.cognome ecc, se invece selezionassi cliente la pagina si popolerebbe con @model.ragionesociale ecc.


per quanto riguarda l'html della pagina potrei lasciarlo perdere per adesso, prima devo capire se è fattibile fare questa cosa.


Questi tre campi sarebbe preferibile salvarli su db, in modo da persisterli da qualche parte.

Il succo del discorso é che per ora non ho trovato una soluzione ad entrambi i problemi. Per la prima parte mi hai consigliato di utilizzare un dto, ma al momento non saprei come implementarlo, anche in un progetto di prova. Mentre per quanto riguarda la creazione del template sono proprio al buio, non ho idea se é fattibile come cosa. Grazie comunque.
Modificato da Mirko Pastorelli il 30 ottobre 2013 01.27 -
11.862 messaggi dal 09 febbraio 2002
Contributi
ciao Mirko,
cerchiamo di capire se è realmente necessario modificare i nomi delle proprietà. La tua esigenza è questa:

Nome: Pallino
nel template dovrà essere scritto NOME2: PALLINO

Ok, dunque hai bisogno che l'etichetta sia diversa, cioè il testo che si trova di fianco al campo. Il nome della proprietà può anche restare identico, il che sarebbe un vantaggio perché potresti riutilizzare i tipi Stutende e Cliente che hai già.


non posso di conseguenza usare le labelfor perchè sarebbe stronglytyped

Non sei obbligato ad usare LabelFor. Quando generi il form avrai cura di inserire questo esatto codice HTML per il campo Nome:

<input type="text" id="Nome" name="Nome" value="@Model.Nome" />

(Non ho usato alcun helper di MVC).

Mentre per l'etichetta scriverai
<label for="Nome">Nome2</label>


L'utente, nella sua form, non vedrà mai apparire il testo "Nome", perché l'abbiamo usato in punti non visibili, cioè come attributo for, come attributi id della textbox, e come token nell'attributo value.

Ciò che vedrà, invece, è Nome2 perché questo è il testo della label.

Se usi il template come View di MVC, alle sue spalle potrà esserci una stessa Action tipo questa
[HttpPost]
public ActionResult Invia(Studente studente){
  ...
}

...e questa andrà bene per il template generato per qualsiasi utente, perché ricorda che abbiamo modificato solo il testo visualizzato (Nome2 anziché Nome) e non i nomi delle proprietà.

Non resta che determinate con quale criterio dovrà apparire Nome2 anziché Nome.
Puoi crearti un dizionario per tradurre Nome in Nome2, oppure puoi conservare questa traduzione nel database, il che sarebbe utile se le etichette devono essere personalizzate da utente ad utente. Oppure puoi lasciare che sia l'utente stesso a modificarsi quei testi.
Oppure ancora puoi inserire i nomi delle label su un attributo Description che poni sopra la proprietà stessa.
    public class Studente
    {

        [Required, Description("Nome2")]
        public string Nome { get; set; }

    }


pensi che possa funzionare? In questo modo non dovrai crearti DTO o altro.

ciao,
Moreno
Modificato da BrightSoul il 30 ottobre 2013 08.32 -

Enjoy learning and just keep making
420 messaggi dal 23 marzo 2010
Contributi
BrightSoul ha scritto:

Puoi crearti un dizionario per tradurre Nome in Nome2, oppure puoi conservare questa traduzione nel database, il che sarebbe utile se le etichette devono essere personalizzate da utente ad utente. Oppure puoi lasciare che sia l'utente stesso a modificarsi quei testi.
Oppure ancora puoi inserire i nomi delle label su un attributo Description che poni sopra la proprietà stessa.
    public class Studente
    {

        [Required, Description("Nome2")]
        public string Nome { get; set; }

    }


pensi che possa funzionare? In questo modo non dovrai crearti DTO o altro.

ciao,
Moreno
Modificato da BrightSoul il 30 ottobre 2013 08.32 -


ciao Moreno

In effetti sarebbe preferibile che l'utente possa modificarsi queste etichette da solo, con l'attribuito description non funzionerebbe perchè non riuscirei a modificarlo a runtime (cioè da una maschera edit, per esempio). Le etichette cambieranno in base ai template, quindi se sto utilizzando quello degli studenti, sono sicuro che le modifiche che sto facendo a quelle etichette si rifletterà su tutti i template di tipo studente.

Se domani ne aggiungo uno di tipo professore, avrà altre etichette e la loro modifica si rifletterà su tutti i template di quel tipo.

L'utente deve modificare l'html della pagina oltre alle label (testo in grassetto in corsivo e quant'altro) e sto valutando l'utilizzo di editor come tinyMCE nella mia applicazione.

Ora, ho solo questa possibilità in mente ed è la seguente:

Creare una tabella Template, con questi campi:

Titolo: Il title della pagina

Path: Il percorso della pagina

EtichettaNomeCampo: Questo campo verrà ripetuto per tutte le etichette di quel template.

ContenutoHTML: L'html della pagina.

Persistendo tutto su database ipoteticamente risolverei il problema di creazione e di modifica. Potrebbero esistere soluzioni migliori? L'unica cosa della quale ho paura sono le performace, attualmente.

L'unico svantaggio che vedo di questo approccio e che se l'utente vuole creare un nuovo template deve inserire i nomi di tutte le etichette per farle persistere du sb e potrebbe essere frustrante.

Con il razorengine si potrebbe recuperare l'html salvato in un database?
Modificato da Mirko Pastorelli il 30 ottobre 2013 21.01 -
11.862 messaggi dal 09 febbraio 2002
Contributi
ciao Mirko,


L'utente deve modificare l'html della pagina oltre alle label (testo in grassetto in corsivo e quant'altro) e sto valutando l'utilizzo di editor come tinyMCE nella mia applicazione.

ok, va bene. A proposito delle label: l'utente modificherà solo quelle che vuole personalizzare. Tu gli avrai già impostato delle label predefinite, che possono essere scelte da te o prese direttamente dai nomi delle proprietà di Studente (o Professore).


Con il razorengine si potrebbe recuperare l'html salvato in un database?

Sì, a lui interessa soltanto che tu gli fornisca una stringa. Sei tu a scegliere se ottenere questo contenuto stringa da un database o da un file di testo.


Persistendo tutto su database ipoteticamente risolverei il problema di creazione e di modifica. Potrebbero esistere soluzioni migliori?

Non so, dipende poi da come questi templates vengono consumati. Spiega da quali utenti vengono caricati e a quale scopo.

Ad esempio: diventano delle view MVC? Cioè, sono liberamente visualizzabili da un URL? In questo caso potrebbe essere opportuno salvarle come file ma se preferisci continuare ad usare il database le puoi comunque andare a pescare mettendoci un VirtualPathProvider in mezzo.
http://stackoverflow.com/questions/236972/using-virtualpathprovider-to-load-asp-net-mvc-views-from-dlls

ciao

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.