2010-11-16 16 views
12

My View si presenta così:ASP.NET MVC - difficoltà di minzione modello routeValues ​​Html.ActionLink

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<TMS.MVC.BusinessSystemsSupport.Models.SearchDataTypeModel>" %> 


<table class="classQueryResultsTable"> 
    <!-- the header --> 
    <tr class="headerRow"> 

     <td> 
     <%= Html.ActionLink("Effective Startdate", 
        "SortDetails", 
        "DataQryUpdate", 
        new 
        { 
         model = Model, 
         sortBy = "EffectiveStartDate", 
        }, 
        new { @class = "classLinkLogDetails" })%> 
     </td> 

    </tr> 


</table> 

La mia azione di controllo:

public ActionResult SortDetails(SearchDataTypeModel model, String sortBy) 
    { 

Il modello parametro è nullo. Il parametro sortBy è popolato. Posso passare una proprietà String dal modello all'azione senza problemi. Voglio passare in tutto il modello però.

Qualche idea su cosa sto facendo male?

risposta

3

Un'altra opzione è mantenere i dati necessari in TempData. Questo lo consegnerà alla prossima richiesta, e potrai recuperarlo lì. Dovresti essere in grado di mantenere l'intero oggetto del modello, se lo desideri.

Ma è più semplice (e migliore pratica) recuperarlo nuovamente dal database, come suggerisce Darin.

+1

TempData deve essere utilizzato solo se immediatamente seguito da un reindirizzamento dopo essere stato archiviato e recuperato da TempData nell'azione reindirizzata. Non lo userei in questo scenario. –

17

Non è possibile passare oggetti complessi:

new 
{ 
    model = Model, 
    sortBy = "EffectiveStartDate", 
}, 

model = Model non ha senso e non possono essere inviati tramite GET. Potrebbe essere necessario utilizzare un modulo con un modello di editor e/o campi nascosti per inviare tutte le proprietà del modello. Ricordare che solo i valori scalari possono essere inviati nella stringa di query (chiave1 = valore1 & chiave2 = valore2 ...). Un'altra alternativa che viene in mente è quello di inviare solo l'ID:

new 
{ 
    modelId = Model.Id, 
    sortBy = "EffectiveStartDate", 
}, 

e nella vostra azione di controllo recuperare il modello dato questo ID dal tuo archivio dati:

public ActionResult SortDetails(int modelId, String sortBy) 
{ 
    var model = repository.GetModel(modelId); 
    ... 
} 

Naturalmente questo è vero solo se l'utente non deve modificare le proprietà del modello in un modulo. Dipende dal tuo scenario.

E per completezza lasciatemi esporre un'altra opzione: utilizzare l'helper Html.Serialize da MVC Futures per serializzare l'intero modello in un campo nascosto che potrebbe essere passato all'azione del controller e deserializzato lì.

+0

Quindi, fondamentalmente semplice solo parametri di stringa? –

+3

Yeap, stringhe semplici, è così che funziona il protocollo HTTP. Un'altra alternativa è inviare solo l'ID e nell'azione del controller utilizzare un repository per recuperare il modello da questo ID dall'archivio dati. –

13

C'è un altro modo per passare in modo specifico modello o oggetti complessi in ActionLink come RouteValues.

  1. MODELLO: Fare serializzare e deserializzare metodi statici della classe come

    public class XYZ 
    { 
        // Some Fields 
        public string X { get; set; } 
        public string Y { get; set; } 
        public string X { get; set; } 
    
        // This will convert the passed XYZ object to JSON string 
        public static string Serialize(XYZ xyz) 
        { 
         var serializer = new JavaScriptSerializer(); 
         return serializer.Serialize(xyz); 
        } 
    
        // This will convert the passed JSON string back to XYZ object 
        public static XYZ Deserialize(string data) 
        { 
         var serializer = new JavaScriptSerializer(); 
         return serializer.Deserialize<XYZ>(data); 
        } 
    } 
    
  2. VISTA: Ora convertire il vostro oggetto complesso a stringa JSON prima di passarla in azione Visualizza

    <%= Html.ActionLink(Model.x, "SomeAction", new { modelString = XYZ.Serialize(Model) })%> 
    
  3. CONTROLLER: Ottieni l'oggetto come stringa nel metodo Action e convertilo nuovamente in oggetto prima di utilizzare

    public ActionResult SomeAction(string modelString) 
    { 
        XYX xyz = XYX.Deserialize(modelString); 
    } 
    

questo è tutto ...

Nota: tecniche discusse in altre risposte sono abbastanza bene in caso di modello, ma alcune volte si ha bisogno di passare un po 'di oggetto complesso (diverso modello di database) di nuovo al controller, perché ho un caso così specifico.

Spero che questo vi aiuterà un po '... :)

+0

Grazie per questa idea, risolve il mio problema. –

0

Forse è troppo tardi. Ho qualche soluzione. Qualcosa di simile a this. Ecco il mio esempio.

URL codice di generazione:

var rv = new RouteValueDictionary(); 
rv["sortBy"] = currentSortColumn; 
rv["ascending"] = currentSortColumn == sortBy ? !ascending : true; 
rv["filter.Id"] = // some value 
rv["filter.Creator"] = // some value 

var url = url.Action(// url is UrlHelper 
    actionName, 
    controllerName, 
    rv); 

// as result it will output something like this: 
// http://your_host/yourController/yourAction?sortBy=name&ascending=True&filter.Id=100&filter.Creator=test 

Controller cod:

public ActionResult YourAction(string sortBy = "name", bool ascending = false, YourFilterModel filter = null) 

Filtro classe di oggetti:

public class YourFilterModel 
{ 
    public string Id { get; set; } 
    public string Creator { get; set; } 
} 
Problemi correlati