简体   繁体   中英

Deserialize JSON object into C#

In my ASP.NET MVC 5 webapp, on the client side, I have two JavaScript constructors

MyDate = function (y, m, d) {
    this.year = y;
    this.month = m;
    this.day = d;
}

Person = function (dateOfBirth, name) {
    this.dateOfBirth = dateOfBirth;
    this.name = name;
}

And on a Razor view, I have the following function which constructs a Person object and post it to an Action method

saveThisPerson = function () {

    var dob = new MyDate(1980, 5, 19);

    var p = new Person(dob, 'Mike');

    var requestUri = "/MyProfile/SaveThisPerson";
    var req = JSON.stringify(p);

    $http.post(requestUri, req).success(function (data) {
        // yeas !! this person is saved!!   
    })
}

On the C# side, this is the SaveThisPerson method:

[HttpPost]
public JsonResult SaveThisPerson(Person person)
{
    // omitted
}

And these are two C# classes needed

public class Person
{
    public MyDate DateOfBirth { get; set; }

    public string Name { get; set; }
}

public class MyDate
{
    public int Year { get; set; }

    public int Month { get; set; }

    public int Day { get; set; }
}

When I run it, the SaveThisPerson action method is called and the posted json is deserialized to a Person object with name field correctly populated (as "Mike"). But the DateOfBirth field has Year/Month/Day all equal to 0. What do I need to do to make the DateOfBirth field correctly deserialized? - in this case to Year = 1980, Month = 5, and Day = 19. Thanks

When using angular $http service, you do not need to use JSON.stringify . angular will take care of all those.

var dob = new MyDate(1980, 5, 19);
var p = new Person(dob, 'Mike');

var requestUri = "@Url.Action("SaveThisPerson","MyProfile")";   

$http.post(requestUri, p)
    .then(function (data) {
       console.log(data.data);
       // yeas !! this person is saved!!   
    });

The above code uses Url.Action helper method to build the correct relative url to the SaveThisPerson action method. If your javascript code is not in the razor view, but in an external js file, you should build the relative url to the app root and pass it to your javascript code as explained in this post.

Also, You should consider using the DateTime type in your DTO for the datetime instead of building your own custom class.

public class Person
{
    public DateTime DateOfBirth { get; set; }    
    public string Name { get; set; }
}

And angular/javascript code will be

var p = { Name="Scott" , DateOfBirth="12/26/2015" };
var requestUri = "@Url.Action("SaveThisPerson","MyProfile")";   

$http.post(requestUri, p)
    .then(function (data) {
       console.log(data.data);
       // yeas !! this person is saved!!   
    });

Change this part of you code.

   $.post(requestUri, {person:req}, function (data) {
    // yeas !! this person is saved!!   
   });

In your javascript, Remove MyDate class and have dateOfBirth as a string in Person class.

Change your person class like this;

public class Person
{
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
}

If you really need to have DateOfBirth as string, and want to be able to convert it in to a DateTime later, you may do this.

DateTime.ParseExact(dateOfBirth, "dd/MM/yyyy", CultureInfo.InvariantCulture);

If you still want to use MyDate class change your controller like this.

   [HttpPost]
    public JsonResult PostComplexType(string person)
    {
        var oPerson = JsonConvert.DeserializeObject<Person>(person);
        return Json("success");
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM