2

I made a post request class that I could re-use to make POST requests to an external api and return the objects they send me (JSON):

class PostRequest
    {
        private Action<DataUpdateState> Callback;

        public PostRequest(string urlPath, string data, Action<DataUpdateState> callback)
        {
            Callback = callback;

            // form the URI
            UriBuilder fullUri = new UriBuilder(urlPath);
            fullUri.Query = data;

            // initialize a new WebRequest
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fullUri.Uri);
            request.Method = "POST";

            // set up the state object for the async request
            DataUpdateState dataState = new DataUpdateState();
            dataState.AsyncRequest = request;

            // start the asynchronous request
            request.BeginGetResponse(new AsyncCallback(HandleResponse),
                dataState);
        }

        private void HandleResponse(IAsyncResult asyncResult)
        {
            // get the state information
            DataUpdateState dataState = (DataUpdateState)asyncResult.AsyncState;
            HttpWebRequest dataRequest = (HttpWebRequest)dataState.AsyncRequest;

            // end the async request
            dataState.AsyncResponse = (HttpWebResponse)dataRequest.EndGetResponse(asyncResult);
            if (dataState.AsyncResponse.StatusCode.ToString() == "OK")
            {
                Callback(dataState); // THIS IS THE LINE YOU SHOULD LOOK AT :)
            }
        }
    }

    public class DataUpdateState
    {
        public HttpWebRequest AsyncRequest { get; set; }
        public HttpWebResponse AsyncResponse { get; set; }
    }
}

the Callback method gets the datastate object and pushes it to this function:

    public void LoadDashboard( DataUpdateState dataResponse )
    {
        Stream response = dataResponse.AsyncResponse.GetResponseStream();
        //Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
        //StreamReader readStream = new StreamReader(response, encode);
        //readStream.Close();


        Deployment.Current.Dispatcher.BeginInvoke(() => {
            App.RootFrame.Navigate(new Uri("/Interface.xaml", UriKind.RelativeOrAbsolute));
        });
    }

I'm now unsure of how to get the body of that reply that has been sent to me from the API. It is returning a json format, I need to be able to map it to a nice C# class and use it to display stuff on the phone.

I can't find an example that doesn't use JSON.NET (which doesn't have an assembly for windows phone 8)


This is error I get installing HTTPClient class:

Attempting to resolve dependency 'Microsoft.Bcl (≥ 1.1.3)'.
Attempting to resolve dependency 'Microsoft.Bcl.Build (≥ 1.0.4)'.
Successfully installed 'Microsoft.Bcl.Build 1.0.10'.
Successfully installed 'Microsoft.Bcl 1.1.3'.
Successfully installed 'Microsoft.Net.Http 2.2.13'.
Successfully added 'Microsoft.Bcl.Build 1.0.10' to UnofficialPodio.
Executing script file ***\packages\Microsoft.Bcl.Build.1.0.10\tools\Install.ps1'.
This reference cannot be removed from the project because it is always referenced by the compiler.
This reference cannot be removed from the project because it is always referenced by the compiler.
This reference cannot be removed from the project because it is always referenced by the compiler.
This reference cannot be removed from the project because it is always referenced by the compiler.
Executing script file ***\packages\Microsoft.Bcl.Build.1.0.10\tools\Uninstall.ps1'.
Successfully uninstalled 'Microsoft.Bcl 1.1.3'.
Successfully uninstalled 'Microsoft.Bcl.Build 1.0.10'.
Install failed. Rolling back...
Failed to add reference to 'System.IO'.

"{
    \"access_token\": \"123803120312912j\",
    \"token_type\": \"bearer\",
    \"ref\": {
        \"type\": \"user\",
        \"id\": 123123
    },
    \"expires_in\": 28800,
    \"refresh_token\": \"234234f23f423q432f\"
}"

...

public class Auth
{

    [DataMember(Name = "access_token")]  
    public string AccessToken { get; set; }

    [DataMember(Name = "token_type")]  
    public string TokenType { get; set; }

    [DataMember(Name = "expires_in")]  
    public string ExpiresIn { get; set; }

    [DataMember(Name = "refresh_token")]  
    public string RefreshToken { get; set; }

    //[DataMember(Name = "ref")]  
    //public string Ref { get; set; }

}
4

2 回答 2

5

要获取响应数据,您需要在 HttpWebResponse 对象上调用 GetResponseStream(),然后从流中读取。像这样的东西:

using (Stream s = response.GetResponseStream())
{
    using (TextReader textReader = new StreamReader(s, true))
    {
        jsonString = textReader.ReadToEnd();
    }
}

要从 json 字符串中获取数据,您需要创建一个数据协定类来完全像这样描述 json 数据:

    [DataContract]
    public class ApiData
    {
        [DataMember(Name = "name")]  <--this name must be the exact name of the json key
        public string Name { get; set; }

        [DataMember(Name = "description")]
        public string Description { get; set; }
    }

接下来,您可以从字符串中反序列化 json 对象:

        using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ApiData));
            ApiData obj = (ApiData)serializer.ReadObject(stream);
            return obj;
        }

WebRequest 可以正常工作,但我建议为 HttpClient 类安装 NuGet 包。它使生活变得更简单。例如,您可以只用几行代码编写上述请求代码:

        HttpClient httpClient = new HttpClient();
        HttpRequestMessage msg = new HttpRequestMessage(new HttpMethod("POST"), escapedUrl);
        HttpResponseMessage response = await httpClient.SendAsync(msg);

在回答您下面的问题时,这是我使用的通用 json 转换器代码:

public static class JsonHelper
{
    public static T Deserialize<T>(string json)
    {
        using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            T obj = (T)serializer.ReadObject(stream);
            return obj;
        }
    }

    public static string Serialize(object objectToSerialize)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(objectToSerialize.GetType());
            serializer.WriteObject(ms, objectToSerialize);
            ms.Position = 0;
            using (StreamReader sr = new StreamReader(ms))
            {
                return sr.ReadToEnd();
            }
        }
    }
}
于 2013-09-19T01:05:15.597 回答
0

JSON.Net 确实支持 windows phone 8,根据这个答案,它可以作为可移植类库使用。

只需尝试通过 nuget 添加包...

于 2013-09-19T00:59:35.890 回答