Jeroen Wiert Pluimers
Jeroen Wiert Pluimers

Reputation: 24493

System.Net.WebClient not throwing error during UploadString to invalid url?

Given this code, I expected an exception to happen, but System.Net.WebClient.UploadString returns an empty string into result.

I'm obviously overlooking something, but what?

using System.Net;
using System.Text;

[TestClass()]
public class WebClientTests
{
    [TestMethod()]
    public void WebClientUploadStringToInvalidUrlTest()
    {
        var webClient = new WebClient { Encoding = Encoding.UTF8 };
        var result =  webClient.UploadString("{{foo-bar}}", "snafu");
        Assert.IsTrue(string.IsNullOrEmpty(result));
    }

    [TestMethod()]
    [ExpectedException(typeof(ArgumentNullException))]
    public void WebClientUploadStringToNullUrlTest()
    {
        var webClient = new WebClient { Encoding = Encoding.UTF8 };
        string url = null;
        var result = webClient.UploadString(url, "snafu");
        Assert.IsTrue(string.IsNullOrEmpty(result));
    }

}

edit: as per suggestion by hanno added a null test as well, and this throws an ArgumentNullException which I kind of expected.

Upvotes: 4

Views: 1090

Answers (1)

rene
rene

Reputation: 42453

It is only possible to answer this by looking at internal implementation details.

In preparation the WebClient class tries to build an real Uri from the string you provided in that overload to UploadString.

The code roughly looks like this in the 4.0 framework:

 if (!Uri.TryCreate(path, UriKind.Absolute, out address))
 {
      return new Uri(Path.GetFullPath(path));
 } 

The TryCreate returns false for your non URI conforming path so it falls back to creating an Uri for the Path.GetFullPath of your string, which returns an Uri with a file:// scheme.

Internally the WebClient uses WebRequest.Create to obtain a WebRequest that is capable of handling the given scheme. In your case a FileWebRequest will be returned (due to the scheme being file://)

Stripping all checks and internal plumbing the following simplified call sequence is executed after the Uri is obtained:

        var fwr = (FileWebRequest) WebRequest.Create(new Uri(Path.GetFullPath(path)));
        fwr.Method ="POST";
        var us = fwr.GetRequestStream();
        var upload = Encoding.UTF8.GetBytes("snafu");
        us.Write(upload,0,upload.Length);
        us.Close();
        var sr = new StreamReader(fwr.GetResponse().GetResponseStream());
        return sr.ReadToEnd();

Which doesn't throw an exception and returns an empty string.

Your assumption "I expect this to throw an exception" is wrong.

Upvotes: 3

Related Questions