2017-06-29 48 views
1

我有一個現有的控制器,其中[FromBody]正如HttpPost方法所期望的那樣工作。在編寫測試時,我發現有必要使用客戶序列化程序,以避免由於父對象具有引用父對象的子對象而引起的循環引用。串行化器使用這些設置:WebApi [FromBody]解析

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參數的情況下獲得正確的對象?

+0

我假設您直接使用實體。我的意思是你使用相同的實體爲你的數據庫操作和API返回類型? –

+0

沒錯,我的一些API調用其他API,因此這種序列化/反序列化對我很重要 – riqitang

回答

1

這是我在我的WebAPI中做的事情。我有一個擁有許多Player實體的Team實體。每個玩家實體都有一個對團隊實體的引用。當我找回一名球員時,將會有一支球隊,而球隊會讓所有球員和每名球員再次擁有一支球隊。

要處理這個問題,我必須改變公開數據和使用數據的方法。我爲每個實體創建了模型並暴露了模型對象。模型對象是平面對象。在玩家模型的情況下,它具有TeamID和團隊名稱,而不是使用整個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(); 
      } 

     } 
+0

您的意思是讓控制器對API命令使用不同的模型,並且控制器使用的服務使用實體框架數據庫模型?這種方法可能會起作用,但我不打算將答案標記爲已被接受,但我希望首先看到其他答案。 – riqitang