2011-04-07 18 views
6

dado es una URL como http://localhost:1973/Services.aspx?idProject=10&idService=14.Cómo reemplazar el parámetro url?

¿Cuál es la forma más directa de reemplazar ambos valores de parámetros de URL (por ejemplo 10 a 12 y 14 a 7)?

Regex, String.Replace, Substring o LinQ - Estoy un poco atascado.

gracias de antemano,

Tim


que terminó con lo siguiente, que está trabajando para mí, porque esta página tiene sólo estos dos parámetros:

string newUrl = url.Replace(url.Substring(url.IndexOf("Services.aspx?") + "Services.aspx?".Length), string.Format("idProject={0}&idService={1}", Services.IdProject, Services.IdService)); 

Pero gracias por sus sugerencias :)

Respuesta

2

encontré esto en un viejo ejemplo de código, wouldnt necesita mucho para mejorarlo, teniendo un IEnumerable<KeyValuePair<string,object>> puede ser mejor que la cadena delimeted actual.

public static string AppendQuerystring(string keyvalue) 
    { 
     return AppendQuerystring(System.Web.HttpContext.Current.Request.RawUrl, keyvalue); 
    } 
    public static string AppendQuerystring(string url, string keyvalue) 
    { 
     string dummyHost = "http://www.test.com:80/"; 
     if (!url.ToLower().StartsWith("http")) 
     { 
      url = String.Concat(dummyHost, url); 
     } 
     UriBuilder builder = new UriBuilder(url); 
     string query = builder.Query; 
     var qs = HttpUtility.ParseQueryString(query); 
     string[] pts = keyvalue.Split('&'); 
     foreach (string p in pts) 
     { 
      string[] pts2 = p.Split('='); 
      qs.Set(pts2[0], pts2[1]); 
     } 
     StringBuilder sb = new StringBuilder(); 

     foreach (string key in qs.Keys) 
     { 
      sb.Append(String.Format("{0}={1}&", key, qs[key])); 
     } 
     builder.Query = sb.ToString().TrimEnd('&'); 
     string ret = builder.ToString().Replace(dummyHost,String.Empty); 
     return ret; 
    } 

Uso

var url = AppendQueryString("http://localhost:1973/Services.aspx?idProject=10&idService=14","idProject=12&idService=17"); 
+0

Gracias. Utilicé un reemplazo simple porque la página solo tiene estos dos parámetros, pero su respuesta es un buen ejemplo para una mejor manera;) –

+0

Debe indicar que el valor de clave debe codificarse correctamente en uri para que esto funcione. Si quiero enviar 'query =? Est' con esto, creará una cadena de consulta no válida –

1

La forma más robusta sería usar la clase Uri t o analizar la cadena, cambiar los valores de param y luego generar el resultado.

Existen muchos matices sobre cómo funcionan las URL y si bien podrías tratar de rodar tu propia expresión regular para hacer esto, podría complicar rápidamente el manejo de todos los casos.

Todos los otros métodos tendrían problemas con subcadenas, etc. y ni siquiera veo cómo se aplica Linq aquí.

2

La forma más sencilla es String.Replace, pero usted va a terminar con problemas si su URI parece http://localhost:1212/base.axd?id=12&otherId=12

+0

El requisito de OP no se puede cumplir correctamente con la simple sustitución de cadenas. – harpo

+0

Lo sé, de ahí que establezca (aunque implícitamente) que la forma más directa (como se solicita) no es la correcta. –

+0

En realidad terminé usando String.Replace (ver mi edición), está funcionando para mi requerimiento. –

8

C# HttpUtility.ParseQueryString utilidad va a hacer el trabajo pesado para usted. Querrá hacer una comprobación nula más robusta en su versión final.

// Let the object fill itself 
    // with the parameters of the current page. 
    var qs = System.Web.HttpUtility.ParseQueryString(Request.RawUrl); 

    // Read a parameter from the QueryString object. 
    string value1 = qs["name1"]; 

    // Write a value into the QueryString object. 
    qs["name1"] = "This is a value"; 
+0

¿Por qué pasan RawUrl a ParseQueryString? Hay una diferencia entre una cadena de consulta y una URL. ¿No debería dividir la URL primero para extraer la cadena de consulta? –

+0

Sí, excelente respuesta, pero si pasa la URL completa, la clave de su primer argumento se verá como 'http: // localhost: 50819/Request? Pagenumber' en lugar de' pagenumber'. –

