+44(0) 1234 567 890 info@domainname.com

Monday, January 21, 2013

ASP.NET – Serialize đối tượng .NET thành JSON và ngược lại

7:20 PM

Share it Please
Các dữ liệu JSON được sử dụng rất thường xuyên trong ứng dụng web, đặc biệt khi cần truyền dữ liệu thông qua ajax. Trong ASP.NET, bạn có thể sử dụng classJavaScriptSerializer để chuyển đối một đối tượng .NET (hay CLR) bất kì thành một chuỗi JSON và ngược lại. Đồng thời, bạn có thể tạo ra các JavaScriptConverter để quy định cách thức chuyển đổi của JavaScriptSerializer.

Cơ bản

Trong bài viết này, tôi sử dụng một ứng dụng kiểu Console vì vậy cần phải thêm tham chiếu đến assembly System.Web.Script.Serialization. Class  JavaScriptSerializer chứa hai phương thức là  Serialize() và  Deserialize() dùng để chuyển đối tượng thành chuỗi JSON và ngược lại. Với một collection, phương thức Serialize() sẽ trả về một chuỗi JSON dạng mảng.

class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Birthday { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        var js = new JavaScriptSerializer();
        var foo=new Foo(){
            Id = 1,
            Name = "Bar",
            Birthday = DateTime.Today
        };
        var json = js.Serialize(foo);
        Console.WriteLine("+ Serialize:\n"+json+"\n");
        var obj = (Foo) js.Deserialize(json, typeof(Foo));
        Console.WriteLine("+ Deserialize:\nId = {0} \nName = {1} \nBirthday = {2}",obj.Id,obj.Name,obj.Birthday);
        Console.Read();
    }
}
Ouput:

+ Serialize:
{"Id":1,"Name":"Bar","Birthday":"\/Date(1329670800000)\/"}
+ Deserialize:
Id = 1
Name = Bar
Birthday = 2/19/2012 5:00:00 PM

Sử dụng JavaScriptConverter

Trong ví dụ trên, kiểu dữ liệu DateTime được serialize thành một chuỗi rất khó để đọc và định dạng khi cần thiết. Vì thế tôi sẽ tạo một tạo một converter sau đó đăng kí cho đối tượng  JavaScriptSerializer. Converter tôi cần tạo phải được thừa kế từ JavaScriptConverter. Class này có 3 thành viên cần được override trong subclass:
-        SupportedTypes: property này sẽ trả về một danh sách các kiểu dữ liệu được hỗ trợ bởi converter này.
-        Serialize: Phương thức này sẽ tạo một đối tượng Dictionary chứa các cặp name/value dùng để chuyển đổi một đối tượng thành JSON.
-        Deserialize: Phương thức này nhận các dữ liệu cần thiết từ một Dictionary để tạo ra đối tượng .NET.
Như vậy Dictionary chính là đối tượng trung gian của quá trình chuyển đổi giữa đối tượng .NET và JSON. Mọi công việc mà bạn cần thực hiện chỉ đơn giản là thao tác trên dữ liệu của đối tượng Dictionary.
Tôi sẽ viết một class  MyFooConverter và sau đó đăng kí một instance của nó vào  JavaScriptSerializer bằng phương thức  RegisterConverters():

public class MyFooConverter : JavaScriptConverter
{
    public override IEnumerable SupportedTypes
    {
        get { return new List() { typeof(Foo) }; }
    }
    public override IDictionary Serialize(object obj, JavaScriptSerializer serializer)
    {
        var result = new Dictionary();
        var foo = obj as Foo;
        if (foo == null)
            return result;
        result["Id"] = foo.Id;
        result["Name"] = foo.Name;
        result["Birthday"] = foo.Birthday.ToShortDateString();
        return result;
    }
    public override object Deserialize(IDictionary dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");
        return new Foo()
        {
            Id = (int) dictionary["Id"],
            Name = (string) dictionary["Name"],
            Birthday = DateTime.Parse(dictionary["Birthday"].ToString())
        };
    }
}
// Main method:
// …
 var js = new JavaScriptSerializer();
        js.RegisterConverters(new []{ new MyFooConverter() });
