Skip to content
This repository has been archived by the owner on Jan 24, 2021. It is now read-only.

External serializer does not take existing instance into account when using BindTo #1383

Closed
thecodejunkie opened this issue Dec 23, 2013 · 2 comments · May be fixed by NancyFx/Nancy.Serialization.JsonNet#6 or NancyFx/Nancy.Serialization.ServiceStack#6

Comments

@thecodejunkie
Copy link
Member

This is related to #1376

It looks like the the Nancy.Serializers.* does not take into account that when you call BindTo then the BindingContext can contain an existing instance that should be bound to, they will always try to create a new instance

https://github.com/NancyFx/Nancy.Serialization.JsonNet/blob/master/src/Nancy.Serialization.JsonNet/JsonNetBodyDeserializer.cs#L81

The same holds true for the ServiceStack serialization package

https://github.com/NancyFx/Nancy.Serialization.ServiceStack/blob/master/src/Nancy.Serialization.ServiceStack/Nancy.Serialization.ServiceStack/ServiceStackBodyDeserializer.cs#L46

We need to make sure we can distinguish an existing instance from a created one, because the Model is set by the DefaultBinder

https://github.com/NancyFx/Nancy/blob/master/src/Nancy/ModelBinding/DefaultBinder.cs#L334

@jchannon
Copy link
Member

I think this applies to the default body serializer too

Post["/serializer"] = _ =>
{
    var model = new FakeSerializerModel {CreatedOn = new DateTime(2014, 01, 30)};
    this.BindTo(model);
    return model;
};

[Fact]
public void Should_BindTo_Existing_Instance_Using_Body_Serializer()
{
    //Given
    var model = new FakeSerializerModel { Name = "Marsellus Wallace" };

    //When
    var result = browser.Post("/serializer", with =>
    {
        with.JsonBody(model);
        with.Accept("application/json");
    });

    var resultModel = result.Body.DeserializeJson<FakeSerializerModel>();

    //Then
    Assert.Equal("Marsellus Wallace", resultModel.Name);
    Assert.Equal(new DateTime(2014, 01, 30), resultModel.CreatedOn);
}

Test fails as the CreatedOn is DateTime.MinValue showing that an existing instance is ignored even though an existing instance is passed in. The same test passes when you POST with a FormValue.

The issue is this line https://github.com/NancyFx/Nancy/blob/master/src/Nancy/ModelBinding/DefaultBinder.cs#L269

The bindingContext.Configuration.Overwrite is true so it overwrites it.

The reason when POSTing with a form value is because there is no body deserialized model at this line: https://github.com/NancyFx/Nancy/blob/master/src/Nancy/ModelBinding/DefaultBinder.cs#L98

@khellang
Copy link
Member

khellang commented Dec 8, 2015

Closed by #1431

@khellang khellang closed this as completed Dec 8, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
4 participants