2012-06-22 2 views
20

나는 몇 가지 코드 단위 테스트에 노력하고, 나는이를 교체해야합니다WebRequest에 쿠키를 추가하는 방법은 무엇입니까?

HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri); 
    httpWebRequest.CookieContainer = new CookieContainer(); 

기본적으로

WebRequest webRequest = WebRequest.Create(uri); 
    webRequest.CookieContainer = new CookieContainer(); 

으로, 어떻게 얻을 않는 HttpWebRequest를 사용하지 않고 요청에 쿠키? 이 같은 뭔가

+0

:

public static bool TryAddCookie(this WebRequest webRequest, Cookie cookie) { HttpWebRequest httpRequest = webRequest as HttpWebRequest; if (httpRequest == null) { return false; } if (httpRequest.CookieContainer == null) { httpRequest.CookieContainer = new CookieContainer(); } httpRequest.CookieContainer.Add(cookie); return true; } 

이렇게하면 전체 코드를 사용하는 방법이다이 쿠키를 사용하여 문자열을 다운로드하는 기능입니다 쿠키는 HTTP 개념이기 때문에 어렵습니다. 이 변경을해야하는 이유가 있습니까? – dlev

+0

@dlev - WebRequest는 uri를 기반으로 HttpWebRequest를 생성합니다. 따라서 내 자신의 WebRequest 객체를 조롱하거나 WebRequest를 반환하는 자체 URI를 등록하려는 경우이 메서드를 HttpWebRequest 객체 만 사용하도록 제한하고 싶지는 않습니다. –

+1

'webRequest'의 런타임 타입이'HttpWebRequest'라고 이해합니다. 그러나'CookieContainer'에 접근하려면 컴파일 타임 타입이'HttpWebRequest'이어야합니다. 또한, 당신은 HTTP에 자신을 제한하지 않는다고 언급하지만, 쿠키는 HTTP 구조이기 때문에 그다지 의미가 없습니다 (처음에는'WebRequest'가 없다는 이유입니다). – dlev

답변

22

, 당신은 서면으로 고려할 가능성이있는 extension method :

public static bool TryAddCookie(this WebRequest webRequest, Cookie cookie) 
{ 
    HttpWebRequest httpRequest = webRequest as HttpWebRequest; 
    if (httpRequest == null) 
    { 
     return false; 
    } 

    if (httpRequest.CookieContainer == null) 
    { 
     httpRequest.CookieContainer = new CookieContainer(); 
    } 

    httpRequest.CookieContainer.Add(cookie); 
    return true; 
} 

그럼 당신이 가질 수있는 코드와 같은 :

WebRequest webRequest = WebRequest.Create(uri); 
webRequest.TryAddCookie(new Cookie("someName","someValue")); 
+1

이 코드는 "매개 변수 '{0}'을 (를) 빈 문자열로 사용할 수 없습니다." 온라인 httpRequest.CookieContainer.Add (쿠키); 어떤 생각? –

+2

@drdigit 도메인을 포함하는 쿠키를 만들지 않았기 때문입니다. 또한, 나는 오류 문자열이 BCL의 버그라고 확신한다. (불행히도, 4.5에서 지속되는 것으로 보인다) – dlev

+0

답장을 보내 주셔서 감사합니다. –

3

보십시오 : 귀하의 의견을 바탕으로

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/default.html"); 
request.CookieContainer.Add(new Cookie("ConstoCookie", "Chocolate Flavour")); 
+0

위해 도움이되었습니다입니다.그것은 새로운 WebRequest를 생성하고이 요청에 대한 쿠키를 설정하는 것입니다. 그리고 질문의 태그를보고 단위 테스트에서 요청을 실행합니다. –

+2

이것은 '객체 참조가 ...로 설정되지 않았습니다.'라는 오류를 발생시킵니다. 먼저 우리는'request.CookieContainer = new CookieContainer(); '가 필요할 수 있습니다. 그러면 Add 메소드가 제대로 작동합니다. – shashwat

6

WebRequest는 CookieContainer 속성이없는 추상 클래스입니다. 또한 헤더 컬렉션 (구현되지 않은 예외)을 사용할 수 없으므로 webRequest.Headers.Add ("Cookie", "...")와 같은 모든 시도가 실패합니다.

죄송합니다.하지만 WebRequest에서 쿠키를 사용할 수는 없습니다.

HttpWebRequest에 스틱을 추가하고 헤더 집합을 사용하여 원하는만큼 많은 쿠키를 추가/편집하십시오!

+0

그건 내가 두려워했던거야. –

+0

나는 그것을하지 않았다 :) 당신의 "if then addcookies"요구 사항은 HttpWebRequest.Headers.Add ("Cookie", "...")에 의해 다룰 수있다. –

0

dlev의 응답이 끝났지 만 솔루션 구현에 문제가있었습니다 ("매개 변수 '{0}'은 (는) 빈 문자열이 될 수 없습니다.)), 그래서 누군가 다른 유사한 문제가있는 경우를 대비하여 전체 코드를 작성하기로했습니다. .

목표는 HTML을 문자열로 가져 오는 것이지만 웹 요청에 쿠키를 추가해야했습니다.

public static string DownloadString(string url, Encoding encoding, IDictionary<string, string> cookieNameValues) 
{ 
    using (var webClient = new WebClient()) 
    { 
     var uri = new Uri(url); 
     var webRequest = WebRequest.Create(uri); 
     foreach(var nameValue in cookieNameValues) 
     { 
      webRequest.TryAddCookie(new Cookie(nameValue.Key, nameValue.Value, "/", uri.Host)); 
     }     
     var response = webRequest.GetResponse(); 
     var receiveStream = response.GetResponseStream(); 
     var readStream = new StreamReader(receiveStream, encoding); 
     var htmlCode = readStream.ReadToEnd();     
     return htmlCode; 
    } 
} 

우리는 dlev의 대답에서 코드를 사용 :

var cookieNameValues = new Dictionary<string, string>(); 
cookieNameValues.Add("varName", "varValue"); 
var htmlResult = DownloadString(url, Encoding.UTF8, cookieNameValues); 
관련 문제