// ...
Output:


{"Id":1,"Name":"Bar","Birthday":"2/20/2012"}

Một Converter linh hoạt hơn

Sẽ rất bất tiện nếu như đối tượng bạn cần chuyển đối có quá nhiều property, việc override hai phương thức Serialize() và Deserialize() sẽ chiếm một số lượng code kha khá. Vì vậy, để giải quyết vấn đề này, tôi sẽ sử dụng reflection để tự động xây dựng một Dictionary từ đối tượng:

public class MyFooConverter : JavaScriptConverter
{
    public override IEnumerable SupportedTypes
    {
        get { return new List() { typeof(Foo) }; }
    }
    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        if (obj == null)
            return new Dictionary<string, object>();
        var result = obj.GetType()
             .GetProperties()
             .ToDictionary(p => p.Name, p => p.GetValue(obj, null));
        result["Birthday"] = ((DateTime)result["Birthday"]).ToShortDateString();
        return result;
    }
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");
        return new Foo()
        {
            Id = (int) dictionary["Id"],
            Name = (string) dictionary["Name"],
            Birthday = DateTime.Parse(dictionary["Birthday"].ToString())
        };
    }
}

Đoạn mã trên chỉ là một ví dụ đơn giản về cách làm và nó cần phải cải tiến để có thể được cho mọi class. Bạn có thể gọi đây là một JsDateTimeConverter, nhưng dĩ nhiên bạn có thể thay đổi nó để chuyển đối cả các kiểu dữ liệu khác về định dạng JSON cần thiết. Đây mới thực sự là đoạn mã tôi muốn giới thiệu:

Một Generic Javascript Converter

Kết hợp generic, LINQ và reflection để giải quyết, tôi được đoạn mã sau:

public class MyJsConverter : JavaScriptConverter
{
    public override IEnumerable SupportedTypes
    {
        get { return new List() { typeof(T) }; }
    }
    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        if (obj == null)
            return new Dictionary<string, object>();
        var result = obj.GetType()
             .GetProperties()
             .ToDictionary(p => p.Name,
                p => {
                 var value = p.GetValue(obj, null);
                 if (value.GetType() == typeof(DateTime))
                     value = ((DateTime)value).ToShortDateString();
                 return value;
                });
        return result;
    }
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");
        var foo = Activator.CreateInstance();
        foreach (var property in type.GetProperties())
        {
            var value = dictionary[property.Name];
            if (property.PropertyType == typeof(DateTime))
                value = DateTime.Parse(value.ToString());
            property.SetValue(foo,value,null);
        }
        return foo;
    }
}
Khi đăng kí, bạn cần xác định rõ kiểu dữ liệu cần chuyển đổi, hoặc bạn cũng có thể tạo một class converter sử dụng kiểu object:

var js = new JavaScriptSerializer();
js.RegisterConverters(new []{new MyJsConverter()});

0 comments:

Post a Comment

Tags

