2012-03-22 10 views
18

tengo este (simplificado) Clase:Convertir cadena de consulta del/al objeto

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

Y tengo que transformar instancias de la misma a una cadena de consulta como esta:

"BaseNo=5&Width=100" 

Además tengo que transformar una cadena de preguntas de ese tipo en un objeto de esa clase.

sé que esto es más o menos lo que hace un modelbinder, pero no tengo el contexto del controlador en mi situación (algunos enterrado profundamente clase en curso en un hilo).

Entonces, ¿hay una forma sencilla de convertir un objeto en una cadena de consulta y volver sin tener un marco regulador?

Sería muy bueno para usar el modelbinding pero no saben cómo.

+0

Todo lo que puedo pensar es el uso de la reflexión. – ojlovecd

+0

@ojlovecd ¿Cómo ayudaría la reflexión aquí? –

+0

Estoy seguro de que esta situación se puede evitar. ¿Podría describir su escenario? ¿Cómo terminaste con una cadena de consulta en esta clase? –

Respuesta

23

Puede utilizar la reflexión, algo como esto:

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; 
} 

Tendrá que aplicar el método Parse, simplemente usando int.Parse, decimal.Parse, DateTime.Parse, etc.

4

Es posible ajustar las propiedades de este objeto en su constructor mediante la recuperación de los valores relevantes de la cadena de consulta

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

y se puede asegurar que el objeto se convierte en el formato de cadena de consulta correcta reemplazando el método ToString.

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

No obstante, deberá construir y llamar ToString en los lugares apropiados, pero esto debería ayudar.

3

esto debería funcionar siempre que ninguna de las propiedades se han encontrado otros parámetros de la ruta como controlador, acción, ID, etc.

new RouteValueDictionary(Model) 

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

Inicializa una nueva instancia de la clase RouteValueDictionary y agrega los valores que se basan en las propiedades del objeto especificado.

Para analizar de nuevo desde la cadena de consulta, puede usar la clase de modelo como parámetro de acción y dejar que ModelBinder lo haga.

9

Vamos a hacer esta completa ... Aquí es el método de análisis.

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

sólo puede utilizar.HttpUtility.ParseQueryString() método de NET:

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

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

Una solución con Newtonsoft JSON serializador y 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

Esto no funciona cuando la cadena de consulta contiene matrices, p. Ej. P [0] [A] = xxx y P [0] [B] = aaaa & P [1] [A] = aaaa & P [1] [B] = bbbb – DrGriff

+0

¡Me gusta! esto fue obras sin contexto. Solicitud –

Cuestiones relacionadas