2012-03-22 22 views
18

ho questo (semplificato) classe:Converti querystring da/per opporsi

public class StarBuildParams 
{ 
    public int BaseNo { get; set; } 
    public int Width { get; set; } 
} 

E devo trasformare le istanze di esso ad un querystring come questo:

"BaseNo=5&Width=100" 

Inoltre devo trasformare una querystring di nuovo in un oggetto di quella classe.

So che questo è praticamente ciò che fa un modelbinder, ma non ho il contesto del controller nella mia situazione (alcune classi sepolte in profondità in una discussione).

Quindi, esiste un modo semplice per convertire un oggetto in una stringa di query e viceversa senza avere un contesto di controller?

Sarebbe bello usare la modellazione, ma non so come.

+0

Tutto quello che posso pensare è utilizzando la riflessione. – ojlovecd

+0

@ojlovecd In che modo la riflessione può aiutare qui? –

+0

Sono sicuro che questa situazione può essere evitata. Potresti descrivere il tuo scenario? Come sei finito con una stringa di query in questa classe? –

risposta

23

È possibile utilizzare la riflessione, qualcosa di simile:

public T GetFromQueryString<T>() where T : new(){ 
    var obj = new T(); 
    var properties = typeof(T).GetProperties(); 
    foreach(var property in properties){ 
     var valueAsString = HttpContext.Current.Request.QueryString[property.PropertyName]; 
     var value = Parse(valueAsString, property.PropertyType); 

     if(value == null) 
      continue; 

     property.SetValue(obj, value, null); 
    } 
    return obj; 
} 

Avrai bisogno di implementare il metodo Parse, usando solo int.Parse, decimal.Parse, DateTime.Parse, ecc

4

è possibile impostare le proprietà di questo oggetto nel suo costruttore recuperando i valori rilevanti dal querystring

public StarBuildParams() 
{ 
    this.BaseNo = Int32.Parse(Request.QueryString["BaseNo"].ToString()); 
    this.Width = Int32.Parse(Request.QueryString["Width"].ToString()); 
} 

e si può garantire che l'oggetto viene convertito nel formato querystring corretto sovrascrivendo il metodo ToString.

public override string ToString() 
{ 
    return String.Format("BaseNo={0}&Width={1}", this.BaseNo, this.Width); 
} 

avrai ancora bisogno di costruire e chiamare ToString nei luoghi appropriati, ma questo dovrebbe aiutare.

3

Questo dovrebbe funzionare fino a quando nessuna delle proprietà corrispondono altri parametri del percorso come controllore, azione, id, ecc

new RouteValueDictionary(Model) 

http://msdn.microsoft.com/en-us/library/cc680272.aspx

Inizializza una nuova istanza della classe RouteValueDictionary e aggiunge i valori basati sulle proprietà dell'oggetto specificato.

Per analizzare dalla stringa di query è possibile utilizzare la classe del modello come parametro di azione e lasciare che ModelBinder faccia il suo lavoro.

9

Consente di completare questo ... Ecco il metodo Parse.

public object Parse(Type dataType,string ValueToConvert) 
    { 
     TypeConverter obj = TypeDescriptor.GetConverter(dataType); 
     object value = obj.ConvertFromString(null, CultureInfo.InvariantCulture, ValueToConvert); 
     return value; 
    } 
0

Si può usare.HttpUtility.ParseQueryString() il metodo di NET:

HttpUtility.ParseQueryString("a=b&c=d") produce una NameValueCollection come tale:

[0] Key = "a", Value = "b" 
[1] Key = "c", Value = "d" 
3

Una soluzione con Newtonsoft JSON serializzatore e LINQ:

string responseString = "BaseNo=5&Width=100"; 
var dict = HttpUtility.ParseQueryString(responseString); 
string json = JsonConvert.SerializeObject(dict.Cast<string>().ToDictionary(k => k, v => dict[v])); 
StarBuildParams respObj = JsonConvert.DeserializeObject<StarBuildParams>(json); 
+0

Questo non funziona quando la stringa di query contiene matrici, ad es. P [0] [A] = xxx & P [0] [B] = yyyy & P [1] [A] = aaaa & P [1] [B] = bbbb – DrGriff

+0

Mi piace! questo era un lavoro senza contesto. Richiesta –