WebHeaderCollection&关于Xamarin的HttpWebRequest

时间:2013-06-19 09:12:27

标签: c# mono httpwebrequest xamarin xamarin-studio

我试图将我的项目从Mac上的Xamarin Studio移植到Windows 7上的Visual Studio 2012。 在Mac和XS上工作得很好。在VisualStudio 2012上,我遇到了这两个问题:

  

错误3' System.Net.WebHeaderCollection'不包含定义   为'添加'没有扩展方法'添加'接受第一个论点   输入' System.Net.WebHeaderCollection'可以找到(你错过了吗?   使用指令或程序集   参考?)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 \项目\ MyProject的\ MyProject.Core \服务\ 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();
    }

我怎么能解决它?

2 个答案:

答案 0 :(得分:6)

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

回答你的问题。

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

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

(另外,我相信,这对异步实践的一般理解非常有用)。

基本样本可以在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);
    }

答案 1 :(得分:1)

为了回答错误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数据很有用