2017-05-15 8 views
2

나는 jsons을 수락 API를 서버에 HTTP 요청을 할 수있는 기능을 가지고 :request.GetRequestStream()는 "값은 null 일 수 없습니다"예외를 발생

private static string DoRequest(object objToSend, string Url) 
     { 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); 
      request.Method = "POST"; 
      request.ContentType = "application/json"; 
      request.Accept = "application/json"; 
      var jsonString= Obj2Json(objToSend); 
      if (string.IsNullOrEmpty(jsonString)) 
       throw new ArgumentNullException("objToSend", "Objcet was converted to json string and produces an empty string"); 
      var buffer = Encoding.UTF8.GetBytes(jsonString); 
      request.ContentLength = buffer.Length; 
      using (var stream = request.GetRequestStream()) 
      { 
       stream.Write(buffer, 0, buffer.Length); 
      } 
      var response = (HttpWebResponse)request.GetResponse(); 
      var sResponse = new System.IO.StreamReader(response.GetResponseStream()).ReadToEnd(); 

      return sResponse; 
     } 

나는 줄 실행하면 :

using (var stream = request.GetRequestStream()) 

mscorlib.dll에서 예외 : 'System.ArgumentNullException'이 있습니다 ("값은 null이 될 수 없습니다."). System.ArgumentNullException. 스택 트레이스의

말한다 한 줄이 있었다 :

"System.Enum.TryParseEnum (유형 enumType, 문자열 값, 부울하여 ignoreCase, EnumResult & parseResult)"

예외 F10 키를 클릭하면 사라집니다.

왜 예외가 던져 졌는지 아무도 모르는 사람이 있습니까?

, 즉 시간의 거대한 낭비 후 stream.Write()

의 사용에 전에 나는 그것이 GetRequestStream()에서 예외를 throw 것을 강조하고 싶은

입니다 , 나는 excaption가에서 던진 것을 발견 system.dll의 일부인 ServicePointManager.cs. 여기 기능하고있다 예외가 발생합니다 여기

private static void LoadDisableStrongCryptoConfiguration() 
{ 
    try 
    { 
     bool disableStrongCryptoInternal = false; 
     int schUseStrongCryptoKeyValue = 0; 

     if (LocalAppContextSwitches.DontEnableSchUseStrongCrypto) 
     { 
      //.Net 4.5.2 and below will default to false unless the registry key is specifically set to 1. 
      schUseStrongCryptoKeyValue = 
       RegistryConfiguration.GlobalConfigReadInt(strongCryptoValueName, 0); 

      disableStrongCryptoInternal = schUseStrongCryptoKeyValue != 1; 
     } 
     else 
     { 
      // .Net 4.6 and above will default to true unless the registry key is specifically set to 0. 
      schUseStrongCryptoKeyValue = 
       RegistryConfiguration.GlobalConfigReadInt(strongCryptoValueName, 1); 

      disableStrongCryptoInternal = schUseStrongCryptoKeyValue == 0; 
     } 

     if (disableStrongCryptoInternal) 
     { 
      // Revert the SecurityProtocol selection to the legacy combination. 
      s_SecurityProtocolType = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; 
     } 
     else 
     { 
      s_SecurityProtocolType = 
       SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; 

      string appSetting = RegistryConfiguration.AppConfigReadString(secureProtocolAppSetting, null); 

      SecurityProtocolType value; 
      try 
      { 
       value = (SecurityProtocolType)Enum.Parse(typeof(SecurityProtocolType), appSetting); 
       ValidateSecurityProtocol(value); 
       s_SecurityProtocolType = value; 
      } 
      // Ignore all potential exceptions caused by Enum.Parse. 
      catch (ArgumentNullException) { } 
      catch (ArgumentException) { } 
      catch (NotSupportedException) { } 
      catch (OverflowException) { } 
     } 

     disableStrongCrypto = disableStrongCryptoInternal; 
    } 
    catch (Exception e) 
    { 
     if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) 
     { 
      throw; 
     } 
    } 
} 

전체 호출 스택입니다

