function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Rennie ReidRennie Reid 

Web to Lead with .NET server post no longer working.

I have a contact form on a client's website that uses the web-to-lead feature to add a lead to SalesForce. The post is done via a .NET server post. This was working fine until recently when it just sort of stopped working. The weird thing is that it still works using the basic form that is auto-generated from the SF admin (just running locally in a browser), even when I customize that form so that the fields are exactly the same as my .NET form. I added the debug=1 parameter in both cases, and in both cases, I am getting the exact same response. But the requests from the basic form are going into SF while the requests from the .NET form are not, though in debug mode it is not returning anything that looks like an error. I'm not sure if this could be related, but one thing that I did notice with the auto-generated form is that (though it does go through) the page it posts to has HTTPS crossed out in Google Chrome with a message that says, "Your connection to this site is not private because the site loaded an insecure script."

Below is the .NET code I am using:

string postURL = "";
                NameValueCollection postData = new NameValueCollection();
                postData.Add("oid", "00Dd0000000enW3");
                postData.Add("retURL", "");
                postData.Add("first_name", model.FirstName);
                postData.Add("last_name", model.LastName);
                postData.Add("email", model.Email);
                if (!string.IsNullOrEmpty(model.Phone))
                    postData.Add("phone", model.Phone);
                if (!string.IsNullOrEmpty(model.Company))
                    postData.Add("company", model.Company);
                postData.Add("city", model.City);
                postData.Add("00Nd00000051cEi", model.State);
                postData.Add("description", model.Message);
                postData.Add("lead_source", "Cheetah Website");
                postData.Add("debug", "1");
                postData.Add("submit", "Submit");
                if (!string.IsNullOrEmpty(model.Subject))
                    postData.Add("00Nd0000006ddpY", model.Subject.Substring(4));

                WebClient http = new WebClient();
                    http.Encoding = Encoding.UTF8;
                    System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls11;
                    http.UploadValues(postURL, "POST", postData);
                    TempData["mailMessage"] = "success";
                catch (Exception ex)
                    TempData["mailError"] = ex.Message;
When I look at the http.UploadValuse result (converted from a byte array to a string) in the debugger, I get what looks like a standard redirect page or a list of name value pairs exactly the same as with the form below (if debug=1). And here is the modified version of the auto-generated form that is working.
<!--  ----------------------------------------------------------------------  -->
<!--  NOTE: Please add the following <META> element to your page <HEAD>.      -->
<!--  If necessary, please modify the charset parameter to specify the        -->
<!--  character set of your HTML page.                                        -->
<!--  ----------------------------------------------------------------------  -->

<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=UTF-8">

<!--  ----------------------------------------------------------------------  -->
<!--  NOTE: Please add the following <FORM> element to your page.             -->
<!--  ----------------------------------------------------------------------  -->

<form action="" method="POST">

<input type=hidden name="oid" value="00Dd0000000enW3">
<input type=hidden name="retURL" value="">
<input type=hidden name="lead_source" value="Cheetah Website">
<!--<input type=hidden name="debug" value="1">-->

<!--  ----------------------------------------------------------------------  -->
<!--  NOTE: These fields are optional debugging elements. Please uncomment    -->
<!--  these lines if you wish to test in debug mode.                          -->
<!--  <input type="hidden" name="debug" value=1>                              -->
<!--  <input type="hidden" name="debugEmail" value="">     -->
<!--  ----------------------------------------------------------------------  -->

<label for="first_name">First Name</label><input  id="first_name" maxlength="40" name="first_name" size="20" type="text" /><br>

<label for="last_name">Last Name</label><input  id="last_name" maxlength="80" name="last_name" size="20" type="text" /><br>

<label for="email">Email</label><input  id="email" maxlength="80" name="email" size="20" type="text" /><br>

<label for="company">Company</label><input  id="company" maxlength="40" name="company" size="20" type="text" /><br>

<label for="city">City</label><input  id="city" maxlength="40" name="city" size="20" type="text" /><br>

<label for="state">State/Province</label><input  id="state" maxlength="20" name="00Nd00000051cEi" size="20" type="text" /><br>

<textarea id="description" name="description"></textarea>

<input type="submit" name="submit">


Daniel BallingerDaniel Ballinger
At a guess, since it has been working then stopped, I suspect this is the Require TLS 1.1 or higher for HTTPS connections critial update.

When on, any attempt to connect using TLS 1.0 will fail. .NET 3.5 doesn't support TLS 1.1 or higher. .NET 4.5 requires a registry key or explict code to enable TLS 1.1 and 1.2. See Callouts to web services started failing with CalloutException: Server chose TLSv1 (
Rennie ReidRennie Reid
I did see this when I was searching the forum about information about this before. The code I posted above does include the line
System.Net.ServicePointManager.SecurityProtocol =System.Net.SecurityProtocolType.Tls11;

I saw in the documentation that something slightly different was used, so I tried this:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

However, it didn't work in either case. I am currently testing on localhost using IIS Express, and the build for the project is set to .NET 4.5, so it seems like it should work.

But the other thing that makes me think that this isn't the issue is that I am not getting an exception when I call http.UploadValues. Instead, I am getting a response back, which, when I convert it from a byte array to a string, looks like the same thing that the request returns when I run it on a basic form in a browser (a JS redirect to the specified return address normally and a list of the fields passed if debug=1). I would think that if it were a TLS issue, I wouldn't be able to connect to the server at all.
Daniel BallingerDaniel Ballinger

OK, I missed that you were already setting the security protocol.

What happens if you set  debugEmail in the post data to your email address? Do you get an email from the .NET code?

Are there any triggers etc... in the Org that might be processing the leads after they are inserted? Although that wouldn't explain why it works from a browser but not .NET.

You could try capturing the debug log in Salesforce by enabling tracing for the configured Default Lead Owner.

Rennie ReidRennie Reid
Actually, the email made me realize that I apparently already fixed it--the TLS change makes it work! The leads just weren't showing under "Recent Leads" on the leads Home page. But they are visible when I view the specific queues they were added to.

Thanks for the help!