序列化 ListView 数据以发送 JSON POST

我正在关注这个问题ListView Get Multiple Entry Values to validate and send我现在需要序列化数据以将其发送到服务器,我已经做到了这一点:


public class SurveyList

{

    public List<QuestionList> Questions { get; set; }

}


public class QuestionList

{

    public string QuestionLabel { get; set; }

    public string QuestionCode { get; set; }

}


public partial class SurveyPage : ContentPage

{

    private List<QuestionList> survey;


    public SurveyPage()

    {

        InitializeComponent();


        survey = new List<QuestionList>

        {

            new QuestionList { QuestionLabel = "Question 1?", QuestionCode = "01" },

            new QuestionList { QuestionLabel = "Question 2?", QuestionCode = "02" }

        };


        surveyList.ItemsSource = survey;

    }


    void Button_Clicked(object sender, System.EventArgs e)

    {

        HttpClient client = new HttpClient();


        client.BaseAddress = new Uri("http://myip");


        foreach (var getValues in survey)

        {

            Dictionary<string, string> listViewData = new Dictionary<string, string>()

            {

                { "Question", getValues.QuestionLabel },

                { "Answer", getValues.QuestionCode }

            };


            var listViewDataContent = new FormUrlEncodedContent(listViewData);


            var response = client.PostAsync("/api/GetData", listViewDataContent);

        }


    }

}

请帮助我正确获取所有数据以通过 POST 发送。不知道如何收集所有数据,因为我得到的数据是动态的。


注意:那里显示的数据是静态的,但应该是从同一个 API 获取数据


沧海一幻觉
浏览 177回答 2
2回答

侃侃无极

您不必手动编写 Json,还有其他方法可以做到这一点。首先修改您的QuestionList对象以调用另一个字段,Answer或者您更喜欢调用它。public class QuestionList{&nbsp; &nbsp; public string QuestionLabel { get; set; }&nbsp; &nbsp; public string QuestionCode { get; set; }&nbsp; &nbsp; public string Answer { get; set; }}这个新属性将保存答案的值。第二:改变你List<QuestionList>的 ObservableCollection这里:private ObservableCollection<QuestionList> survey;和这里survey = new ObservableCollection<QuestionList>{&nbsp; &nbsp; new QuestionList { QuestionLabel = "Question 1?", QuestionCode = "01" },&nbsp; &nbsp; new QuestionList { QuestionLabel = "Question 2?", QuestionCode = "02" }};稍微改变一下你的 XAML。将 绑定Answer到Picker SelectedItem. 这就是“魔术”发生的地方。<Picker x:Name="QuestionPicker"&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; SelectedItem="{Binding Answer, Mode=TwoWay}">&nbsp; &nbsp; <Picker.Items>&nbsp; &nbsp; &nbsp; &nbsp; <x:String>Yes</x:String>&nbsp; &nbsp; &nbsp; &nbsp; <x:String>No</x:String>&nbsp; &nbsp; </Picker.Items></Picker>每次用户从中选择一个值时,Picker它都会自动更新Answer您设置为的 List 的属性ItemsSource。更多关于绑定在这里现在您只需更改 Button Clicked 事件,使用这行代码您将拥有一个做得很好的 Json。(首先你需要安装Newtonsoft Nugget)这里有一个教程,展示了如何安装一个 nugget 包(巧合的是,他们使用相同的库作为示例,我们很幸运!)。var json = JsonConvert.SerializeObject(survey);上面将创建一个具有以下格式的 json:[&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; "QuestionLabel":"Question 1",&nbsp; &nbsp; &nbsp; &nbsp; "QuestionCode" : "01",&nbsp; &nbsp; &nbsp; &nbsp; "Answer":"No"&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; "QuestionLabel":"Question 2",&nbsp; &nbsp; &nbsp; &nbsp; "QuestionCode" : "02",&nbsp; &nbsp; &nbsp; &nbsp; "Answer":"Yes"&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; "QuestionLabel":"Question 3",&nbsp; &nbsp; &nbsp; &nbsp; "QuestionCode" : "03",&nbsp; &nbsp; &nbsp; &nbsp; "Answer":"Yes"&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; "QuestionLabel":"Question 4",&nbsp; &nbsp; &nbsp; &nbsp; "QuestionCode" : "04",&nbsp; &nbsp; &nbsp; &nbsp; "Answer":"Yes"&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; "QuestionLabel":"Question 5",&nbsp; &nbsp; &nbsp; &nbsp; "QuestionCode" : "05",&nbsp; &nbsp; &nbsp; &nbsp; "Answer":"No"&nbsp; &nbsp; }]如您所见,这表示一个 QuestionList 数组,并且您的服务器端点应该期望它作为请求正文。为了清楚起见,我Answer用随机值填充。整个 Click 事件代码看起来像void Button_Clicked(object sender, System.EventArgs e){&nbsp; &nbsp; using(var client = new HttpClient())&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; client.BaseAddress = new Uri("http://myip");&nbsp; &nbsp; &nbsp; &nbsp; var json = JsonConvert.SerializeObject(survey);&nbsp; &nbsp; &nbsp; &nbsp; var listViewDataContent = new FormUrlEncodedContent(json);&nbsp; &nbsp; &nbsp; &nbsp; var response = client.PostAsync("/api/GetData", listViewDataContent);&nbsp; &nbsp; }}注意:请注意,我对初始化 HttpClient 的方式进行了一些更改。是的,我知道该文档存在,但是您每次单击按钮时都会创建一个新实例,因为这不是问题的一部分,以免说我们没有看到它。注意 2:将值与服务器在 json 中的期望值匹配。这里重要的是向您展示使用Xamarin.Forms绑定您可以从中获取值,ListView并且使用Newtownsoft.Json您可以轻松地将数据从C# Object 转换为Json。更多关于这个库的信息在这里。

