【问题标题】:How to receive response from server in Xamarin.Forms如何在 Xamarin.Forms 中接收来自服务器的响应
【发布时间】:2018-09-18 11:41:54
【问题描述】:

我创建了一个向我的服务器发送数据的 HTTP 客户端。此数据将查询我的服务器,该服务器将返回一个 JSON 对象。如何从我的服务器接收 JSON 对象响应并将其插入到我的数据库中?

下面的代码将向我的服务器发送一个ContactID,我的服务器将返回一个 JSON 对象 如何从我的服务器获取 JSON 对象?我将在我的代码中添加什么?我已经添加了

var data = await response.Content.ReadAsStringAsync();

但我不知道如何继续。

try
        {
            var db = DependencyService.Get<ISQLiteDB>();
            var conn = db.GetConnection();

            var sql = "SELECT * FROM tblUser WHERE ContactID = '" + contact + "'";
            var getUser = conn.QueryAsync<UserTable>(sql);
            var resultCount = getUser.Result.Count;

            //Check if the user has been sync
            if (resultCount < 1)
            {
                try
                {
                    syncStatus.Text = "Syncing user to server...";

                    var link = Constants.requestUrl + "Host=" + host + "&Database=" + database + "&Contact=" + contact + "&Request=8qApc8";
                    string contentType = "application/json";
                    JObject json = new JObject
                    {
                        { "ContactID", contact }
                    };

                    HttpClient client = new HttpClient();
                    var response = await client.PostAsync(link, new StringContent(json.ToString(), Encoding.UTF8, contentType));
                    var data = await response.Content.ReadAsStringAsync();

                    if (response.IsSuccessStatusCode)
                    {
                        var content = await response.Content.ReadAsStringAsync();
                        var userresult = JsonConvert.DeserializeObject<IList<UserData>>(content);
                        var count = userresult.Count;

                        for (int i = 0; i < count; i++)
                        {
                            try
                            {
                                syncStatus.Text = "Syncing user to server...";

                                var item = userresult[i];
                                var contactID = item.ContactID;
                                var userID = item.UserID;
                                var userPassword = item.UserPassword;
                                var userType = item.UserType;
                                var userStatus = item.UserStatus;
                                var lastSync = item.LastSync;
                                var serverUpdate = item.ServerUpdate;
                                var mobileUpdate = item.MobileUpdate;

                                var user = new UserTable
                                {
                                    ContactID = Convert.ToInt32(contactID),
                                    UserID = userID,
                                    UserPassword = userPassword,
                                    UserType = userType,
                                    UserStatus = userStatus,
                                    LastSync = lastSync,
                                    ServerUpdate = serverUpdate,
                                    MobileUpdate = mobileUpdate
                                };

                                await conn.InsertAsync(user);
                            }
                            catch (Exception ex)
                            {
                                Console.Write("Syncing user error " + ex.Message);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.Write("Syncing User Error " + ex.Message);
                }
            }

我的 PHP 代码将使用从 Xamarin HTTP 客户端 收到的 ContactID 查询我的数据库。

$json_str = file_get_contents('php://input');
    $json_obj = json_decode($json_str);

    $ContactID = $json_obj->ContactID;

    $sql = "SELECT * FROM tblUser WHERE ContactID = '$ContactID'";
    $result = mysqli_query($conn, $sql);
    $count = mysqli_num_rows($result);

    if($count > 0){
        while ($row = @mysqli_fetch_array($result)) {
            $decr = CryptRC4(FromHexDump($row['UserPassword']), $key);

            $ar[] = array(
                'ContactID' => $row['ContactID'],
                'UserID' => $row['UserID'],
                'UserPassword' => $decr,
                'UserType' => $row['UserType'],
                'UserStatus' => $row['UserStatus'],
                'LastSync' => $sync,
                'ServerUpdate' => $row['ServerUpdate'],
                'MobileUpdate' => $row['MobileUpdate']
            );

            print json_encode($ar);

            //Update LastSync DateTime
            $sql = "UPDATE tblUser SET LastSync = '$sync' WHERE ContactID = '$ContactID'";
            mysqli_query($conn, $sql);
        }
    }    

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    上面示例中的最后一条语句以字符串格式提供了 json 对象列表。

    var data = await response.Content.ReadAsStringAsync();
    

    您需要将其转换回对象列表。要让您的项目了解对象的定义,请创建一个具有公共属性的普通类(如下所示)

    public class UserLog
    {
        public int ContactId { get; set; }
        public string Log { get; set; }
        public DateTime LogDate { get; set; }
    }
    

    Newtonsoft.Json (by James Newton-King) Nuget 包添加到您的项目中,以便您可以使用 json。

    要将变量“数据”的内容转换为 UserLog 对象列表,请编写类似的代码

    var list = NewtonsoftUtil<IList<UserLog>>.DeserializeObject(data);
    

    (在文件顶部添加using Newtonsoft.Json;

    如果这有帮助,请告诉我。

    【讨论】:

    • 我会试试这个谢谢你我会告诉你这是否有效
    • 我更新了我的代码,我可以得到响应,但似乎无法在我的本地数据库中添加响应
    • 我无法计算 var userresult = JsonConvert.DeserializeObject>(content); var count = userresult.Count;
    • 你能检查一下你在变量“数据”中得到了什么字符串吗?也许它与您定义的模型类('UserLog')不一样。请分享变量“数据”的内容。
    【解决方案2】:

    上面的答案漏掉了一个重点 -> efficiency.

    无需在内存中分配字符串,尤其是当您的 JSON 很大时。 Streams 可以比 strings 做得更好:

    // Read the response as stream
    var stream = await response.Content.ReadAsStreamAsync();
    
    // Use the next method for deserialization
    T DeserializeJsonFromStream<T>(Stream stream)
    {
        if (stream == null || stream.CanRead == false)
            return default(T);
    
        using (var sr = new StreamReader(stream))
        using (var jtr = new JsonTextReader(sr))
        {
            var js = new JsonSerializer();
            return js.Deserialize<T>(jtr);
        }
    }
    

    P.S.:代码示例基于Json.NET
    P.S.S.:这个话题有很多好文章,可以推荐熟悉下one

    【讨论】:

    • 我更新了我的代码,请参阅我无法将数据插入本地数据库 我可以获得响应,但似乎无法将响应插入本地数据库。当我在调试时休息时,我无法计算响应的数量@EvZ
    • 听起来像是一个完全不同的话题,请尽可能详细地提出一个新问题。
    【解决方案3】:

    假设您已正确完成所有操作。换句话说,您可以发送您的 contactID 并取回一个 json。

    假设您的 json 结构类似于: {"firstname" : "Doe", "lastname" : "foo" "age" : "27"}

    检索数据的一种可能方法如下:

    using Newtonsoft.Json;
    
    //after PostAsync()
    if (response.IsSuccessStatusCode)
    {
        var content = await response.Content.ReadAsStringAsync();
        JObject jContent = (JObject)JsonConvert.DeserializeObject(content);
        string firstName = (string)jContent.GetValue("firstname")
        string lastName = (string)jContent.GetValue("lastname");
        int age = (int)jContent.GetValue("age");
    }
    

    Newtonsoft 在 Nuget 上可用。如果您还没有安装,则需要安装它。

    改进的解决方案

    如果您的 json 有许多如下所示的键/值对怎么办:

    { key1 : value1, key2 : value2, key3 : value3, ... key10 : value10}

    那么这样做不是一个好主意:

    string foo1 = (string)jContent.GetValue("key1");
    string foo2 = (string)jContent.GetValue("key2");
    //...
    string foo10 = (string)jContent.GetValue("key10");
    

    要处理这种情况,您可以创建一个类:

    public class Foo
    {
        public string Foo1 {get;set;}
        public string Foo2 {get;set;}
        //...
        public string Foo2 {get;set;}
    }
    

    那么,你可以像下面这样简单:

    if (response.IsSuccessStatusCode)
    {
        var content = await response.Content.ReadAsStringAsync();
        Foo foo = JsonConvert.DeserializeObject<Foo>(content);
    }
    

    www.newtonsoft.com 引用的改进解决方案。去那里看看使用图书馆的其他方式。

    【讨论】:

    • 我更新了我的代码,请查看我无法将数据插入本地数据库 我可以得到响应,但似乎无法插入响应
    • 我无法计算响应以将其插入我的本地数据库@Fuong
    • 我添加了一个try catch 错误是Cannot convert string to datetime in LastSync
    • 不应将您的问题编辑与原始问题不同的问题。这使得其他人更难理解问题和答案。如果需要,请发布另一个单独的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多