가 mscorlib.dll System.Enum.TryParseEnum (System.Type enumType, 문자열 값, 부울하여 ignoreCase! , 심판 System.Enum.EnumResult parseResult) 가 mscorlib.dll! System.Enum.Parse (System.Type enumType, 문자열 값, 부울하여 ignoreCase) System.dll을! System.Net.ServicePointManager.LoadDisableStrongCryptoConfiguration() System.dll! System.Net.ServicePointManager.EnsureConfigurationLoaded() System.dll System.Net.ServicePointManager.SecurityProtocol.get() System.dll! System.Net.TlsStream.ProcessAuthentication (System.Net.LazyAsyncResult result) System.dll System.Net.TlsStream.Write (byte [] buffer, int 오프셋, int 크기) System.Net.PooledStream.Write (byte [] 버퍼, int 오프셋, int 크기) System.Net.ConnectStream.WriteHeaders (bool async) System.dll! System.Net.HttpWebRequest.EndSubmitRequest() System.dll System.Net.HttpWebRequest.SetRequestSubmitDone (System.Net.ConnectStream submitStream) System.dll! System.Net.Connection.CompleteConnection (bool async, System.Ne t.HttpWebRequest 요청) System.dll을! System.Net.Connection.CompleteStartConnection (부울 비동기, System.Net.HttpWebRequest HttpWebRequest를) System.dll을! System.Net.Connection.CompleteStartRequest (부울 onSubmitThread, System.Net. HttpWebRequest를 요청, System.Net.TriState needReConnect) System.dll을! System.Net.Connection.SubmitRequest (System.Net.HttpWebRequest 요청, 부울 forcedsubmit) System.dll을! System.Net.ServicePoint.SubmitRequest (시스템. 그물.HttpWebRequest를 요청, 문자열 connName 여기서) System.dll을! System.Net.HttpWebRequest.SubmitRequest (System.Net.ServicePoint servicePoint) System.dll을! System.Net.HttpWebRequest.GetRequestStream ( 밖으로 System.Net.TransportContext 컨텍스트) System.dll을! System.Net.HttpWebRequest.GetRequestStream() RivhitApi.dll! RivhitApi.RivhitService.DoRequest (객체 objToSend, 문자열 URL) 라인 59

답변

1

the documentation에 따르면, 상기 방법은 Write를 슬로우 버퍼가 널인 경우 ArgumentNullException. 귀하의 경우에는 bJsonReq이 null임을 의미합니다.

Write으로 전화하기 전에 null이 아닌지 확인하십시오.

+0

'bJsonReq'이 (가) null이 아닙니다. F10 키를 clicing하여 완벽하게 작동합니다 = 서버에서 응답을 올바르게받습니다. 또한 - bJsonReq를 사용하기 전에 "GetRequestStream()"부분에서 예외를 throw합니다. – Developer

+0

아마도 비어 있습니까? –

+0

@ 개발자는 다른 스레드 또는 비동기 적으로 실행되는 코드에 의해 설정되고 있습니까? 이는 라인 단위 디버깅에서 왜 작동 하는지를 설명 할 수 있지만 정상적으로 실행되지는 않습니다. –

0

this microsoft document에 따르면이 코드 줄을 추가하면 문제가 해결됩니다.

private const string DisableCachingName = @"TestSwitch.LocalAppContext.DisableCaching"; 
private const string DontEnableSchUseStrongCryptoName = @"Switch.System.Net.DontEnableSchUseStrongCrypto"; 
AppContext.SetSwitch(DisableCachingName, true); 
AppContext.SetSwitch(DontEnableSchUseStrongCryptoName, true); 

이 문서에는이 정의를 정의 할 수있는 몇 가지 옵션이 있습니다.

하지만 죄수는 보안이 약한 것으로 보입니다. 더 똑똑한 솔루션을 찾고 있는데 ServicePointManagerSecurityProtocolType null이 아닌 방식으로 설정하는 방법을 찾고 있습니다. 당분간 나는 그런 사람을 찾지 못한다.