HttpWebRequest를 사용하여 양식 데이터 게시


91

내 웹 응용 프로그램에없는 지정된 URL에 일부 양식 데이터를 게시하고 싶습니다. "domain.client.nl"과 같은 동일한 도메인이 있습니다. 웹 응용 프로그램에는 "web.domain.client.nl"이라는 URL이 있으며 게시 할 URL은 "idp.domain.client.nl"입니다. 하지만 내 코드는 아무것도하지 않습니다 ..... 누군가 내가 뭘 잘못하고 있는지 아는가?

Wouter

StringBuilder postData = new StringBuilder();
postData.Append(HttpUtility.UrlEncode(String.Format("username={0}&", uname)));
postData.Append(HttpUtility.UrlEncode(String.Format("password={0}&", pword)));
postData.Append(HttpUtility.UrlEncode(String.Format("url_success={0}&", urlSuccess)));
postData.Append(HttpUtility.UrlEncode(String.Format("url_failed={0}", urlFailed)));

ASCIIEncoding ascii = new ASCIIEncoding();
byte[] postBytes = ascii.GetBytes(postData.ToString());

// set up request object
HttpWebRequest request;
try
{
    request = (HttpWebRequest)HttpWebRequest.Create(WebSiteConstants.UrlIdp);
}
catch (UriFormatException)
{
    request = null;
}
if (request == null)
    throw new ApplicationException("Invalid URL: " + WebSiteConstants.UrlIdp);

request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";

// add post data to request
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();


6
다른 사람이 특별히 WebClient.

답변:


72

필드 이름과 값은 모두 URL로 인코딩되어야합니다. 게시물 데이터의 형식과 쿼리 문자열이 동일합니다.

.net 방식은 다음과 같습니다.

NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
outgoingQueryString.Add("field1","value1");
outgoingQueryString.Add("field2", "value2");
string postdata = outgoingQueryString.ToString();

이것은 필드와 값 이름의 인코딩을 처리합니다.


10
string postdata = outgoingQueryString.ToString();값이있는 문자열을 제공합니다 "System.Collections.Specialized.NameValueCollection".
sfuqua

1
실제로 @sfuqua HttpUtility의 소스 (특히 System.Web의 소스)를 디 컴파일하면 특수한 NameValueCollection 유형을 반환하는 것을 볼 수 있습니다. return (NameValueCollection) new HttpValueCollection (query, false, true, encoding); 컬렉션을 쿼리 문자열로 올바르게 변환합니다. 그러나 RestSharp에서 사용하는 경우에는 그렇지 않습니다 ...
The Senator

흥미롭게도에서이 정확한 문제 ToString()를 보았으므로 RestSharp를 사용하는 동안인지 기억할 수 없습니다. 확실한 가능성. 수정 해 주셔서 감사합니다.
sfuqua

outgoingQueryString예제 코드에서 암시하는 것처럼 작동 방식 이 즉시 명확하지 않았습니다 . 이 두 질문에 대한 답은 다음 과 같습니다. (1) HttpValueCollection 및 NameValueCollection 및 (2) 키 값 쌍 등이 주어진 쿼리 문자열을 만드는 모든 .NET 클래스 .
Kenny Evitt 2016

57

이 시도:

var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx");

var postData = "thing1=hello";
    postData += "&thing2=world";
var data = Encoding.ASCII.GetBytes(postData);

request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;

using (var stream = request.GetRequestStream())
{
    stream.Write(data, 0, data.Length);
}

var response = (HttpWebResponse)request.GetResponse();

var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

6
차라리 다음과 같이 작성합니다. request.Method = WebRequestMethods.Http.Post;
Totalys

사용 응답하기 전에 request.HaveResponse을 확인
마르코 판타지아에게

@MarcoFantasia 확인 request.HaveResponse하면 실제로 먼저 응답을 받아야 합니다. HttpWebResponse response = (HttpWebResponse) request.GetResponse(); if (request.HaveResponse) { ... }
네 배리

41

양식을 잘못 인코딩하고 있습니다. 다음 값만 인코딩해야합니다.

StringBuilder postData = new StringBuilder();
postData.Append("username=" + HttpUtility.UrlEncode(uname) + "&");
postData.Append("password=" + HttpUtility.UrlEncode(pword) + "&");
postData.Append("url_success=" + HttpUtility.UrlEncode(urlSuccess) + "&");
postData.Append("url_failed=" + HttpUtility.UrlEncode(urlFailed));

편집하다

나는 틀렸다. 따르면 RFC1866 섹션 8.2.1 모두 이름과 값은 인코딩되어야한다.

그러나 주어진 예제의 경우 이름에 인코딩해야하는 문자가 없으므로이 경우 코드 예제가 정확합니다.)

질문의 코드는 웹 서버가 디코딩 할 수없는 이유 인 등호를 인코딩하므로 여전히 올바르지 않습니다.

더 적절한 방법은 다음과 같습니다.

StringBuilder postData = new StringBuilder();
postData.AppendUrlEncoded("username", uname);
postData.AppendUrlEncoded("password", pword);
postData.AppendUrlEncoded("url_success", urlSuccess);
postData.AppendUrlEncoded("url_failed", urlFailed);

//in an extension class
public static void AppendUrlEncoded(this StringBuilder sb, string name, string value)
{
    if (sb.Length != 0)
        sb.Append("&");
    sb.Append(HttpUtility.UrlEncode(name));
    sb.Append("=");
    sb.Append(HttpUtility.UrlEncode(value));
}

감사합니다.하지만 이제 다음과 같은 오류가 발생합니다. 원격 서버에서 오류를 반환했습니다. (412) 전제 조건 실패.
wsplinter

나는 많이 google :) 그러나 나는 그것을 고쳤고, 더러운 방식으로하고 있습니다. HttpWebRequest는 아니지만 String 내부에 html 양식을 작성하고 브라우저에 작성합니다 (onload에서 제출을 수행합니다).
wsplinter 2013

3
@wsplinter : 사전 조건 실패에 대한 솔루션을 문서화하면 다른 사람들에게 도움이 될 것입니다.
jgauffin

@jgauffin : 라디오 버튼 값을 어떻게 게시합니까? 동일한 그룹에 속하는 3 개의 라디오 버튼이 있다고 가정합니다.
아사드 Refai

1
분명히 이것은 UrlEncode가 @와 같은 기호를 API 호출에서 허용되지 않는 코드로 변경하기 때문에 예상대로 작동하지 않았습니다. @ user3389691의 답변에 표시된 NameValueCollection을 사용하도록 변경하면 완벽하게 작동합니다.
dhruvpatel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.