Thủ thuật pc Góc Làm Đẹp Làm Đẹp Da Thủ Thuật Blogspot - Wordpress - Joomla Thủ Thuật Network Giải trí Thủ Thuật Hay thu-thuat-blogspot ASP.NET Danh bạ Lập trình CSDL Thủ Thuật Blog Lập trình Thủ thuật Excel Phần Mềm Góc Phụ Nữ SEO TT Windows Lý Thuyết CCNA Dịch Vụ Hot CCNA Sức Khỏe - Đời Sống Office Thủ Thuật Mobile Thủ Thuật Win 8 Download Xây dựng liên kết Android Thủ thuật Word Website thu-thuat-internet Forum PHP Tư Vấn Làm Đẹp Mẹo Vặt tien-ich-widget Đọc báo ASP.NET MVC Ca nhạc Hỏi Đáp Thơ Vui Thủ Thuật Game vui-nhon Download Phần Mềm - Crack VBA Excel thu-thuat-facebook Cuộc sống Download Game Photoshop Thủ thuật Blogspot VBA trong Excel Widget Blogspot Địa Điểm Hot C# CSS Giới Tính Tài Liệu Đại học Chuyện lạ Clip Hài - Video Hot Góc Kỹ Năng Góc Sinh Viên Liên Minh Huyền Thoại Sao Sức Khỏe Giới Tính Thủ Thuật Tin Học template-blogger Chuyện Của Sao Design Pattern Kiến thức cơ bản PM hệ thống Thủ thuật Facebook Tin nổi bật Đề thi LAB CCNA Love story Học và hỏi Môn toán Spring.NET Tủ Sách Video lam-quen-voi-blogger Ảnh Vui Bảng Giá Con trai Cẩm nang du học Dependency Injection Hình ảnh Kinh nghiệm học Kỹ Năng Xin Việc Luật Pháp ORM Tin nóng Tiện ích Truyện cười Việt Nam hinh-anh-hai-huoc tho-vui-con-coc thu-thuat-phan-mem Blogspot Distributed Technologies Hợp Tác Kinh Doanh Khám phá MVP NHibernate Photoshop Action Thủ Thuật Win 7 Trẻ Tư Vấn Tiêu Dùng VietYeah TV Xã Hội thu-thuat-SEO Blogger Templates Game flash Khối B Nghịch Nhân vật Phong Cách Slider Thư giãn Thủ thuật Youtube WCF facebook hinh-anh-dep thu-thuat-may-tinh Đời Sống 2010 Con gái Download Game Mobile Drivers External Post Học Nấu Ăn Học vui Làm Đẹp Tóc MVC N-Tier PM hệ điều hành Sao Quốc tế Thủ thuật internet Thông Tin Tin Tức Hot Tivi Truyện Hay Tuyển Dụng Xả Stress Youtube anh-bia-facebook san-pham-google ung-dung-website Đáp án Đề thi thử AOP Abstract Factory Cool stuffs Design Principles Khối A Thông tin mạng Tình yêu lập trình viên phan-mem-van-phong thu-thuat-windows-7 thu-thuat-windows-8 Điện Tử Ảnh Nghệ Thuật 2009 2011 2012 Adapter Pattern Công Nghệ Factory Method Game Hình sự Khối D Kiếm Tiền Qua Mạng Kỹ Năng Nơi Công Sở LinQ Menu Miễn phí Photoshop PSD Sexy Singleton Sành điệu Thủ Thuật Di Động Tin nhắn SMS phan-mem-do-hoa phan-mem-tien-ich Đọc xong vọc liền .NET Remoting 10-thing series 2013 Ajax Bridge Pattern Bóng đá Castle Windsor Chơi Game Online Cover Facebook Có Thể Bạn Chưa Biết Download Phim Dịch vụ Fedora Garbage Collection Google Plus Góc Tâm Sự HTML Hibernate Hài hước IoC JSF Javascript Jquery Khối C Kỹ Năng Bán Hàng Kỹ Năng Thuyết Trình Lazy Load Linux Lock Log4Net MWC Memory Management Mock Multi-Thread MySQL Môn sử Mặc Đẹp Mẹ Và Bé Mỹ Tâm NUnit Ngọc Trinh Nhịp sống trẻ PM văn phòng POCO Passive View Photoshop tách ảnh Phạm Băng Băng Phầm Mềm Crack PostSharp Primefaces Shop Bít Tuốt Strategy Pattern Supervising Controller Sự kiện Thể thao Thủ Thuật Office Tin đặc biệt Toán Tình bạn Tình dục Tốt nghiệp Unit Testing VBA Word Virtual Server Văn WMC 2012 Windows Service acc fshare acc mien phi anh-nghe-thuat cntt di dong di động dropbox dung luong dropbox fshare hinh nen hinh nen dep hình nền job mac os mang xa hoi may ao mạng xã hội social tang dung luong dropbox thu-thuat-mobile thu-thuat-windows-xp tháng 2 top truyen-cuoi tăng dung lượng dropbox vmware Ảnh đẹp