HttpWebRequest: ¿Cómo encontrar un código postal en Canada Post a través de un WebRequest con x-www-form-adjunto?
-
22-07-2019 - |
Pregunta
Actualmente estoy escribiendo algunas pruebas para que pueda mejorar mis habilidades con la interacción de Internet a través de Windows Forms. Una de esas pruebas es encontrar un código postal que debe devolver el sitio web de Canada Post.
- Mi configuración de URL predeterminada está establecida en: http: / /www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
- Los campos de formulario obligatorios son: número de calle , nombre de calle , ciudad , provincia
- ContentType es " application / x-www-form-enclosed "
EDITAR: considere el valor " application / x-www-form-encoded " en lugar del valor del punto 3 como contentType. (¡Gracias EricLaw-MSFT!)
El resultado que obtengo no es el resultado esperado. Obtengo el código fuente HTML de la página donde podría ingresar manualmente la información para encontrar el código postal, pero no el código fuente HTML con el código postal encontrado. ¿Alguna idea de lo que estoy haciendo mal?
¿Debo considerar seguir el camino XML? ¿Es posible en primer lugar buscar en Canada Post de forma anónima?
Aquí hay una muestra de código para una mejor descripción:
public static string FindPostalCode(ICanadadianAddress address) {
var postData = string.Concat(string.Format("&streetNumber={0}", address.StreetNumber)
, string.Format("&streetName={0}", address.StreetName)
, string.Format("&city={0}", address.City)
, string.Format("&province={0}", address.Province));
var encoding = new ASCIIEncoding();
byte[] postDataBytes = encoding.GetBytes(postData);
request = (HttpWebRequest)WebRequest.Create(DefaultUrlSettings);
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Anonymous;
request.Container = new CookieContainer();
request.Timeout = 10000;
request.ContentType = contentType;
request.ContentLength = postDataBytes.LongLength;
request.Method = @"post";
var senderStream = new StreamWriter(request.GetRequestStream());
senderStream.Write(postDataBytes, 0, postDataBytes.Length);
senderStream.Close();
string htmlResponse = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
return processedResult(htmlResponse); // Processing the HTML source code parsing, etc.
}
Parece que estoy atrapado en el cuello de una botella en mi punto de vista. No encuentro salida al resultado deseado.
EDITAR: parece que tiene que haber parámetros en cuanto al ContentType de este sitio. Déjame explicarte.
- Hay uno con las '' meta '' -variables que estipula lo siguiente:
meta http-equiv = " Tipo de contenido " contenido = " application / xhtml + xml, texto / xml, texto / html; charset = utf-8 "
- Y otro más abajo en el código que se lee como:
id de formulario = " fpcByAdvancedSearch: fpcSearch " name = " fpcByAdvancedSearch: fpcSearch " método = " publicar " action = " / cpotools / apps / fpc / personal / findByCity? execute = e1s1 " enctype = " application / x-www-form-urlencoded "
Mi pregunta es la siguiente: ¿con cuál debo seguir?
Permítanme adivinar, ¿el primer ContentType debe considerarse ya que el segundo es solo para otra solicitud a una función más o menos cuando se publican los datos?
EDITAR: Según la solicitud, más cerca de la solución que estoy aparece en esta pregunta: WebRequest: Cómo encontrar un código postal usando un WebRequest contra este ContentType = ”application / xhtml + xml, text / xml, text / html; charset = utf-8 "?
¡Gracias por cualquier ayuda! :-)
Solución
Estoy tratando de ver una razón por la que no está utilizando la clase WebClient: -
var fields = new NameValueCollection();
fields.Add("streetnumber", address.StreetNumber);
fields.Add("streetname", address.StreetName);
fields.Add("city", address.City);
fields.Add("province", address.Province);
var wc = new WebClient();
byte[] resultData = wc.UploadValues(url, fields);
string result = Encoding.Default.GetString(resultData);
Es posible que desee verificar la codificación utilizada por el servidor al enviar los resultados, si usa UTF-8 cambie la última línea a: -
string result = Encoding.UTF8.GetString(resultData);
Algunos problemas que veo en su código original:
- El primer campo tiene el prefijo & amp ;, que no debería estar allí.
- Necesita usar la llamada
Uri.EscapeDataString
en cada valor de campo. - Está intentando construir una secuencia de memoria alrededor del resultado de
GetRequestStream
, no puedo ver qué lograría eso incluso siMemoryStream
tuviera un constructor de este tipo, pero no de todos modos. Simplemente escriba directamente en la secuencia devuelta porGetRequestStream
Si ya lo ha hecho, consiga una copia de fiddler para que pueda observar lo que ocurre cuando un estándar formulario solicita los datos correctamente y lo que está haciendo su código.
Editar : si tiene evidencia de que la falta de un contenedor de cookies es lo que hace que WebClient no funcione, entonces puede probar este enfoque: -
public class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest (Uri address)
{
WebRequest request = (WebRequest) base.GetWebRequest (address);
request.Container = new CookieContainer();
return request;
}
}
Ahora use mi código anterior para, pero en su lugar, instan WebClient
instancia MyWebClient
en su lugar.
Otros consejos
HTTPWebRequest devolverá el contenido de la URL solicitada. Si es una página HTML, devolverá el marcado HTML. Si el contenido de la página es XML, devolverá el marcado XML.
Parece que lo que necesita es un servicio web. Vería si ese sitio tiene algún servicio web disponible para procesar ese tipo de solicitud. Si lo hacen, devolverá el marcado XML, JSON en respuesta a su consulta. De lo contrario, tendrá que analizar el resultado de la solicitud.