【问题标题】:WebHeaderCollection & HttpWebRequest on XamarinXamarin 上的 WebHeaderCollection 和 HttpWebRequest
【发布时间】:2013-06-19 09:12:26
【问题描述】:

我正在尝试将我的项目从 Mac 上的 Xamarin Studio 移植到 Windows 7 上的 Visual Studio 2012。 在 Mac 和 XS 上一切正常。在 VisualStudio 2012 上,我遇到了这两个问题:

错误 3 'System.Net.WebHeaderCollection' 不包含定义 对于“添加”并且没有扩展方法“添加”接受第一个参数 可以找到类型“System.Net.WebHeaderCollection”(您是否缺少 using 指令或程序集 参考?) C:\Users\user\Documents\Visual Studio 2012\Projects\MyProject\MyProject.Core\Services\MyProjectService.cs

错误 4 'System.Net.HttpWebRequest' 不包含对 'GetResponse' 并且没有扩展方法 'GetResponse' 接受第一个 可以找到“System.Net.HttpWebRequest”类型的参数(你是 缺少 using 指令或程序集 参考?) C:\Users\user\Documents\Visual Studio 2012\Projects\MyProject\MyProject.Core\Services\MyProjectService.cs

关于该代码:

    var request = WebRequest.Create("https://www.myaddress.com/test/") as HttpWebRequest;
    request.Method = "GET";
    request.Accept = "application/json";
    request.Headers.Add(HttpRequestHeader.Cookie,"mycookievalue");

    // Get response  
    using (var response = request.GetResponse() as HttpWebResponse)
    {
        // Get the response stream  
        var reader = new StreamReader(response.GetResponseStream());
        content = reader.ReadToEnd();
    }

我该如何解决?

【问题讨论】:

  • 一个想法:Headers["key"] = value 有效吗?
  • 我不知道密钥...我如何检查它(通过 RestClient?)
  • 密钥不是HttpRequestHeader.Cookie吗?
  • request.Headers[HttpRequestHeader.Cookie] = value; 应该可以工作。
  • ok 1 错误输出...对于 GetResponse 错误?

标签: c# mono httpwebrequest xamarin xamarin-studio


【解决方案1】:

到目前为止,您提到的事情没有实现。 但没关系。他们仍然做得很好!

回答您的问题。

错误 3。是的。目前您只能使用 Headers["key"] = value。但。不是每个标题。我试图把“Content-Length”放在那里(因为也没有实现“ContentLength”属性),但是得到了“restricted headers”异常。 但是,请求 POST 已为我成功处理,所以我放弃了。

错误 4。是的。没有这样的方法。 (同样的,因为没有“GetRequestStream”(例如,如果你想将 POST 数据写入请求流))。好消息是分别有 BeginGetResponse 和 BeginGetRequestStream,而 C# action 方法 简化了所有厨房。

(另外,我敢肯定,这对于一般理解异步实践非常有用)。

基本示例可以在Microsoft official docs找到。

但是为了做到这一点,我使用了以下操作:

    public void MakeRequest(string url, string verb, Dictionary<string, string> requestParams,
        Action<string> onSuccess, Action<Exception> onError)
    {
        string paramsFormatted;

        if (verb == "GET")
        {
            paramsFormatted = string.Join("&", requestParams.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
            url = url + (string.IsNullOrEmpty(paramsFormatted) ? "" : "?" + paramsFormatted);
        }
        else
        {
            // I don't escape parameters here,
            // as Uri.EscapeDataString would throw exception if the parameter length
            // is too long, so you must control that manually before passing them here
            // for instance to convert to base64 safely
            paramsFormatted = string.Join("&", requestParams.Select(x => x.Key + "=" + (x.Value)));
        }

        var request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = verb;

        requestParams = requestParams ?? new Dictionary<string, string>();

        Action goRequest = () => MakeRequest(request, 
            response =>
            {
                onSuccess(response);
            },
            error =>
            {
                if (onError != null)
                {
                    onError(error);
                }
            });

        if (request.Method == "POST")
        {
            request.BeginGetRequestStream(ar =>
            {
                using (Stream postStream = request.EndGetRequestStream(ar))
                {
                    byte[] byteArray = Encoding.UTF8.GetBytes(paramsFormatted);
                    postStream.Write(byteArray, 0, paramsFormatted.Length);
                }
                goRequest();
            }, request);
        }
        else // GET
        {
            goRequest();
        }
    }

    private void MakeRequest(HttpWebRequest request, Action<string> onSuccess, Action<Exception> onError)
    {
        request.BeginGetResponse(token =>
        {
            try
            {
                using (var response = request.EndGetResponse(token))
                {
                    using (var stream = response.GetResponseStream())
                    {
                        var reader = new StreamReader(stream);
                        onSuccess(reader.ReadToEnd());
                    }
                }
            }
            catch (WebException ex)
            {
                onError(ex);
            }
        }, null);
    }

【讨论】:

    【解决方案2】:

    为了回答错误 4,我做了两个扩展方法,这样我就可以在 WebRequest 类中使用 GetRespone() 和 GetRequestStream() 方法,并像它们的原始版本一样工作,即阻塞线程。所以这里是:

    public static class ExtensionMethods
    {
        public static WebResponse GetResponse(this WebRequest request){
            ManualResetEvent evt = new ManualResetEvent (false);
            WebResponse response = null;
            request.BeginGetResponse ((IAsyncResult ar) => {
                response = request.EndGetResponse(ar);
                evt.Set();
            }, null);
            evt.WaitOne ();
            return response as WebResponse;
        }
    
        public static Stream GetRequestStream(this WebRequest request){
            ManualResetEvent evt = new ManualResetEvent (false);
            Stream requestStream = null;
            request.BeginGetRequestStream ((IAsyncResult ar) => {
                requestStream = request.EndGetRequestStream(ar);
                evt.Set();
            }, null);
            evt.WaitOne ();
            return requestStream;
        }
    }
    

    只需确保将其放置在与常规代码不同的命名空间中并导入该命名空间即可。然后,您将拥有 WebRequest 实例的 GetResponse() 方法。哦,还有 GetRequestStream(),这对于发送 POST 数据很有用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多