Tengo un activador HTTP de función de Azure de .NET Core 6.0.
Me gustaría manejar un parámetro de cadena de consulta de matriz en estas dos formas comunes:
?param=foo¶m=escape%2Ctest?param=foo,escape%2Ctest En ambos casos, me gustaría extraer la matriz ["foo", "escape,test"] .
Me sorprendió descubrir que las opciones de análisis de cadena de consulta disponibles para mí no admitían la sintaxis de coma o la URL descodificó la cadena de consulta como parte de la agrupación de parámetros.
He intentado usar varias API dotnet diferentes:
System.Web. HttpUtility.ParseQueryStringMicrosoft.AspNetCore.WebUtilities. QueryHelpers.ParseQueryMicrosoft.AspNetCore.Http. HttpRequest.Query var qs = "?param=foo,escape%2Ctest"; var a = httpRequest.Query["param"]; // ["foo,escape,test"] var b = HttpUtility.ParseQueryString(qs)["param"]; // "foo,escape,test" var c = QueryHelpers.ParseQuery(qs)["param"]; // ["foo,escape,test"] Estoy un poco sorprendido de que no haya soporte para el formato separado por comas. Y estoy muy sorprendido de que no parezca haber una forma de obtener la cadena de consulta segmentada sin decodificar también los parámetros de la cadena de consulta (lo que impide distinguir entre param=foo,escape%2Ctest y ?param=foo,escape,test ).
Publicaré mi solución actual como una "respuesta" a continuación, pero espero que me falte una solución más simple que use una biblioteca .NET. Si alguien puede señalar lo que me he perdido aquí, se lo agradecería.
Aquí está mi solución actual. Nuevamente, espero que haya una forma menos manual de lograr este comportamiento.
public static IDictionary<string, List<string>> GroupByKey(this QueryString queryString) { if (!queryString.Contains("?")) { throw new ArgumentException("Expected query string to contain '?' character."); } var encodedUrl = queryString.Value; var result = new Dictionary<string, List<string>>(); string trimmedQueryString = encodedUrl.Split('?')[1]; string[] queryStringSections = trimmedQueryString.Split('&'); foreach (var section in queryStringSections) { var sides = section.Split('='); var key = sides[0]; var value = sides[1]; var values = value.Split(','); var decodedValues = values.Select(x => WebUtility.UrlDecode(x)); if (!result.ContainsKey(key)) { result.Add(key, new List<string>()); } result[key].AddRange(decodedValues); } return result; }Desafortunadamente, no existe una especificación oficial en RFC 3986 > Sección 3.4 que detalle cómo pasar múltiples valores para un parámetro de consulta.
Dicho esto, los navegadores parecen implementar de forma nativa el enfoque de varias teclas al crear una cadena de consulta por su cuenta. Por ejemplo, en la siguiente demostración :
<form method="GET"> <label for="cars">Choose a car:</label> <select name="cars" id="cars" multiple> <option value="audi" selected>Audi</option> <option value="saab" selected>Saab</option> </select> <button type="submit">Submit</button> </form> La solicitud de obtención se enviará con ?cars=audi&cars=saab
En ausencia de una especificación, con dotnet que ya admite el enfoque de varias claves con el resultado deseado , y dado que los navegadores usan varias claves de forma nativa, puede valer la pena actualizar la forma en que crea cadenas de consulta en el cliente.
Quizás alguien más pueda agregar una forma inteligente de analizar en .net, pero de lo contrario, puede estar luchando cuesta arriba contra la implementación en dotnet.