2014-06-06 1 views
4

Учитывая этот код, я ожидал, что произойдет исключение, но System.Net.WebClient.UploadString возвращает пустую строку в result.System.Net.WebClient не бросает ошибку во время UploadString на недопустимый URL?

Я, очевидно, что-то пропускаю, но что?

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

} 

редактировать: в per suggestion по hanno добавлен тест null, а также, и это бросает ArgumentNullException, который я отчасти ожидал.

+1

Просто для того, чтобы быть уверенным: этот тест проходит точно так же, как написано ?! Обновление: Это так. – usr

+0

Согласно [MSDN] (http://msdn.microsoft.com/en-us/library/0645045y (v = vs.110) .aspx), он должен выдать исключение. Бросает ли он, если вы передаете null в метод? – Hanno

+0

Интересно, что, если введен другой URL-адрес; возможно, эта форма в URI делает что-то странное? (try ...) –

ответ

2

На это можно ответить, посмотрев внутренние детали реализации.

В процессе подготовки класс WebClient пытается построить реальный Uri из строки, указанной в этой перегрузке, до UploadString.

Код примерно выглядит в 4.0 рамках:

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

В TryCreate возвращается false для вашего отсутствия URI соответствующей пути, чтобы он возвращается к созданию Uri для Path.GetFullPath вашей строки, которая возвращает Uri с file:// scheme.

Внутренне WebClient использует WebRequest.Create для получения WebRequest, который способен обрабатывать данную scheme. В вашем случае FileWebRequest будет возвращен (из-за схемы будучи file://)

Зачистка все проверки и внутренняя сантехника следующая упрощенная последовательность вызова выполняется после того, как Uri получается:

 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(); 

который не выдает исключение и возвращает пустую строку.

Ваше предположение «Я ожидаю, что это вызовет исключение» неверно.

+0

Является ли это 'FileWebRequest' или' FtpWebRequest'? И если это действительно «FileWebRequest»: не должна ли загрузка выходить из строя, так как файл не существует и место загрузки недопустимо? Или он загружается в какой-то текущий каталог? (Я не отстаю от ПК в течение нескольких часов, поэтому я не могу проверить это в ближайшее время). –

+0

Это, безусловно, FileWebRequest. Я не могу ответить, почему это удается, только разработчики этого кода могут ответить на этот вопрос. – rene

+0

ОК. Я уточню ваш ответ, чтобы исправить это и еще несколько опечаток. –

Смежные вопросы