【问题标题】:reading my json response from a post request i sent从我发送的帖子请求中读取我的 json 响应
【发布时间】:2013-10-03 05:10:59
【问题描述】:

我创建了一个发布请求类,我可以重复使用它来向外部 api 发出 POST 请求并返回他们发送给我的对象 (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; }
    }
}

Callback 方法获取数据状态对象并将其推送到此函数:

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

我现在不确定如何获取从 API 发送给我的回复正文。它返回一个 json 格式,我需要能够将它映射到一个不错的 C# 类并使用它在手机上显示内容。

我找不到不使用 JSON.NET 的示例(没有适用于 windows phone 8 的程序集)


这是我安装 HTTPClient 类时出现的错误:

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

}

【问题讨论】:

    标签: c# json windows-phone-8


    【解决方案1】:

    要获取响应数据,您需要在 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();
                }
            }
        }
    }
    

    【讨论】:

    • 我实际上无法让上面的HttpClient代码工作......我回家后看看,看看我是否可以提醒自己为什么:)
    • 我添加了使用 nuget 安装时遇到的错误(适用于 windows phone visual studio 2012)
    • 是的,它工作得很好......我只是让它工作:D......谢谢你的回答伙伴。你是专业人士!
    • 为什么我的 datacontract 类在 ReadObject 行之后可能为空?请查看我调用的 api 返回的 json(最新编辑)
    • 很高兴它正在工作。要获取“ref”对象,请创建另一个 datacontract 类并将“Ref”属性的类型设置为新的类类型。
    【解决方案2】:

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

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

    【讨论】:

    • 我有,它出现了没有为 windows phone 编写的程序集的安装错误。我回家后看看你的链接,谢谢。
    猜你喜欢
    • 2023-02-01
    • 1970-01-01
    • 2016-03-29
    • 2021-11-10
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多