2017/08/30

[C#] 透過 JSON 進行資料前後端傳遞

透過 JSON 字串進行資料前後端傳遞已是非常普遍的作法。此作法好處在於可跨網域進行資料交換。這邊將記錄後端資料透過 Ajax 傳遞給前端、及兩種前端透過 Ajax 方式傳遞給後端的作法。

首先,先定義一下所需要的 Model 架構:
//C#: Model
public class Movie
{
    public int ID { get; set; }

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]
    [Required]
    [StringLength(30)]
    public string Genre { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]
    [StringLength(5)]
    [Required]
    public string Rating { get; set; }
}

1. 後端資料傳遞給前端

後端傳遞給前端的作法還滿單純的,只要建立一個回傳型別為
JsonResult
的 Action,並回傳一個 JSON 物件即可
//C#: Controller
public JsonResult GetMovies()
{
    List<Movie> lstMovie = new List(){
        new Movie
        {
            Title = "When Harry Met Sally",
            ReleaseDate = DateTime.Parse("1989-1-11"),
            Genre = "Romantic Comedy",
            Price = 7.99M
        },
        new Movie
        {
            Title = "Ghostbusters ",
            ReleaseDate = DateTime.Parse("1984-3-13"),
            Genre = "Comedy",
            Price = 8.99M
        },
        new Movie
        {
            Title = "Ghostbusters 2",
            ReleaseDate = DateTime.Parse("1986-2-23"),
            Genre = "Comedy",
            Price = 9.99M
        },
        new Movie
        {
            Title = "Rio Bravo",
            ReleaseDate = DateTime.Parse("1959-4-15"),
            Genre = "Western",
            Price = 3.99M
        }
    };

    return Json(new { MoviesList = JsonConvert.SerializeObject(lstMovie) });
}
前端接收到資料後,即可透過
data.PropertyName
方式取得資料。
//C#: View (JavaScript)
function GetMovies() {
    $.post(
        '@Url.Action("GetMovies")',
        '',
        function (data) {
            alert(typeof data.moviesList);  //return "string"
            var lst = JSON.parse(data.moviesList);
            alert(typeof lst); //return "object"
            for (var i = 0; i < lst.length; i++) {
                alert('Title: ' + lst[i].Title);
            }
        },
        'json');
}
然而由於範例中,Action 取得的是一個清單 (List<T>),因此在回傳時須將 List<T> 透過
JsonConvert.SerializeObject()
方式將清單內容序列化成字串,待前端取得資料後,再使用 JavaScript 的
JSON.parse()
將已序列字串的內容再次反序列回 JSON 物件。


2. 前端資料傳遞給後端

前端資料傳遞到後端有兩種方式,第一種是直接將 JSON 物件序列化後以字串方式傳遞給 Server 端,另一種是不產生 JSON,而是產生矩陣 (Array) 物件,並以「參數」的方式將矩陣方式傳遞給 Server 端。

2.1 使用 JSON

此種方式最主要的關鍵在於資料傳遞至 Server 端前,先將 JSON 物件透過
JSON.stringify()
方法轉換成序列化的字串。
//C#: View (JavaScript)
//透過已 stringifly 的字串,將資料傳至 Server 後端
function AddMovie_PassString() {

    var movie = [
        //Movie 1
        {
            "ID": 1,
            "Title": "movie title 1",
            "ReleaseDate": "2017-08-15",
            "Price" : 15.89,
            "Genre": "Comedy",
            "Rating": "4.5"
        },
        //Movie 2
        {
            "ID": 2,
            "Title": "movie title 2",
            "ReleaseDate": "2017-08-15",
            "Price": 14.99,
            "Genre": "Comedy",
            "Rating": "3.5"
        }];

    //Post data to server
    $.post(
        '@Url.Action("AddMovies_ByPassString")',
        { "dataPost": JSON.stringify(movie) },
        function (data) {
            //Do something here...
        },
        'json'
    );
}


當 Server 端接收到字串後,再透過
JsonConvert.DeserializeObject()
方式轉型成 List<T> 型別物件。
//C#: Controller
public JsonResult AddMovies_ByPassString(string dataPost)
{
    List lst = JsonConvert.DeserializeObject<List<Movie>>(dataPost);
    return Json(new { Result = true, Msg = "OK" });
}

2.2 使用 Array

上述 2.1 透過 JSON 物件麻煩處在於資料傳遞至後端時需要進行序列化的轉換,但若透過陣列作為參數進行傳遞,再搭配 MVC 的 DataBinding 的機制,資訊取得後並不需要任何型別轉換即可立即使用,似乎更加適合懶人的我。
//C#: View (JavaScript)

//透過已陣列物件,將資料傳至 Server 後端
function AddMovie_PassArray() {

    var data_array = [];
    data_array.push({
        "ID": 3,
        "Title": "movie by array 1",
        "ReleaseDate": "2017-08-15",
        "Price": 18.99,
        "Genre": "Comedy",
        "Rating": "4.5"
    });
    data_array.push({
        "ID": 4,
        "Title": "movie by array 2",
        "ReleaseDate": "2017-08-15",
        "Price": 21.98,
        "Genre": "Comedy",
        "Rating": "3"
    });

    //Post datas to server
    $.post(
        '@Url.Action("AddMovies_ByArrayObj")',
        { "dataPost": data_array },
        function (result) {
            //Do something here...
        },
        "json"
    );
}

//C#: Controller
public JsonResult AddMovies_ByArrayObj(IEnumerable dataPost)
{
    return Json(new { Result = true, Msg = "OK" });
}

沒有留言 :

張貼留言

注意:只有此網誌的成員可以留言。