Come gestisci il salvataggio dei tag blog in MVC?

2

Sto scrivendo il mio motore di blog come esercizio di apprendimento. Il blog è abbastanza funzionale in questo momento, ma sto cercando di aggiungere una funzione 'tag' ad esso e sono confuso su quale sia il modo migliore per gestire il salvataggio di un elenco di tag sul mio controller.

La mia domanda:

Devo passare il mio elenco di tag separati da virgola al controller come una stringa singola e convertirlo in IList<Tag> ? O dovrei gestirlo nella vista e poi passare un IList<Tag> al controller?

Una versione sudo del mio modello Post.cs:

public class Post : IEntity
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
    public IList<Tag> Tags { get; set; }
}

e il mio modello Tag.cs:

public class Tag : IEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Post> Posts { get; set; }
}

aggiornamento: condivisione di alcuni file gist .

PostController.cs

Create.cshtml

    
posta Dan Beaulieu 18.05.2015 - 06:21
fonte

1 risposta

2

Quando i tag vengono inviati dall'autore di un blog, sono sotto forma di una semplice stringa (con valori separati da virgola o, come su Stack Exchange, spazi semplici). Questo è l'unico momento nel flusso di lavoro quando tutti i tag appaiono come una singola stringa.

Il controller quindi divide quei tag e li ritaglia. A questo punto, tali tag diventano Collection<string> (o Collection<Tag> se sono presenti dati specifici o logica aziendale associata a un tag.) A seconda delle esigenze specifiche, potrebbe essere necessario utilizzare altre classi di raccolta generiche, ad esempio HashSet<T> se devi cercare rapidamente nella sequenza di tag.

Il controllore può quindi mantenere questi tag insieme all'articolo, al titolo, alle informazioni dell'autore, ecc. A seconda del livello di persistenza (cioè del tipo di database) che usi, i tag possono assumere forme diverse, ma di solito sarà comunque considerato come una sorta di array e memorizzato uno per uno, non come un singolo valore.

Infine, quando si tratta di visualizzare i tag, il controller li carica dal livello di persistenza (i tag vengono quindi visualizzati in una forma di Collection<string> / Collection<Tag> ) e memorizza la raccolta (eventualmente come IEnumerable<string> ) nel modello, passando il modello alla vista.

La vista enumera quei tag e visualizza il codice HTML corrispondente.

Guardando il tuo codice, non sono sicuro di cosa stai cercando di fare. Immagino che Tags sia una sequenza nel tuo modello, ma stai visualizzando solo il primo elemento nella tua vista (riga 54 e 55). Perché?

Questo è anche il motivo per cui ho chiesto nei miei commenti come vengono visualizzati i tag nel modulo. Ecco un modo per associare una matrice a una sequenza di caselle di controllo; Non sono sicuro che questo sia ciò che desideri o di cui hai bisogno. Probabilmente ciò di cui hai effettivamente bisogno è qualcosa di simile al tagging Stack Exchange: un singolo campo di testo in cui un utente può inserire una o più parole (o valori separati da virgola nel tuo caso). Ad esempio:

data-center, rack, power-management, wiring

sarà inserito in una singola casella di testo e avrà come risultato quattro tag: , , e .

Questo porta alla differenza tra:

  • La vista che mostra un modulo a un autore, che gli consente di modificare l'articolo e i suoi tag, e:

  • La vista che mostra l'articolo agli utenti finali.

La prima vista può riguardare tutti i tag rappresentati come una semplice stringa. Lo fa già quando si tratta di inviare un modulo: il valore di una casella di testo, un testo semplice, viene tradotto in una stringa che può essere analizzata come hai fatto nel tuo codice alla riga 79 con un Split() . Sebbene sia fastidioso, ¹ puoi anche usare una stringa per popolare il modulo quando l'autore vuole modificare un articolo (questo rende possibile utilizzare lo stesso modello in entrambi i casi). Mentre il modello conterrà una stringa contenente tag separati da virgola, prova a utilizzare Collection<Tag> il più possibile all'interno del controller stesso. Le uniche posizioni in cui dovresti vedere una stringa sono i limiti: quando il controller riceve l'input e quando crea un modello.

D'altra parte, la vista che mostra l'articolo e i tag per l'utente finale dovrebbe basarsi completamente sulla rappresentazione IEnumerable<Tag> che dovrebbe essere spinta dal controllore attraverso il modello fino alla vista. È la vista che utilizzerà la sequenza per enumerare i valori con una foreach , generando il codice HTML corrispondente.

Un'ultima nota: quando il codice verrà completato, compilato e funzionante, assicurati di pubblicare alcune parti su CodeReview . Ci sono molte cose da dire sul codice nel suo stato attuale.

¹ L'approccio è disturbante perché una stringa concatenata è una struttura di dati errata per i tag. Quello di destra rimane una sequenza (come Collection<T> ). Il problema, nel tuo caso, è che ti stai affidando allo stesso modello sia per generare il modulo sia per ottenere i valori inviati. Dato che sei forzato per usare una stringa nel secondo caso, l'utilizzo di una sequenza nel primo richiederà due modelli diversi, il che renderà il tuo codice più complesso di quanto dovrebbe essere.

    
risposta data 18.05.2015 - 11:55
fonte

Leggi altre domande sui tag