超链接按钮和 Json Uri
Hyperlink Button and Json Uri
在我的 UWP 应用程序中,我从 Json 文件解析文本图像和 URI,但是当我解析 URI 并在我的 xaml 页面中的超链接按钮中调用它时,没有任何反应。如果有人可以和我核对这段代码,请告诉我是否应该将字符串转换为 uri (Common_sense_media,metacritic) 或相反,或者告诉我如何使它工作
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
jsonCall();
}
public static BitmapImage ImageFromRelativePath(FrameworkElement parent, string path)
{
var uri = new Uri(parent.BaseUri, path);
BitmapImage result = new BitmapImage();
result.UriSource = uri;
return result;
}
public async void jsonCall()
{
List<Result> listResult = new List<Result>();
var client = new HttpClient();
String jsonString = await client.GetStringAsync(new Uri("http://api-public.guidebox.com/v1.43/Tunisia/rKgEWJbFg0kgEHrcGXPKhPDo0XtTafyC/movies/all/250/250"));
System.Diagnostics.Debug.WriteLine(JsonValue.Parse(jsonString).ValueType);
JsonObject root = JsonValue.Parse(jsonString).GetObject();
JsonArray res = root.GetNamedArray("results");
for (uint i = 0; i < res.Count; i++)
{
JsonObject con = res.GetObjectAt(i);
String id = con.GetNamedNumber("id").ToString();
String title = con.GetNamedString("title");
string release_year = con.GetNamedNumber("release_year").ToString();
string themoviedb = con.GetNamedNumber("themoviedb").ToString();
string original_title = con.GetNamedString("original_title");
JsonArray alt = con.GetNamedArray("alternate_titles");
String name = "-";
if (alt.Count != 0) {
name = alt.GetStringAt(0);
for (uint j = 1; j < alt.Count; j++)
{
name = name + ", " + alt.GetStringAt(j);
}
}
string imdb = con.GetNamedString("imdb");
string pre_order = con.GetNamedBoolean("pre_order").ToString();
string in_theaters = con.GetNamedBoolean("in_theaters").ToString();
string release_date = con.GetNamedString("release_date");
string rating = con.GetNamedString("rating");
string rottentomatoes = con.GetNamedNumber("rottentomatoes").ToString();
string freebase = con.GetNamedString("freebase");
string wikipedia_id = con.GetNamedNumber("wikipedia_id").ToString();
//System.Diagnostics.Debug.WriteLine("------------------------------"+con.GetNamedValue("metacritic").ValueType);
// string metacritic = con.GetNamedString("metacritic");
// MediaElement metacritic= VideoFromRelativePath(this, con.GetNamedValue("metacritic").ValueType.ToString());
string common_sense_media = con.GetNamedValue("common_sense_media").ToString();
string metacritic = con.GetNamedValue("metacritic").ToString();
// Uri Common_sense_media = con.GetNamedValue("Common_sense_media").ToString();
// string Common_sense_media = con.GetNamedValue("Common_sense_media").ToString();
//string Common_sense_media = con.GetNamedString("metacritic");
//System.Diagnostics.Debug.WriteLine("-------------"+Common_sense_media);
BitmapImage Poster_120x171 = ImageFromRelativePath(this, con.GetNamedString("poster_120x171"));
BitmapImage poster_240x342 = ImageFromRelativePath(this, con.GetNamedString("poster_240x342"));
BitmapImage poster_400x570 = ImageFromRelativePath(this, con.GetNamedString("poster_400x570"));
list.Items.Add(new Result {Id=id,Title=title,Themoviedb=themoviedb,Original_title=original_title,Alternate_titles=name,
Imdb=imdb,Pre_order=pre_order,In_theaters=in_theaters,Release_date=release_date,
Rating=rating, Rottentomatoes=rottentomatoes,Freebase=freebase,Wikipedia_id=wikipedia_id,
Common_sense_media = common_sense_media,
Metacritic= metacritic,
Poster = Poster_120x171, Poster_240x342=poster_240x342,Poster_400x570=poster_400x570});
}
}
}
}
我的xaml代码:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView
Name="list"
DataContext="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Orientation="Vertical">
<Image Source="{Binding Poster}" Width="100" Height="100"/>
<TextBlock
Name="id"
Text="{Binding Id}" />
<TextBlock
Name="title"
Text="{Binding Title}" />
<TextBlock
Name="release_year"
Text="{Binding Release_year}" />
<TextBlock
Name="themoviedb"
Text="{Binding Themoviedb}" />
<TextBlock
Name="original_title"
Text="{Binding Original_title}" />
<TextBlock
Name="alternate_titles"
Text="{Binding Alternate_titles}" />
<TextBlock
Name="imdb"
Text="{Binding Imdb}" />
<TextBlock
Name="pre_order"
Text="{Binding Pre_order}" />
<TextBlock
Name="in_theaters"
Text="{Binding In_theaters}" />
<TextBlock
Name="release_date"
Text="{Binding Release_date}" />
<HyperlinkButton Content="Common_sense_media" NavigateUri= "{Binding Common_sense_media}"/>
<HyperlinkButton Content="metacritic" NavigateUri= "{Binding metacritic}"/>
<TextBlock
Name="rating"
Text="{Binding Rating}" />
<TextBlock
Name="rottentomatoes"
Text="{Binding Rottentomatoes}" />
<TextBlock
Name="freebase"
Text="{Binding Freebase}" />
<TextBlock
Name="wikipedia_id"
Text="{Binding Wikipedia_id}" />
<TextBlock
Name="common_sense_media"
Text="{Binding Common_sense_media}" />
<TextBlock
Name="poster_120x171"
Text="{Binding Poster_120x171}" />
<Image Source="{Binding Poster_240x342}" Width="100" Height="100"/>
<Image Source="{Binding Poster_400x570}" Width="100" Height="100"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
HyperLinkButton 的给定字符串格式不正确 URL。双引号( ""
)被添加到字符串的每一端。所以如果你注意到你得到 BindingExpressionError(Error: Converter failed to convert value of type 'Windows.Foundation.String' to type 'Uri'; BindingExpression: Path='Common_sense_media' DataItem='test1.Result, test1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.HyperlinkButton' (Name='null'); target property is 'NavigateUri' (type 'Uri').
)
使用 Newtonsoft.Json 包进行 JSON 解析。它具有 JsonPropertyAttribute,允许您指定 Json 属性 的名称,指示 Newtonsoft.Json.JsonSerializer 始终序列化具有指定名称的成员。这是 tutorial 的 link。您只需将 [JsonProperty(keyname)]
添加到所有属性。库将反序列化 json 给你
只需一行代码 Result resu = Newtonsoft.Json.JsonConvert.DeserializeObject<Result>(con.ToString())
这里是简化的配对码
public class Result
{
//public string Alternate_titles { get; set; }
//public string Common_sense_media { get; set; }
//public string Freebase { get; set; }
//public string Id { get; set; }
//public string Imdb { get; set; }
//public string In_theaters { get; set; }
//public string Metacritic { get; set; }
//public string Original_title { get; set; }
//public BitmapImage Poster { get; set; }
//public BitmapImage Poster_240x342 { get; set; }
//public BitmapImage Poster_400x570 { get; set; }
//public string Pre_order { get; set; }
//public string Rating { get; set; }
//public string Release_date { get; set; }
//public string Rottentomatoes { get; set; }
//public string Themoviedb { get; set; }
//public string Title { get; set; }
//public string Wikipedia_id { get; set; }
//declare all above properties like below using JsonProperty
[JsonProperty("common_sense_media")]
public string Common_sense_media
{
get; set;
}
[JsonProperty("poster_120x171")]
public string Poster { get; set; }
[JsonProperty("poster_240x342")]
public string Poster_240x342 { get; set; }
[JsonProperty("poster_400x570")]
public string Poster_400x570 { get; set; }
}
public async void jsonCall()
{
List<Result> listResult = new List<Result>();
var client = new HttpClient();
String jsonString = await client.GetStringAsync(new Uri("http://api-public.guidebox.com/v1.43/Tunisia/rKgEWJbFg0kgEHrcGXPKhPDo0XtTafyC/movies/all/250/250"));
System.Diagnostics.Debug.WriteLine(JsonValue.Parse(jsonString).ValueType);
JsonObject root = JsonValue.Parse(jsonString).GetObject();
JsonArray res = root.GetNamedArray("results");
for (uint i = 0; i < res.Count; i++)
{
JsonObject con = res.GetObjectAt(i);
Result resu = Newtonsoft.Json.JsonConvert.DeserializeObject<Result>(con.ToString());
list.Items.Add(resu);
}
}
因为你得到的common_sense_media
值像"\"https://www.commonsensemedia.org/movie-reviews/magic-mike\""
一样在开头和结尾包含额外的双引号。所以你应该使用 Trim
删除它们,更改代码如下
string common_sense_media = con.GetNamedValue("common_sense_media").ToString().TrimStart('"').TrimEnd('"');
string metacritic = con.GetNamedValue("metacritic").ToString().TrimStart('"').TrimEnd('"');
更新后部分链接仍然无法访问,这是因为您的common_sense_media
和metacritic
的httprequest的return结果为空。对于这种情况,请按您的意愿处理。你可以简单判断
if(common_sense_media==null || metacritic==null)
{
//Do what you want do deal with them, such as give a default link
}
在我的 UWP 应用程序中,我从 Json 文件解析文本图像和 URI,但是当我解析 URI 并在我的 xaml 页面中的超链接按钮中调用它时,没有任何反应。如果有人可以和我核对这段代码,请告诉我是否应该将字符串转换为 uri (Common_sense_media,metacritic) 或相反,或者告诉我如何使它工作
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
jsonCall();
}
public static BitmapImage ImageFromRelativePath(FrameworkElement parent, string path)
{
var uri = new Uri(parent.BaseUri, path);
BitmapImage result = new BitmapImage();
result.UriSource = uri;
return result;
}
public async void jsonCall()
{
List<Result> listResult = new List<Result>();
var client = new HttpClient();
String jsonString = await client.GetStringAsync(new Uri("http://api-public.guidebox.com/v1.43/Tunisia/rKgEWJbFg0kgEHrcGXPKhPDo0XtTafyC/movies/all/250/250"));
System.Diagnostics.Debug.WriteLine(JsonValue.Parse(jsonString).ValueType);
JsonObject root = JsonValue.Parse(jsonString).GetObject();
JsonArray res = root.GetNamedArray("results");
for (uint i = 0; i < res.Count; i++)
{
JsonObject con = res.GetObjectAt(i);
String id = con.GetNamedNumber("id").ToString();
String title = con.GetNamedString("title");
string release_year = con.GetNamedNumber("release_year").ToString();
string themoviedb = con.GetNamedNumber("themoviedb").ToString();
string original_title = con.GetNamedString("original_title");
JsonArray alt = con.GetNamedArray("alternate_titles");
String name = "-";
if (alt.Count != 0) {
name = alt.GetStringAt(0);
for (uint j = 1; j < alt.Count; j++)
{
name = name + ", " + alt.GetStringAt(j);
}
}
string imdb = con.GetNamedString("imdb");
string pre_order = con.GetNamedBoolean("pre_order").ToString();
string in_theaters = con.GetNamedBoolean("in_theaters").ToString();
string release_date = con.GetNamedString("release_date");
string rating = con.GetNamedString("rating");
string rottentomatoes = con.GetNamedNumber("rottentomatoes").ToString();
string freebase = con.GetNamedString("freebase");
string wikipedia_id = con.GetNamedNumber("wikipedia_id").ToString();
//System.Diagnostics.Debug.WriteLine("------------------------------"+con.GetNamedValue("metacritic").ValueType);
// string metacritic = con.GetNamedString("metacritic");
// MediaElement metacritic= VideoFromRelativePath(this, con.GetNamedValue("metacritic").ValueType.ToString());
string common_sense_media = con.GetNamedValue("common_sense_media").ToString();
string metacritic = con.GetNamedValue("metacritic").ToString();
// Uri Common_sense_media = con.GetNamedValue("Common_sense_media").ToString();
// string Common_sense_media = con.GetNamedValue("Common_sense_media").ToString();
//string Common_sense_media = con.GetNamedString("metacritic");
//System.Diagnostics.Debug.WriteLine("-------------"+Common_sense_media);
BitmapImage Poster_120x171 = ImageFromRelativePath(this, con.GetNamedString("poster_120x171"));
BitmapImage poster_240x342 = ImageFromRelativePath(this, con.GetNamedString("poster_240x342"));
BitmapImage poster_400x570 = ImageFromRelativePath(this, con.GetNamedString("poster_400x570"));
list.Items.Add(new Result {Id=id,Title=title,Themoviedb=themoviedb,Original_title=original_title,Alternate_titles=name,
Imdb=imdb,Pre_order=pre_order,In_theaters=in_theaters,Release_date=release_date,
Rating=rating, Rottentomatoes=rottentomatoes,Freebase=freebase,Wikipedia_id=wikipedia_id,
Common_sense_media = common_sense_media,
Metacritic= metacritic,
Poster = Poster_120x171, Poster_240x342=poster_240x342,Poster_400x570=poster_400x570});
}
}
}
}
我的xaml代码:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView
Name="list"
DataContext="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Orientation="Vertical">
<Image Source="{Binding Poster}" Width="100" Height="100"/>
<TextBlock
Name="id"
Text="{Binding Id}" />
<TextBlock
Name="title"
Text="{Binding Title}" />
<TextBlock
Name="release_year"
Text="{Binding Release_year}" />
<TextBlock
Name="themoviedb"
Text="{Binding Themoviedb}" />
<TextBlock
Name="original_title"
Text="{Binding Original_title}" />
<TextBlock
Name="alternate_titles"
Text="{Binding Alternate_titles}" />
<TextBlock
Name="imdb"
Text="{Binding Imdb}" />
<TextBlock
Name="pre_order"
Text="{Binding Pre_order}" />
<TextBlock
Name="in_theaters"
Text="{Binding In_theaters}" />
<TextBlock
Name="release_date"
Text="{Binding Release_date}" />
<HyperlinkButton Content="Common_sense_media" NavigateUri= "{Binding Common_sense_media}"/>
<HyperlinkButton Content="metacritic" NavigateUri= "{Binding metacritic}"/>
<TextBlock
Name="rating"
Text="{Binding Rating}" />
<TextBlock
Name="rottentomatoes"
Text="{Binding Rottentomatoes}" />
<TextBlock
Name="freebase"
Text="{Binding Freebase}" />
<TextBlock
Name="wikipedia_id"
Text="{Binding Wikipedia_id}" />
<TextBlock
Name="common_sense_media"
Text="{Binding Common_sense_media}" />
<TextBlock
Name="poster_120x171"
Text="{Binding Poster_120x171}" />
<Image Source="{Binding Poster_240x342}" Width="100" Height="100"/>
<Image Source="{Binding Poster_400x570}" Width="100" Height="100"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
HyperLinkButton 的给定字符串格式不正确 URL。双引号( ""
)被添加到字符串的每一端。所以如果你注意到你得到 BindingExpressionError(Error: Converter failed to convert value of type 'Windows.Foundation.String' to type 'Uri'; BindingExpression: Path='Common_sense_media' DataItem='test1.Result, test1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.HyperlinkButton' (Name='null'); target property is 'NavigateUri' (type 'Uri').
)
使用 Newtonsoft.Json 包进行 JSON 解析。它具有 JsonPropertyAttribute,允许您指定 Json 属性 的名称,指示 Newtonsoft.Json.JsonSerializer 始终序列化具有指定名称的成员。这是 tutorial 的 link。您只需将 [JsonProperty(keyname)]
添加到所有属性。库将反序列化 json 给你
只需一行代码 Result resu = Newtonsoft.Json.JsonConvert.DeserializeObject<Result>(con.ToString())
这里是简化的配对码
public class Result
{
//public string Alternate_titles { get; set; }
//public string Common_sense_media { get; set; }
//public string Freebase { get; set; }
//public string Id { get; set; }
//public string Imdb { get; set; }
//public string In_theaters { get; set; }
//public string Metacritic { get; set; }
//public string Original_title { get; set; }
//public BitmapImage Poster { get; set; }
//public BitmapImage Poster_240x342 { get; set; }
//public BitmapImage Poster_400x570 { get; set; }
//public string Pre_order { get; set; }
//public string Rating { get; set; }
//public string Release_date { get; set; }
//public string Rottentomatoes { get; set; }
//public string Themoviedb { get; set; }
//public string Title { get; set; }
//public string Wikipedia_id { get; set; }
//declare all above properties like below using JsonProperty
[JsonProperty("common_sense_media")]
public string Common_sense_media
{
get; set;
}
[JsonProperty("poster_120x171")]
public string Poster { get; set; }
[JsonProperty("poster_240x342")]
public string Poster_240x342 { get; set; }
[JsonProperty("poster_400x570")]
public string Poster_400x570 { get; set; }
}
public async void jsonCall()
{
List<Result> listResult = new List<Result>();
var client = new HttpClient();
String jsonString = await client.GetStringAsync(new Uri("http://api-public.guidebox.com/v1.43/Tunisia/rKgEWJbFg0kgEHrcGXPKhPDo0XtTafyC/movies/all/250/250"));
System.Diagnostics.Debug.WriteLine(JsonValue.Parse(jsonString).ValueType);
JsonObject root = JsonValue.Parse(jsonString).GetObject();
JsonArray res = root.GetNamedArray("results");
for (uint i = 0; i < res.Count; i++)
{
JsonObject con = res.GetObjectAt(i);
Result resu = Newtonsoft.Json.JsonConvert.DeserializeObject<Result>(con.ToString());
list.Items.Add(resu);
}
}
因为你得到的common_sense_media
值像"\"https://www.commonsensemedia.org/movie-reviews/magic-mike\""
一样在开头和结尾包含额外的双引号。所以你应该使用 Trim
删除它们,更改代码如下
string common_sense_media = con.GetNamedValue("common_sense_media").ToString().TrimStart('"').TrimEnd('"');
string metacritic = con.GetNamedValue("metacritic").ToString().TrimStart('"').TrimEnd('"');
更新后部分链接仍然无法访问,这是因为您的common_sense_media
和metacritic
的httprequest的return结果为空。对于这种情况,请按您的意愿处理。你可以简单判断
if(common_sense_media==null || metacritic==null)
{
//Do what you want do deal with them, such as give a default link
}