Come passare un oggetto modificato non supportato dalla vista al controller senza un modulo?

StackOverflow https://stackoverflow.com/questions/295200

  •  08-07-2019
  •  | 
  •  

Domanda

Breve: in che modo la modellazione passa oggetti dalla vista al controller?

Long:
Innanzitutto, in base ai parametri forniti dall'utente tramite un modulo di ricerca, alcuni oggetti vengono recuperati dal database. A questi oggetti vengono forniti metadati che sono visibili (ma non definibili) al cliente (ad esempio: la denominazione e il prezzo degli oggetti differiscono da regione a regione).
Più avanti nel sito, l'utente può fare clic sui collegamenti che dovrebbero mostrare i dettagli di questi oggetti. Poiché questi metadati sono importanti per la visualizzazione, ma non per la definizione, è necessario ripristinare l'oggetto precedentemente modificato nel controller. Quando utilizzo il modelbinding asp.net predefinito mvc, viene utilizzato il metodo .ToString (). Questo fuori rotta non restituisce una stringa rilevante per ricreare l'oggetto completo.
Avrei immaginato che sarebbe stata coinvolta l'interfaccia ISerializable, ma non è così. Come devo fare per ottenere l'effetto desiderato? Non riesco a immaginare di essere il primo a dover affrontare questa domanda, quindi immagino che mi manchi qualcosa da qualche parte ...

È stato utile?

Soluzione

L'associazione del modello predefinito assume i parametri del modulo in base al nome e li abbina alle proprietà del tipo specificato nell'elenco degli argomenti. Ad esempio, il tuo modello ha proprietà " Price " e "Nome", quindi il modulo dovrebbe contenere input con ID / nomi "Prezzo" e " Nome " (Ho il sospetto che faccia una corrispondenza senza distinzione tra maiuscole e minuscole). Il raccoglitore utilizza la riflessione per convertire i valori del modulo associati a queste chiavi nel tipo appropriato e lo assegna alle proprietà di un oggetto appena creato del tipo specificato dal parametro (sempre derivato da reflection).

Puoi effettivamente consultare (e scaricare) la fonte per questo a http://www.codeplex.com / aspnet , anche se dovrai approfondire la fonte MVC da lì. Darei un collegamento alla fonte DefaultModelBinder, ma il modo in cui sono costruiti, credo che il collegamento cambi con l'introduzione delle revisioni.

Quindi, per rispondere alla tua domanda, devi avere dei parametri (che potrebbero essere nascosti) nel tuo modulo che corrispondono alle proprietà dell'oggetto che vuoi ricreare. Quando si invia il modulo (nella vista) al controller, il raccoglitore dovrebbe ricostituire un oggetto del tipo specificato utilizzando i parametri del modulo. Se devi eseguire la traduzione dai valori nel parametro form alle proprietà dell'oggetto, probabilmente dovrai implementare il tuo raccoglitore di modelli personalizzato.

[EDIT] In risposta al tuo secondo post:

Supponiamo di voler ricollegare un collegamento a un'azione che utilizza un oggetto personalizzato. Possiamo archiviare l'oggetto personalizzato in TempData (o nella Sessione se ne abbiamo bisogno per durare di più attraverso più di un postback) con una chiave particolare. Possiamo quindi costruire il collegamento di azione e fornire la chiave dell'oggetto come valore per ActionLink in una classe anonima. Questo passerà indietro la chiave come parametro Request. Nella nostra azione possiamo usare la chiave da questo parametro per recuperare l'oggetto da TempData.

<%= Html.ActionLink( ViewData["CustomObject1",
                     "Select",
                     new { TempDataKey = ViewData["CustomObject1_Key"] }
                   ) %>
&nbsp;

public ActionResult Select()
{
    Entity custObj = null;
    string objKey = Request.Params["TempDataKey"];
    if (!string.IsNullOrEmpty(objKey))
    {
       custObj = (Entity)TempData[objKey];
    }

    ... continue processing
}

Altri suggerimenti

@tvanfosson

Grazie per la tua spiegazione, ma per quanto riguarda i link? (nessun modulo coinvolto) Attualmente Html.ActionLink (c = > c.Action (parametro), " label ") accetta gli oggetti come parametro. Questi devono essere tradotti in parti URL. Per questo, MVC SEMPRE passa al metodo .ToString (). Non voglio serializzare il mio oggetto nel metodo ToString.
Non dovrei essere in grado di aiutare in qualche modo il framework a serializzare il mio oggetto? Dire attraverso l'interfaccia ISerialize o qualcosa del genere?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top