浮云间

好的,所以我解决了,感谢@apineda 和@Andrew,他们将我引导到正确的方向。也许解决方案没有它可以的那么干净,但它确实有效。第 1 步 - 模型我有两个班级调查列表问题清单public class SurveyList{&nbsp; &nbsp; [JsonProperty("title")]&nbsp; &nbsp; public string SurveyTtitle { get; set; }&nbsp; &nbsp; [JsonProperty("questions")]&nbsp; &nbsp; public List<QuestionList> Questions { get; set; }}public class QuestionList{&nbsp; &nbsp; [JsonProperty("question")]&nbsp; &nbsp; public string QuestionText { get; set; }&nbsp; &nbsp; [JsonProperty("questionId")]&nbsp; &nbsp; public string QuestionCode { get; set; }}第 2 步 - 我的 Xaml我的 ListView 标题的标题<ListView.Header>&nbsp; &nbsp; <StackLayout Padding="0, 30" VerticalOptions="CenterAndExpand">&nbsp; &nbsp; &nbsp; &nbsp; <Label x:Name="surveyTitle" Text="" FontSize="18" FontAttributes="Bold" HorizontalOptions="Center"/>&nbsp; &nbsp; </StackLayout></ListView.Header>ListView 项目模板<ListView.ItemTemplate>&nbsp; &nbsp; <DataTemplate>&nbsp; &nbsp; &nbsp; &nbsp; <ViewCell>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <StackLayout Padding="5, 5, 5, 15" VerticalOptions="Start" HorizontalOptions="FillAndExpand">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Label Text="{Binding QuestionText}"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Picker ItemDisplayBinding="{Binding QuestionCode}" Title="Select Yes or No" FontSize="Small" TextColor="Gray" SelectedIndexChanged="Handle_SelectedIndexChanged">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Picker.Items>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <x:String>Yes</x:String>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <x:String>No</x:String>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </Picker.Items>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </Picker>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </StackLayout>&nbsp; &nbsp; &nbsp; &nbsp; </ViewCell>&nbsp; &nbsp; </DataTemplate></ListView.ItemTemplate>用于发送数据的按钮的 ListView 页脚<ListView.Footer>&nbsp; &nbsp; <StackLayout Padding="0, 30, 0, 30">&nbsp; &nbsp; &nbsp; &nbsp; <Button x:Name="surveyButton"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Text="Send Survey"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TextColor="White"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BackgroundColor="Teal"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Clicked="Handle_Clicked" />&nbsp; &nbsp; </StackLayout></ListView.Footer>第 3 步 - 我的 CodeBehind我添加了参数、IDictionary、baseURI、API 和资源&nbsp; &nbsp; private IDictionary<string, string> Answers;&nbsp; &nbsp; private string baseUri = "http://myip";&nbsp; &nbsp; private string api = "/api";&nbsp; &nbsp; private string resource = "/GetData";&nbsp; &nbsp; private string username = "username";&nbsp; &nbsp; private string password = "password";在构造函数中,我实例化了 Dictionary 对象&nbsp; &nbsp; Answers = new Dictionary<string, string>();添加了一个覆盖 OnAppearing() ,因此每次调用该页面时,它都会调用 API 并检查它们是否有可用的调查(注意:@apineda,抱歉,没有添加您的代码,这更干净,但我已经在编写它了)&nbsp; &nbsp; HttpClient client = new HttpClient();&nbsp; &nbsp; &nbsp; &nbsp; client.BaseAddress = new Uri(baseUri);&nbsp; &nbsp; &nbsp; &nbsp; client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password)));&nbsp; &nbsp; &nbsp; &nbsp; client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("Application/json"));&nbsp; &nbsp; &nbsp; &nbsp; var response = client.GetAsync(api).Result;&nbsp; &nbsp; &nbsp; &nbsp; if (response.IsSuccessStatusCode)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var getJson = client.GetStringAsync(api + resource).Result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var jsonString = JsonConvert.DeserializeObject<SurveyList>(getJson);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; surveyTitle.Text = jsonString.SurveyTtitle;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Survey = new List<QuestionList>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (var surveys in jsonString.Questions)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Survey.Add(new QuestionList { QuestionText = surveys.QuestionText, QuestionCode = surveys.QuestionCode });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; surveyList.ItemsSource = Survey;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; surveyList.EndRefresh();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stackButton.IsVisible = true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; surveyTitle.Text = "No Surveys Available";&nbsp; &nbsp; &nbsp; &nbsp; }选择器选择索引更改以在每次更改时将值添加到答案字典&nbsp; &nbsp; void Handle_SelectedIndexChanged(object sender, System.EventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var picker = sender as Picker;&nbsp; &nbsp; &nbsp; &nbsp; var item = picker.BindingContext;&nbsp; &nbsp; &nbsp; &nbsp; var question = item as QuestionList;&nbsp; &nbsp; &nbsp; &nbsp; Answers.Add(question.QuestionCode, picker.SelectedItem.ToString());&nbsp; &nbsp; }发送所有数据的按钮方法&nbsp; &nbsp; void Handle_Clicked(object sender, System.EventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; HttpClient client = new HttpClient();&nbsp; &nbsp; &nbsp; &nbsp; client.BaseAddress = new Uri(baseUri);&nbsp; &nbsp; &nbsp; &nbsp; client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password)));&nbsp; &nbsp; &nbsp; &nbsp; foreach (KeyValuePair<string, string> item in Answers)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dictionary<string, string> collectAnswers = new Dictionary<string, string>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ item.Key, item.Value }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var collectAnswersContent = new FormUrlEncodedContent(collectAnswers);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var response = await client.PostAsync(api + "/addSurveyAnswers", collectAnswersContent);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (response.IsSuccessStatusCode)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;await DisplayAlert(null, "Thank you for answering the survey", "Close");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(sender as Button).BackgroundColor = Color.FromHex("#00afb9");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;await DisplayAlert("Error", "Please Try Again, something went wrong", "OK");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(sender as Button).BackgroundColor = Color.FromHex("#00afb9");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; }我知道这段代码不是很干净(Xamarin 和 C# 的新手),只是想发布答案以防有人发现它有用。我违反了程序员法,我在很多地方都在重复自己,但到目前为止它仍然有效,现在我可以开始清理代码了
打开App,查看更多内容
随时随地看视频慕课网APP