13

Esto es lo que haría:

public static class UrlExtensions 
{ 
    public static string SetUrlParameter(this string url, string paramName, string value) 
    { 
     return new Uri(url).SetParameter(paramName, value).ToString(); 
    } 

    public static Uri SetParameter(this Uri url, string paramName, string value) 
    {   
     var queryParts = HttpUtility.ParseQueryString(url.Query); 
     queryParts[paramName] = value; 
     return new Uri(url.AbsoluteUriExcludingQuery() + '?' + queryParts.ToString()); 
    } 

    public static string AbsoluteUriExcludingQuery(this Uri url) 
    { 
     return url.AbsoluteUri.Split('?').FirstOrDefault() ?? String.Empty; 
    } 
} 

Uso:

string oldUrl = "http://localhost:1973/Services.aspx?idProject=10&idService=14"; 
string newUrl = oldUrl.SetUrlParameter("idProject", "12").SetUrlParameter("idService", "7"); 

O:

Uri oldUrl = new Uri("http://localhost:1973/Services.aspx?idProject=10&idService=14"); 
Uri newUrl = oldUrl.SetParameter("idProject", "12").SetParameter("idService", "7"); 
+0

Gracias, que parece prometedor, la veré más de cerca más adelante. –

0

Tengo el mismo problema y lo resolví con las siguientes tres líneas de código que recibo de los comentarios aquí (como solución de Stephen Oberauer, pero menos overenginieered):

' EXAMPLE: 
    ' INPUT: /MyUrl.aspx?IdCat=5&Page=3 
    ' OUTPUT: /MyUrl.aspx?IdCat=5&Page=4 
    ' Get the URL and breaks each param into Key/value collection: 
    Dim Col As NameValueCollection = System.Web.HttpUtility.ParseQueryString(Request.RawUrl) 

    ' Changes the param you want in the url, with the value you want 
    Col.Item("Page") = "4" 

    ' Generates the output string with the result (it also includes the name of the page, not only the params) 
    Dim ChangedURL As String = HttpUtility.UrlDecode(Col.ToString()) 

Ésta es la solución usando VB .NET pero la conversión a C# es directa.

4

Aquí es mi aplicación:

using System; 
using System.Collections.Specialized; 
using System.Web; // For this you need to reference System.Web assembly from the GAC 

public static class UriExtensions 
{ 
    public static Uri SetQueryVal(this Uri uri, string name, object value) 
    { 
     NameValueCollection nvc = HttpUtility.ParseQueryString(uri.Query); 
     nvc[name] = (value ?? "").ToString(); 
     return new UriBuilder(uri) {Query = nvc.ToString()}.Uri; 
    } 
} 

y aquí están algunos ejemplos:

new Uri("http://host.com/path").SetQueryVal("par", "val") 
// http://host.com/path?par=val 

new Uri("http://host.com/path?other=val").SetQueryVal("par", "val") 
// http://host.com/path?other=val&par=val 

new Uri("http://host.com/path?PAR=old").SetQueryVal("par", "new") 
// http://host.com/path?PAR=new 

new Uri("http://host.com/path").SetQueryVal("par", "/") 
// http://host.com/path?par=%2f 

new Uri("http://host.com/path") 
    .SetQueryVal("p1", "v1") 
    .SetQueryVal("p2", "v2") 
// http://host.com/path?p1=v1&p2=v2 
1

que recientemente han dado a conocer UriBuilderExtended, que es una biblioteca que hace que la edición de las cadenas de consulta en UriBuilder objetos de una brisa a través de métodos de extensión.

Básicamente, simplemente cree un objeto UriBuilder con su cadena de URL actual en el constructor, modifique la consulta mediante los métodos de extensión y cree la nueva cadena de URL desde el objeto UriBuilder.

Ejemplo rápido:

string myUrl = "http://www.example.com/?idProject=10&idService=14"; 

UriBuilder builder = new UriBuilder(myUrl); 

builder.SetQuery("idProject", "12"); 
builder.SetQuery("idService", "7"); 

string newUrl = builder.Url.ToString(); 

cadena URL se obtiene a partir builder.Uri.ToString(), no builder.ToString() ya que a veces hace de manera diferente a lo que se espera.

Puede obtener la Biblioteca a través del NuGet.

Más ejemplos here.

Comentarios y deseos son bienvenidos.

Cuestiones relacionadas