WebApi [FromBody]解析

时间:2017-06-29 13:55:19

标签: asp.net-web-api serialization frombodyattribute

我有一个现有的控制器[FromBody]HttpPost方法中正常工作。在编写测试时,我发现有必要使用客户序列化程序以避免循环引用,因为父对象具有引用父项的子对象。序列化程序使用以下设置:

JsonSerializerSettings Settings = new JsonSerializerSettings()
        {
            TypeNameHandling = TypeNameHandling.Auto,
            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            ObjectCreationHandling = ObjectCreationHandling.Auto
        };

问题是[FromBody]无法解析该序列化程序生成的对象(它会抛出Newtonsoft.Json.JsonSerializationException)。但是,如果我将[FromBody]更改为动态,例如

public IActionResult Update([FromBody]dynamic json)
{
   var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<MyType>(json);
   ...
}

然后我能够毫无问题地解析对象。这让我感到困惑,我想知道我是否可以覆盖WebApi为[FromBody]做的事情,这样我就可以获得正确的对象,而不必让每个方法都接受dynamic参数?

1 个答案:

答案 0 :(得分:1)

这是我在WebAPI中所做的事情。我有一个Team实体,它有许多Player实体。每个Player实体都有一个Team实体的引用。当我检索一个玩家时,它将拥有一个团队,团队将拥有所有玩家,每个玩家将再次拥有一个团队。

要处理这个问题,我不得不改变暴露数据和使用数据的方法。我为每个实体创建了模型并公开了模型对象。模型对象是扁平对象。对于Player模型,它具有TeamID和Team Name,而不是使用整个Team对象。

我使用模型工厂从模型中创建实体和实体的模型。在WebAPI控制器中,使用类似下面的内容

        [ModelValidator]
        public IHttpActionResult Post([FromBody] DoctorModel doctorModel)
        {
            try
            {
                var doctorEntity = ModelFactory.Create(doctorModel);
                doctorEntity.UserId = Userid;
                var doctor = UnitOfWork.Doctors.Add(doctorEntity);
                var doctorModelNew = ModelFactory.Create(doctor);
                return Ok(doctorModelNew);
            }
            catch (Exception ex)
            {
                //Logging    
#if DEBUG
                return InternalServerError(ex);
#endif
                return InternalServerError();
            }

        }