Request.GetRequestStream () throws a "Value cannot be null"

I have a function to make an HTTP request to api servers that accept jsons:

 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;
        }

      

When I run the line:

using (var stream = request.GetRequestStream())

      

I have an exception: 'System.ArgumentNullException' in mscorlib.dll ("The value cannot be null.") System.ArgumentNullException.

there was one line in StackTrace that reads:

"System.Enum.TryParseEnum (Enter enumType, String value, Boolean ignoreCase, EnumResult & parseResult)"

The exception is cleared by pressing the F10 key.

Does anyone know why the exception was thrown?

I want to emphasize that it throws an exception in GetRequestStream (), which is previously used to use stream.Write ()

After wasting a huge amount of time, I found that the exclusion was selected from ServicePointManager.cs, which is part of system.dll. This function throws an exception:

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;
        }
    }
}

      

here is the complete call stack

mscorlib.dll! System.Enum.TryParseEnum (System.Type enumType, string value, bool ignoreCase, ref System.Enum.EnumResult parseResult) mscorlib.dll! System.Enum.Parse (System.Type enumType, string value, bool 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 offset, int size) System.dll! System.Net.PooledStream.Write (byte [] buffer, int offset, int size) System.dll! 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.Net.HttpWebRequest request) System.dll! System.Net.Connection.CompleteStartConnection (bool async, System.Net.HttpWebRequest httpWebRequest) System.dll! System.Net.Connection.CompleteStartRequest (BOOL onSubmitThread, System.Net.HttpWebRequest request, System.Net.TriState needReConnect) System.dll! System.Net.Connection.SubmitRequest (System.Net.HttpWebRequest request, bool forcedsubmit) System.dll! System.Net.ServicePoint.SubmitRequest (System.Net.HttpWebRequest request, string connName) System.dll! System.Net.HttpWebRequest.SubmitRequest (System.Net.ServicePoint Servicepoint) System.dll! System.Net.HttpWebRequest.GetRequestStream (from System.Net.TransportContext Context) System.dll! System.Net.HttpWebRequest.GetRequestStream () RivhitApi.dll! RivhitApi.RivhitService.DoRequest (objToSend object, Url string) Line 59System.Net.ServicePoint.SubmitRequest (System.Net.HttpWebRequest request, string connName) System.dll! System.Net.HttpWebRequest.SubmitRequest (System.Net.ServicePoint Servicepoint) System.dll! System.Net.HttpWebRequest.GetRequestStream (from System.Net.TransportContext Context) System.dll! System.Net.HttpWebRequest.GetRequestStream () RivhitApi.dll! RivhitApi.RivhitService.DoRequest (objToSend object, Url string) Line 59System.Net.ServicePoint.SubmitRequest (System.Net.HttpWebRequest request, string connName) System.dll! System.Net.HttpWebRequest.SubmitRequest (System.Net.ServicePoint Servicepoint) System.dll! System.Net.HttpWebRequest.GetRequestStream (from System.Net.TransportContext Context) System.dll! System.Net.HttpWebRequest.GetRequestStream () RivhitApi.dll! RivhitApi.RivhitService.DoRequest (objToSend object, Url string) Line 59

+3


source to share


2 answers


According to the documentation , the method Write

will be called ArgumentNullException

when the buffer is null. In your case, this means it bJsonReq

is null.



Write

Make sure it is nonzero before calling .

+1


source


according to this Microsoft doc adding that these lines of code fix the problem.

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

      



this document has a few more options to set this protection.

but the cons are likely to reduce security. I'm looking for a smarter solution, perhaps setting the ServicePointManager in some way such that the SecurityProtocolType is not empty. At the moment I do not find anyone like that.

0


source







All Articles