5

Sto provando a passare un array di int da JavaScript a un controller MVC che accetta 2 parametri: un array int e un int. Questo è per eseguire un reindirizzamento di pagina alla vista restituita dall'azione del controller.Passare un array int a MVC Controller

var dataArray = getAllIds(); //passes back a JavaScript array 
window.location.replace("/" + controllerName + "/EditAll?ids=" + dataArray + "&currentID=" + dataArray[0]) 

dataArray contiene 1,7 come previsto per l'utilizzo del mio esempio.

Codice controller

public virtual ActionResult EditAll(int[] ids, int currentID) 
{ 

    currentModel = GetID(currentID); 
    currentVM = Activator.CreateInstance<ViewModel>(); 
    currentVM.DB = DB; 
    currentVM.Model = currentModel; 
    currentVM.ViewMode = ViewMode.EditAll; 
    currentVM.ModelIDs = ids; 

    if (currentModel == null) 
    { 
     return HttpNotFound(); 
    } 

    return View("Edit", MasterName, currentVM); 
} 

Il problema è che durante l'ispezione le int [] ids passati al controllore, il suo valore è nullo. currentID è impostato su 1 come previsto.

Ho provato a impostare jQuery.ajaxSettings.traditional = true che non ha effetto Ho anche provato a creare un URL lato server utilizzando @ Url.Action in JavaScript. Ho anche provato JSON.Stringify prima di passare l'array ad es.

window.location.replace("/" + controllerName + "/EditAll?ids=" + JSON.stringify(dataArray) + "&currentID=" + dataArray[0]) 

Anche in questo caso l'array di id termina con null sul lato controller.

Qualcuno ha qualche suggerimento su come far passare correttamente l'array int al controller? Potrei dichiarare il parametro come String nell'azione Controller e serializzare manualmente e de-serializzare il parametro, ma ho bisogno di capire come ottenere il framework per fare automaticamente conversioni di tipo semplice.

Grazie!

risposta

9

Per passare un array di valori semplici in MVC, è sufficiente assegnare lo stesso nome a più valori, ad es. L'URI finirà per qualcosa di simile

/{controllerName}/EditAll?ids=1&ids=2&ids=3&ids=4&ids=5&currentId=1 

Il modello di default vincolante MVC legherà questo per il parametro Azione int matrice correttamente.

Ora, se si tratta di un array di valori complessi, esistono due approcci che è possibile adottare per il binding del modello. Supponiamo di avere un tipo in questo modo

public class ComplexModel 
{ 
    public string Key { get; set; } 

    public string Value { get; set; } 
} 

e una firma azione del controller di

public virtual ActionResult EditAll(IEnumerable<ComplexModel> models) 
{ 
} 

Per il modello vincolante correttamente, i valori devono includere un indicizzatore nella richiesta per esempio

/{controllerName}/EditAll?models[0].Key=key1&models[0].Value=value1&models[1].Key=key2&models[1].Value=value2 

Stiamo usando un int indicizzatore qui, ma si può immaginare che questo potrebbe essere abbastanza inflessibile in un'applicazione in cui gli elementi presentati a un utente nell'interfaccia utente possono essere aggiunti e cancellati in qualsiasi indice/fessura nella collezione . A tal fine, MVC consente anche di specificare il proprio indicizzatore per ciascun elemento della raccolta e di trasmettere tale valore con la richiesta per il modello di associazione predefinito da utilizzare, ad es.

/{controllerName}/EditAll?models.Index=myOwnIndex&models[myOwnIndex].Key=key1&models[myOwnIndex].Value=value1&models.Index=anotherIndex&models[anotherIndex].Key=key2&models[anotherIndex].Value=value2 

Qui abbiamo specificato le nostre indicizzatori, myOwnIndex e anotherIndex per il modello vincolante da utilizzare per associare un insieme di tipi complessi. È possibile utilizzare qualsiasi stringa per gli indicizzatori per quanto ne so.

In alternativa, è possibile implementare il proprio modello di raccoglitore per dettare come una richiesta in arrivo deve essere associata a un modello. Ciò richiede più lavoro rispetto all'utilizzo delle convenzioni quadro predefinite, ma aggiunge un ulteriore livello di flessibilità.

+0

Non è possibile aggirare il fatto che è necessario creare una stringa lunga aggirando l'array e aggiungendo ogni elemento alla stringa di query? –

+0

Hai taggato che stai usando jQuery, quindi dovresti essere in grado di utilizzare '$ .param' http://api.jquery.com/jQuery.param/ per creare i valori codificati per te, ad es. 'window.location.replace ("/"+ controllerName +"/EditAll? "+ $ .param ({ids: dataArray, currentId: dataArray [0]}))' –