HttpWebRequest: Como encontrar um código postal no Canada Post através de um WebRequest com x-www-form-fechado?
-
22-07-2019 - |
Pergunta
Atualmente estou escrevendo alguns testes para que eu possa melhorar minhas habilidades com a interação Internet através de Windows Forms. Um desses testes é encontrar um código postal que deverá ser devolvido pela Canada Post website.
- A minha configuração de URL padrão é definido como: http: / /www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
- Os campos do formulário necessários são: streetNumber , streetname , cidade , província
- O contentType é "application / x-www-form-fechado"
EDIT: Por favor, considere o valor "application / x-www-form-codificado" em vez de valor do ponto 3 como o contentType. (Graças EricLaw-MSFT!)
O resultado eu recebo não é o resultado esperado. Eu obter o código HTML da página onde eu poderia inserir manualmente as informações para encontrar o código postal, mas não o código HTML com o encontrado código postal. Alguma idéia do que estou fazendo de errado?
Devo considerar ir a maneira XML? É antes de tudo possível pesquisar no Canada Post anonimamente?
Aqui está um exemplo de código para melhor descrição:
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 preso em um gargalo de garrafa no meu ponto de vista. Acho que não há saída para o resultado desejado.
EDIT: Não parece ter a parâmetros como para o ContentType deste site. Deixe-me explicar.
- Há um com os "meta" -variables que estipula o seguinte:
meta http-equiv = conteúdo "Content-Type" = "application / xhtml + xml, text / xml, text / html; charset = utf-8"
- E outro mais tarde para baixo o código que é lido como:
forma id = "fpcByAdvancedSearch: fpcSearch" name = "fpcByAdvancedSearch: fpcSearch" method = "post" action = "? / Cpotools / apps / FPC / / findByCity execução = e1s1 pessoal" enctype = "application / x-www- urlencoded-forma "
A minha pergunta é a seguinte: Com qual deles eu tenho que vara
?Deixe-me adivinhar, o primeiro ContentType deve ser considerado como o segundo é apenas para um outro pedido para uma função mais ou menos quando os dados são postados?
EDIT: Como pelo pedido, o mais perto da solução que eu sou é listado sob esta pergunta: WebRequest: Como encontrar um código postal usando um WebRequest contra esta ContentType =”application / xhtml + xml, text / xml, text / html; charset = utf-8” ?
Obrigado por qualquer ajuda! : -)
Solução
Eu estou tentando ver uma razão para que você não está usando a classe 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);
Você pode querer verificar a codificação usada pelo servidor ao enviar os resultados, se ele usa mudança UTF-8 a última linha para: -
string result = Encoding.UTF8.GetString(resultData);
Algumas questões I lugar no seu código original: -
- O primeiro campo é prefixado com &, que não deveria estar lá.
- Você precisa chamar o uso
Uri.EscapeDataString
em cada valor do campo. - Você está tentando construir um fluxo de memória em torno do resultado de
GetRequestStream
, eu não posso ver o que que iria conseguir, mesmo seMemoryStream
teve como um construtor mas não faz de qualquer maneira. Basta escrever diretamente para o fluxo retornado porGetRequestStream
Se você já tiver feito isso obter-se uma cópia do violinista para que você possa observar o que ocorre quando um padrão formulário solicita os dados com sucesso e qual o seu código está fazendo.
Editar : Se você tem evidências de que a falta de um contêiner de cookie é o que causa WebClient não trabalho, então você pode tentar essa abordagem: -
public class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest (Uri address)
{
WebRequest request = (WebRequest) base.GetWebRequest (address);
request.Container = new CookieContainer();
return request;
}
}
Agora, usar o meu código acima para mas em vez od instanciação WebClient
exemplo MyWebClient
vez.
Outras dicas
HttpWebRequest irá retornar o conteúdo do URLrequested. Se for uma página HTML, ele irá retornar marcação HTML. Se o conteúdo da página é XML, em seguida, ele irá retornar marcação XML.
Parece que você precisa é de um Webservice. Gostaria de ver se esse site tem nenhum webserivces disponíveis para processar esse tipo de pedido. Se eles fizerem isso, então ele irá retornar XML, JSON marcação em resposta a sua consulta. Caso contrário, você são deixados para analisar o resultado do pedido.