0

WSDL이없고 HttpWebRequest를 사용해야하는 .NET Compact Framework 3.5 Project에서 Webservice를 사용하려고합니다. 2 개의 장치와 에뮬레이터에서 코드를 시험해 보았습니다.하지만 매번 동일한 예외가 발생했습니다. 이유는 알지 못합니다..Net CF/HttpWebRequest 및 "WebException이 처리되지 않았습니다."

첫째, 내 코드 : 라인에서

internal void SendSms() 
    { 
     HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"https://username:[email protected]/RPC2"); 
     req.Method = @"POST"; 
     req.ContentType = @"text/xml"; 
     req.ContentLength = Body.Length; 
     using (Stream stream = req.GetRequestStream()) 
     using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) 
     { 
      writer.Write(Body); 
     } 
     using (Stream responseStream = req.GetResponse().GetResponseStream()) 
     using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8)) 
     { 
      string result = reader.ReadToEnd(); 
     } 
    } 

"사용 (스트림 스트림 = req.GetRequestStream())"나는 다음과 같은 예외가 나는 이유를 파악 할수 없어 :

시스템 .Net.WebException 은 { "네트워크에 연결을 설정할 수 없습니다."}

스택 트레이스 :

을 System.Net.HttpWebRequest.finishGetRequestSt에서 System.Windows.Forms.MenuItem에서 SipMSGate.UI.Form1.menuItem1_Click에서 SipMSGate.UI.MainFormController.SendSms()에서 System.Net.HttpWebRequest.GetRequestStream() 에서 묶음() (객체 송신자있는 EventArgs E) System.Windows.Forms.Form.WnProc (WM의 WM, INT32의 wParam, INT32의 lParam에서 System.Windows.Forms.Menu.ProcessMnuProc (컨트롤 ctlThis, WM의 WM, INT32의 wParam, INT32의 lParam) 에서 .OnClick (있는 EventArgs E) ) at System.Windows.Forms.Control._InternalWnProc (WM wm, Int32 wParam, Int32 lParam) at Microsoft.AGL.Forms.EVL.EnterMainLoop (IntPtr hwnMain) at System.Windows.Forms.Application.Run (Form fm) at SipMSGate.Program.Main()

상태 :

System.Net.WebExceptionStatus.ConnectFailure

나는 장치에와 에뮬레이터에서 인터넷 익스플로러를 사용할 수 있습니다, 그래서 내가 인터넷에 연결되어 있다고 생각합니다.

어떤 아이디어가 잘못 되었습니까? 아니면 내 코드에서 잊어 버린 내용입니까?

것보다 훨씬

twickl

다음

지금이 장치에 xception 그들 모두가 인터넷에 연결가있는 에뮬레이터 이미지를 제공 Yakimych의 코드를 포함한 전체 코드 :

HTTPS를 사용하는 경우
using System.Drawing; 
using System.IO; 
using System.Net; 
using System.Security.Cryptography.X509Certificates; 
using System.Text; 
using System.Windows.Forms; 

namespace httpreqTest 
{ 
    public partial class Form1 : Form 
    { 
     private HttpWebRequest _req; 
     private bool _ignoreCertificateErrors; 
     private string _errorMessage; 
     private const string Body = 
     "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>samurai.SessionInitiate</methodName><params><param><value><struct><member><name>LocalUri</name><value><string></string></value></member><member><name>RemoteUri</name><value><string></string></value></member><member><name>TOS</name><value><string>text</string></value></member><member><name>Content</name><value><string>This is a Test</string></value></member><member><name>Schedule</name><value><string></string></value></member></struct></value></param></params></methodCall>"; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     this._ignoreCertificateErrors = true; 
     ASCIIEncoding encoding = new ASCIIEncoding(); 
     byte[] byte1 = encoding.GetBytes(Body); 
     CreateWebRequestObject(@"https://user:[email protected]/RPC2"); 
     _req.Method = @"POST"; 
     _req.ContentType = @"text/xml"; 
     _req.ContentLength = byte1.Length; 
     using (Stream stream = _req.GetRequestStream()) 
     using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) 
     { 
      writer.Write(Body); 
     } 
     using (Stream responseStream = _req.GetResponse().GetResponseStream()) 
     using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8)) 
     { 
      string result = reader.ReadToEnd(); 
     } 
    } 

    public bool CreateWebRequestObject(string Url) 
    { 
     try 
     { 
      this._req = (HttpWebRequest)System.Net.WebRequest.Create(Url); 
      if (this._ignoreCertificateErrors) 
       ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy(); 
     } 
     catch (Exception ex) 
     { 
      this._errorMessage = ex.Message; 
      return false; 
     } 
     return true; 
    } 

    /// <summary> 
    /// Internal object used to allow setting WebRequest.CertificatePolicy to 
    /// not fail on Cert errors 
    /// </summary> 
    internal class AcceptAllCertificatePolicy : ICertificatePolicy 
    { 
     public AcceptAllCertificatePolicy() 
     { 

     } 
     public bool CheckValidationResult(ServicePoint sPoint, X509Certificate cert, WebRequest wRequest, int certProb) 
     { 
      // *** Always accept 
      return true; 
     } 
    } 
} 

}

