【问题标题】:Webclient UploadStringCompleted event not being called未调用 Webclient UploadStringCompleted 事件
【发布时间】:2014-10-07 05:36:22
【问题描述】:

我正在为我们开发的一些网络服务编写单元测试。我有一个 [TestMethod] 发布到 web 服务作为休息。效果很好,但它不会触发我创建的事件处理程序方法。通过调试,我注意到在执行测试方法后,事件处理程序正在获取排除器。它去测试清理。

有人遇到过这个问题吗?这是代码

 [TestMethod,TestCategory("WebServices")]
        public void ValidateWebServiceGetUserAuthToken()
        {
            string _jsonstringparams =
                "{ \"Password\": \"xxx\", \"UserId\": \"xxxx\"}";
            using (var _requestclient = new WebClient())
            {
                _requestclient.UploadStringCompleted += _requestclient_UploadStringCompleted;
                var _uri = String.Format("{0}?format=Json", _webservicesurl);
                _requestclient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
                _requestclient.UploadStringAsync(new Uri(_uri), "POST", _jsonstringparams);
            }
    }

    void _requestclient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
    {
        if (e.Result != null)
        { 
            var _responsecontent = e.Result.ToString();
            Console.WriteLine(_responsecontent);
        }
        else 
        {
            Assert.IsNotNull(e.Error.Message, "Test Case Failed");
        }
    }

【问题讨论】:

    标签: c# webclient


    【解决方案1】:

    问题在于 UploadStringAsync 返回 void(即,它是一劳永逸的)并且本身并不能让您检测到完成。

    有几个选项。第一个选项(这是我推荐的选项)是改用 HttpClient 并使用 PostAsync 方法——你可以await。在这种情况下,我会这样做:

    [TestMethod, TestCategory("WebServices")]
    public async Task ValidateWebServiceGetUserAuthToken()
    {
        string _jsonstringparams =
            "{ \"Password\": \"xxx\", \"UserId\": \"xxxx\"}";
        using (var httpClient = new HttpClient())
        {
            var _uri = String.Format("{0}?format=Json", _webservicesurl);
            var stringContent = new StringContent(_jsonstringparams);
            stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 
            HttpResponseMessage response = await httpClient.PostAsync(_uri, stringContent);
            // Or whatever status code this service response with
            Assert.AreEqual(HttpStatusCode.Accepted, response.StatusCode);
            var responseText = await response.Content.ReadAsStringAsync();
            // TODO: something more specific to your needs
            Assert.IsTrue(!string.IsNullOrWhiteSpace(responseText));
        }
    }
    

    另一种选择是更改您的完整事件处理程序,以向您的测试发出上传已完成的信号,并在您的测试中等待事件发生。例如:

    [TestMethod, TestCategory("WebServices")]
    public void ValidateWebServiceGetUserAuthToken()
    {
        string _jsonstringparams =
            "{ \"Password\": \"xxx\", \"UserId\": \"xxxx\"}";
        using (var _requestclient = new WebClient())
        {
            _requestclient.UploadStringCompleted += _requestclient_UploadStringCompleted;
            var _uri = String.Format("{0}?format=Json", _webservicesurl);
            _requestclient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
            _requestclient.UploadStringAsync(new Uri(_uri), "POST", _jsonstringparams);
            completedEvent.WaitOne();
        }
    }
    
    private ManualResetEvent completedEvent = new ManualResetEvent(false);
    void _requestclient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
    {
        if (e.Result != null)
        {
            var _responsecontent = e.Result.ToString();
            Console.WriteLine(_responsecontent);
        }
        else
        {
            Assert.IsNotNull(e.Error.Message, "Test Case Failed");
        }
        completedEvent.Set();
    }
    

    【讨论】:

    • 有效!谢谢你。两种方法都奏效了。我也在考虑 Async 方法,但没有想到 ManualResetEvent。感谢您的回复!
    【解决方案2】:

    除了上面的答案之外,我还添加了一个方法来支持 httpwebresponse,这样我就不必等待事件了。

    public static AuthTokenResponse GetUserToken(string username, string password)
            {
                string _jsonstringparams =
                    String.Format("{{ \"Password\": \"{0}\", \"UserId\": \"{1}\"}}", password, username);
                string _webservicesurl = ConfigurationManager.AppSettings["WebservicesUrl"];
                HttpWebRequest _requestclient = (HttpWebRequest)WebRequest.Create(String.Format("{0}?format=Json", _webservicesurl));
                _requestclient.ContentType = "application/json";
                _requestclient.Method = "POST";
                using (var streamWriter = new StreamWriter(_requestclient.GetRequestStream()))
                {
                    streamWriter.Write(_jsonstringparams);
                    streamWriter.Flush();
                    streamWriter.Close();
                    var httpResponse = (HttpWebResponse)_requestclient.GetResponse();
                    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                    {
                        _responsecontent = streamReader.ReadToEnd();
                    }
                    AuthTokenResponse _clienttoken = JsonConvert.DeserializeObject<AuthTokenResponse>(_responsecontent);
                    return _clienttoken;
                }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-13
      • 2021-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多