使用 web 服务来显示列表 xamarin 表单
consume a webservice to show list xamarin forms
我想在使用 web 服务的 xamarin(VS 2019) 中显示费用列表,但是当 运行 我的应用程序时,它显示一个空列表但是当我使用断点时,我发现信息是到达元素 "content"
PS:服务是运行在postman,
ListExpenses.xaml
<ListView x:Name="listexpense"
ItemsSource="{Binding expenseLists}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Height="150">
<StackLayout HorizontalOptions="StartAndExpand"
Orientation="Horizontal">
<Label Text="{Binding Name}"/>
<Label Text="{Binding Nature}"/>
<Label Text="{Binding AmountHT }"/>
<Label Text="{Binding AmountReimbursed }"/>
<Label Text="{Binding AmountExceeds }"/>
<Label Text="{Binding ExpenseReport }"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
ListExpenses.xaml.cs
public partial class ListExpenses : ContentPage, INotifyPropertyChanged
{
public ListExpenses()
{
InitializeComponent();
GetExpense();
}
public async void GetExpense()
{ HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("http://192.168.1.6:3000/api/adepApi/GetExpenseReports");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await httpClient.GetAsync("http://192.168.1.6:3000/api/adepApi/GetExpenses");
var content = await response.Content.ReadAsStringAsync();
ResponseData EL = JsonConvert.DeserializeObject<ResponseData>(content);
viewRapport.ItemsSource = EL.Data.expenseRLists;
}
class ResponseData
{
public ExpensRapportList Data;
}
private List<Expense> expenseList { get; set; }
[JsonProperty("expenses")]
public List<Expense> expenseLists
{
get { return expenseList; }
set
{
if (value != expenseList)
{
expenseList = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Expense.cs
public class Expense{
public int Id { get; set; }
public string Name { get; set; }
public string Nature { get; set; }
public string AmountHT { get; set; }
public string AmountReimbursed { get; set; }
public string AmountExceeds { get; set; }
public string ExpenseReport { get; set; }
}
我的网络服务
[Description("Get Expenses")]
[AllowAnonymous]
[AcceptVerbs("GET", "POST")]
public System.Web.Mvc.JsonResult GetExpenses()
{
var WorkContext = EngineContext.Current.Resolve<IWorkContext>();
var expenseBo = EngineContext.Current.Resolve<IExpenseBo>();
var success = true;
var errorMessage = String.Empty;
var successNotificationMessage = String.Empty;
IList<ExpenseModelCustom> expenses = null;
try
{
expenses=new List<ExpenseModelCustom>();
expenses = expenseBo.GetExpenses();
}
catch (Exception ex)
{
success = false;
errorMessage = ex.Message;
}
return new System.Web.Mvc.JsonResult
{
Data = new
{
expenses = expenses,
Success = success,
}
};
}
Json:
{"ContentEncoding": null,
"ContentType": null,
"Data": {
"expenses": [
{
"userId": null,
"Id": 4362,
"Name": "fda",
"Description": null,
"Provider": null,
"Nature": "Déjeuner région Parisienne",
"AmountHT": 16.67,
"AmountTTC": 20,
"AmountReimbursed": 20,
"Tva": "20 %.",
"Remboursable": true,
"Distance": null,
"IsIk": false,
"ExpenseReport": "Senda JAOUANI",
"IsDeleted": false,
"StatusSystemName": "Draft",
"Status": "Draft_",
"HasDocuments": true,
"Devise": "€",
"ReportStatus": "Draft",
"AmountExceeds": false,
"Date": "2020-03-26T15:24:22",
"StartDate": null,
"EndDate": null,
"Departure": null,
"ExpenseNatureId": null,
"CurrencyId": null,
"TvaId": null,
"Quantity": null,
"ExpenseReportId": null,
"IsDeplacementComplementaire": null,
"IsFromHome": null,
"IsToHome": null,
"Remboursabledistance": null,
"DistanceHomeToWork": null,
"IsAlleRetour": null,
"MissionPlace": null,
"IsInclud": null,
"PhysicalEntityId": null,
"CompanyEntity3Id": null,
"ventilationTvaList": null,
"InvitedInExpense": null,
"ExternalInvitedInExpense": null,
"documentIds": null,
"Amount": null
},
{
"userId": null,
"Id": 4356,
"Name": "Reprise Initialisation de Plafond",
"Description": "Reprise Initialisation de plafond",
"Provider": null,
"Nature": "Petit déjeuner",
"AmountHT": 250,
"AmountTTC": 250,
"AmountReimbursed": 250,
"Tva": null,
"Remboursable": true,
"Distance": 100,
"IsIk": false,
"ExpenseReport": "Reprise Initialisation de Plafond",
"IsDeleted": false,
"StatusSystemName": "",
"Status": "",
"HasDocuments": false,
"Devise": "€",
"ReportStatus": "Approved",
"AmountExceeds": false,
"Date": "2019-11-28T00:00:00",
"StartDate": null,
"EndDate": null,
"Departure": null,
"ExpenseNatureId": null,
"CurrencyId": null,
"TvaId": null,
"Quantity": null,
"ExpenseReportId": null,
"IsDeplacementComplementaire": null,
"IsFromHome": null,
"IsToHome": null,
"Remboursabledistance": null,
"DistanceHomeToWork": null,
"IsAlleRetour": null,
"MissionPlace": null,
"IsInclud": null,
"PhysicalEntityId": null,
"CompanyEntity3Id": null,
"ventilationTvaList": null,
"InvitedInExpense": null,
"ExternalInvitedInExpense": null,
"documentIds": null,
"Amount": null
}
],
"Success": true }, "JsonRequestBehavior": 1, "MaxJsonLength": null, "RecursionLimit": null}
您的网络服务 returns 一个包装器对象,其中包含一个数组。所以你需要反序列化包装器。使用 json2csharp.com 将为您生成 类
// assume the wrapper class is "RootObject"
var data = JsonConvert.DeserializeObject<RootObject>(content);
// now your List of Expenses is a property of RootObject, let's assume
// it's called "Expenses"
listexpense.ItemsSource = data.Expenses;
您还需要更新 XAML 中的绑定路径以匹配修改后的费用对象的 属性 名称
我想在使用 web 服务的 xamarin(VS 2019) 中显示费用列表,但是当 运行 我的应用程序时,它显示一个空列表但是当我使用断点时,我发现信息是到达元素 "content"
PS:服务是运行在postman,
ListExpenses.xaml
<ListView x:Name="listexpense"
ItemsSource="{Binding expenseLists}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Height="150">
<StackLayout HorizontalOptions="StartAndExpand"
Orientation="Horizontal">
<Label Text="{Binding Name}"/>
<Label Text="{Binding Nature}"/>
<Label Text="{Binding AmountHT }"/>
<Label Text="{Binding AmountReimbursed }"/>
<Label Text="{Binding AmountExceeds }"/>
<Label Text="{Binding ExpenseReport }"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
ListExpenses.xaml.cs
public partial class ListExpenses : ContentPage, INotifyPropertyChanged
{
public ListExpenses()
{
InitializeComponent();
GetExpense();
}
public async void GetExpense()
{ HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("http://192.168.1.6:3000/api/adepApi/GetExpenseReports");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await httpClient.GetAsync("http://192.168.1.6:3000/api/adepApi/GetExpenses");
var content = await response.Content.ReadAsStringAsync();
ResponseData EL = JsonConvert.DeserializeObject<ResponseData>(content);
viewRapport.ItemsSource = EL.Data.expenseRLists;
}
class ResponseData
{
public ExpensRapportList Data;
}
private List<Expense> expenseList { get; set; }
[JsonProperty("expenses")]
public List<Expense> expenseLists
{
get { return expenseList; }
set
{
if (value != expenseList)
{
expenseList = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Expense.cs
public class Expense{
public int Id { get; set; }
public string Name { get; set; }
public string Nature { get; set; }
public string AmountHT { get; set; }
public string AmountReimbursed { get; set; }
public string AmountExceeds { get; set; }
public string ExpenseReport { get; set; }
}
我的网络服务
[Description("Get Expenses")]
[AllowAnonymous]
[AcceptVerbs("GET", "POST")]
public System.Web.Mvc.JsonResult GetExpenses()
{
var WorkContext = EngineContext.Current.Resolve<IWorkContext>();
var expenseBo = EngineContext.Current.Resolve<IExpenseBo>();
var success = true;
var errorMessage = String.Empty;
var successNotificationMessage = String.Empty;
IList<ExpenseModelCustom> expenses = null;
try
{
expenses=new List<ExpenseModelCustom>();
expenses = expenseBo.GetExpenses();
}
catch (Exception ex)
{
success = false;
errorMessage = ex.Message;
}
return new System.Web.Mvc.JsonResult
{
Data = new
{
expenses = expenses,
Success = success,
}
};
}
Json:
{"ContentEncoding": null,
"ContentType": null,
"Data": {
"expenses": [
{
"userId": null,
"Id": 4362,
"Name": "fda",
"Description": null,
"Provider": null,
"Nature": "Déjeuner région Parisienne",
"AmountHT": 16.67,
"AmountTTC": 20,
"AmountReimbursed": 20,
"Tva": "20 %.",
"Remboursable": true,
"Distance": null,
"IsIk": false,
"ExpenseReport": "Senda JAOUANI",
"IsDeleted": false,
"StatusSystemName": "Draft",
"Status": "Draft_",
"HasDocuments": true,
"Devise": "€",
"ReportStatus": "Draft",
"AmountExceeds": false,
"Date": "2020-03-26T15:24:22",
"StartDate": null,
"EndDate": null,
"Departure": null,
"ExpenseNatureId": null,
"CurrencyId": null,
"TvaId": null,
"Quantity": null,
"ExpenseReportId": null,
"IsDeplacementComplementaire": null,
"IsFromHome": null,
"IsToHome": null,
"Remboursabledistance": null,
"DistanceHomeToWork": null,
"IsAlleRetour": null,
"MissionPlace": null,
"IsInclud": null,
"PhysicalEntityId": null,
"CompanyEntity3Id": null,
"ventilationTvaList": null,
"InvitedInExpense": null,
"ExternalInvitedInExpense": null,
"documentIds": null,
"Amount": null
},
{
"userId": null,
"Id": 4356,
"Name": "Reprise Initialisation de Plafond",
"Description": "Reprise Initialisation de plafond",
"Provider": null,
"Nature": "Petit déjeuner",
"AmountHT": 250,
"AmountTTC": 250,
"AmountReimbursed": 250,
"Tva": null,
"Remboursable": true,
"Distance": 100,
"IsIk": false,
"ExpenseReport": "Reprise Initialisation de Plafond",
"IsDeleted": false,
"StatusSystemName": "",
"Status": "",
"HasDocuments": false,
"Devise": "€",
"ReportStatus": "Approved",
"AmountExceeds": false,
"Date": "2019-11-28T00:00:00",
"StartDate": null,
"EndDate": null,
"Departure": null,
"ExpenseNatureId": null,
"CurrencyId": null,
"TvaId": null,
"Quantity": null,
"ExpenseReportId": null,
"IsDeplacementComplementaire": null,
"IsFromHome": null,
"IsToHome": null,
"Remboursabledistance": null,
"DistanceHomeToWork": null,
"IsAlleRetour": null,
"MissionPlace": null,
"IsInclud": null,
"PhysicalEntityId": null,
"CompanyEntity3Id": null,
"ventilationTvaList": null,
"InvitedInExpense": null,
"ExternalInvitedInExpense": null,
"documentIds": null,
"Amount": null
}
],
"Success": true }, "JsonRequestBehavior": 1, "MaxJsonLength": null, "RecursionLimit": null}
您的网络服务 returns 一个包装器对象,其中包含一个数组。所以你需要反序列化包装器。使用 json2csharp.com 将为您生成 类
// assume the wrapper class is "RootObject"
var data = JsonConvert.DeserializeObject<RootObject>(content);
// now your List of Expenses is a property of RootObject, let's assume
// it's called "Expenses"
listexpense.ItemsSource = data.Expenses;
您还需要更新 XAML 中的绑定路径以匹配修改后的费用对象的 属性 名称