+0

아마도 문제를 일으키는 것이 https의 (들)일까요? 이러한 연결을 만들기 전에 인증서의 유효성을 검사해야합니다. –

+0

완전히 관련이 없지만'req.ContentLength'를 수동으로 설정할 필요는 없습니다. –

+0

흠, 콘텐츠 길이를 설정하지 않는 한 콘텐츠 길이가 -1이 될 수 없다는 예외가 발생합니다. – CaptnCrash

답변

5

을 당신은 콘텐츠 길이 헤더에 잘못된 값을 전달하고 있습니다. 바이트의 내용 길이는 문자열의 유니 코드 문자 수가 아닙니다 (StreamWriter도 UTF8 프리앰블을 추가 함). Preamble을 사용하지 않고 Content-Length 헤더 값을 설정하기 전에 문자열을 바이트 배열로 변환하는 것이 좋습니다. 또한 req.Credentials 속성을 사용하여 사용자 이름과 비밀번호를 전달하는 것이 좋습니다.

internal void SendSms() 
{ 
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"https://api.sipgate.net/RPC2"); 
req.Credentials = new NetworkCredential("username", "password"); 
req.Method = @"POST"; 
req.ContentType = @"text/xml"; 
byte[] data = Encoding.UTF8.GetBytes(Body); 
req.ContentLength = data.Length; 
using(Stream stream = req.GetRequestStream()) 
    stream.Write(data, 0, data.Length); 
using(Stream responseStream = req.GetResponse().GetResponseStream()) 
using(StreamReader reader = new StreamReader(responseStream, Encoding.UTF8)) 
{ 
    string result = reader.ReadToEnd(); 
} 
} 
3

는 사실, 당신은 인증서의 유효성을 검사해야합니다. 이를 수행하려면 AcceptAllCertificatePolicy 클래스를 만들고 코드 전의 인증서 정책을 설정하십시오. ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy(); 이 방법으로 문제가 해결되는지 http://www.west-wind.com/weblog/posts/48909.aspx

참조 :

당신은 샘플과 여기에 클래스 코드를 찾을 수 있습니다.

+0

안녕하세요, 코드를 사용해 보았지만 문제가 해결되지 않았습니다. 나는 전체적으로 동일한 Exception을 얻는다. 모든 mor 아이디어? 이것이 인증 문제인지 확인하는 방법이 있습니까? 예외가 여전히 "네트워크에 연결할 수 없습니다." 내 장치에 인터넷 연결이 설정되어 있지만. 2.0 및 3.5 Compact Framework 프로젝트를 사용해 보았습니다. – CaptnCrash

+2

먼저, 일반적인 http : // 연결을 할 수 있는지 확인하십시오. 그러면 인터넷 연결 문제가 배제됩니다. IE가 연결할 수 있기 때문에 .net 앱이 연결할 수있는 것은 아닙니다. – Cheeso

1

콘텐츠 유형이 text/xml이 아니어야합니까 ?? ??

+0

예, 죄송합니다 ... 문제를 해결했지만 문제는 해결되지 않았습니다. – CaptnCrash

1

HTTP/HTTPS가 FTP와 동일한 URL의 사용자 이름 암호 구성을 지원한다고 생각하지 않습니다.기본 인증을 수행하려는 경우 헤더를 통해 인증을 전달해야합니다. 이것을 시도하십시오 :

req.Credentials = new NetworkCredential("username","password"); 

이것은 "기본 인증"자격 증명을 웹 호스트로 전달합니다. 당신은 여기에 대한 자세한 내용을보실 수 있습니다 :

http://msdn.microsoft.com/en-us/library/system.net.networkcredential.aspx

0

동일한 오류가 발생했습니다. 당신은 당신이 WebResponse를 작성, using(Stream responseStream = req.GetResponse().GetResponseStream())

WebResponse ws = request.GetResponse(); 

// do some stuff 

ws.close(); 

전화를해야하지만, 당신은 그것을 닫지 마십시오. 모바일 장치에서는 타임 아웃 예외가 빠르게 발생합니다.

관련 문제