vs2010 学习Silverlight学习笔记(15):数据与通信之JSON

概述:

       有段时间没学习了,该继续了。不一定写完就发,有可能最后一起发。这个JSON我以前不太了解,只知道是web传输中的一种格式。今天初步了解一下这篇关于JSON是干什么的,写完后再看看W3C中JSON的资料。

内容:

       创建两个实体,一个Post类,一个Blog类。与以往不同的是在sl中也有着相同两个类。

Post.cs

public class Post
{
    public int Id { get; set; }
 
    public string Title { get; set; }
 
    public string Author { get; set; }
}

Blog.cs

public class Blog
{
    public List<Post> Posts { get; set; }
}

新建HttpHandler用于向sl传输JSON数据。

public class BlogHandler : IHttpHandler
{
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            //context.Response.Write("Hello World");
            List<Post> posts = new List<Post>() 
            {
                new Post{Id=1,Title="1a",Author="li"},
                new Post{Id=2,Title="2a",Author="li"},
                new Post{Id=3,Title="3a",Author="li"},
                new Post{Id=4,Title="4a",Author="li"},
                new Post{Id=5,Title="5a",Author="li"}
            };
            Blog blog = new Blog();
            blog.Posts = posts;
            context.Response.Write(JavaScriptConvert.SerializeObject(blog));
        }    
        public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
传出数据的这一句:context.Response.Write(JavaScriptConvert.SerializeObject(blog));

所用的的JavaScriptConvert.SerializeObject来自JSON,在sl中添加引用中会有System.Json;但这WEB中并没有,这里用的是老师源码中的Dll文件引用。有兴趣的可以对Json.net做了解。

       在此时可以查看http://localhost:8081/BlogHandler.ashx,但此时浏览器显示的是错误:文件顶层无效。在下面的留言中也发现有个这错误的,但并没有原因和方法。先不管他,做剩下的部分。

布局界面:

<UserControlx:Class="SLDemo16JOSN.MainPage"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

   mc:Ignorable="d"

   d:DesignHeight="300" d:DesignWidth="400"Loaded="UserControl_Loaded">

   <Grid Background="#46461F">

       <Grid.RowDefinitions>

            <RowDefinitionHeight="40"></RowDefinition>

           <RowDefinition Height="*"></RowDefinition>

       </Grid.RowDefinitions>

       <Grid.ColumnDefinitions>

           <ColumnDefinition></ColumnDefinition>

       </Grid.ColumnDefinitions>

       <Border Grid.Row="0" Grid.Column="0"CornerRadius="15"

           Width="240" Height="36"Background="Orange"

           Margin="20 0 0 0" HorizontalAlignment="Left">

           <TextBlock Text="最新随笔" Foreground="White"

                   HorizontalAlignment="Left"VerticalAlignment="Center"

                   Margin="20 0 00"></TextBlock>

       </Border>

       <ListBox x:Name="Posts" Grid.Row="1"Margin="40 10 10 10">

           <ListBox.ItemTemplate>

                <DataTemplate>

                    <StackPanelOrientation="Horizontal">

                        <TextBlockText="{Binding Id}" Height="40"Foreground="Red"></TextBlock>

                        <TextBlockText="{Binding Title}" Height="40"></TextBlock>

                        <TextBlock Text="{BindingAuthor}" Height="40"Foreground="Orange"></TextBlock>

                    </StackPanel>

                </DataTemplate>

           </ListBox.ItemTemplate>

       </ListBox>

   </Grid>

</UserControl>

MainPage.cs界面:需要添加引用System.Net;,System.ServiceModel.Web;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Net;

using System.IO;

using System.Runtime.Serialization.Json;

using System.Threading;

namespace SLDemo16JOSN

{

   public partial class MainPage : UserControl

    {

       public MainPage()

       {

           InitializeComponent();

       }

       private void UserControl_Loaded(object sender, RoutedEventArgs e)

       {

           Uri endpoint = newUri("http://localhost:8081/BlogHandler.ashx");

           WebRequest request = WebRequest.Create(endpoint);

           request.Method = "POST";

           request.ContentType = "application/x-www-form-urlencoded";

           request.BeginGetResponse(new AsyncCallback(ResponseReady), request);

       }

       void ResponseReady(IAsyncResult asyncResult)

       {

           WebRequest request = asyncResult.AsyncState as WebRequest;

           WebResponse response = request.EndGetResponse(asyncResult);

           using (Stream responseStream = response.GetResponseStream())

           {

                DataContractJsonSerializerjsonSerializer =

                    newDataContractJsonSerializer(typeof(Blog));

                Blog blog =jsonSerializer.ReadObject(responseStream) as Blog;

                //Posts.ItemsSource = blog.Posts;

                //new Thread(() => {Posts.Dispatcher.BeginInvoke(() => Posts.ItemsSource = blog.Posts);}).Start();

                Posts.Dispatcher.BeginInvoke(()=> Posts.ItemsSource = blog.Posts);

           }

       }

    }

}

可能是因为Handler在浏览器中出错的原因吧,在sl页面数据赋值的时候用原来的:

//Posts.ItemsSource = blog.Posts;就会出现数据为空的情况。

具体原因我不了解,不过有人给出了如下两种解决方法:

new Thread(() => {Posts.Dispatcher.BeginInvoke(() => Posts.ItemsSource = blog.Posts);}).Start();

               或 Posts.Dispatcher.BeginInvoke(() => Posts.ItemsSource =blog.Posts);

总结:

       这个JSON以前没接触过,以后也不一定接触多少。我认为学习这个主要不是记住这篇中每一句代码应该怎么写,而是以后遇到时我只知道用JSON需要怎么序列化和怎么反序列化格式,具体的代码可以网上查一查。已经学了几篇的数据通信部分了,其实好多东西差不多,服务器端不是Handler,就是Service,数据先要封装序列化,然后再反序列化显示。但我觉得就凭我这并不聪明的脑袋,记住所有的使用方法是有困难的,但记住他们的区别和关键特征还是有可能的。

原文地址:https://www.cnblogs.com/yaoge/p/1822604.html