0

我正在用ASP.NET構建WebApi。現在我將整個應用程序劃分爲幾個層,其中兩個是「接口」和「模型」(每個層都有自己的.dll)。在「models.dll」中,我定義了所有模型,並在應用程序開始注入需要的地方。到現在爲止還挺好。現在,當我從我的控制檯返回值時,我正面臨一個問題。讓我們假設如下:C#(Web API)依賴注入(帶Unity)返回類型接口

public class TestController : ApiController 
{ 
    IBusinessObject _businessObject; 

    public TestController(IBusinessObject businessObject) 
    { 
     this._businessObject= businessObject; 
    } 

    [Route("details/object/{id}")] 
    [HttpGet] 
    public ISomeObject GetObjectByNr(int id) 
    { 
     return this._businessObject.SearchForObject(id); 
    } 
} 

現在,當你在看GetObjectByNr你可以看到,它的返回類型是ISomeObject(當然回報this._businessObject.SearchForObject(ID類型)也ISomeObject)。 ISomeObject的實際實現在ModelLayer內部,但我不想將它包含到我的WebApi項目中,因爲它僅通過接口進行通信。現在,當我像這樣運行它時,我得到一個錯誤,說我應該使用DataContractResolver(以及一些關於序列化的內容)。我意識到我無法序列化一個接口,但我認爲我的應用程序足夠聰明,可以在這裏找到正確的類(在開始時,我確實解析了所有接口,並且在調用this._businessObject.SearchForObject(id)時調用了正確的類,用正確的值填充,但在此時返回對象時,出現錯誤)。我一直在看SO,並找到了一些「途徑」,例如KnownType(typeof(SomeObject))屬性。但是當我嘗試在TestController中設置它時,它並沒有被識別(但即使這可以工作,它也需要對我的實際模型類的引用,我不希望那樣)。

有沒有什麼辦法讓我的接口可序列化,並返回正確的對象,而實際上不告訴我的控制器ISomeObject的實現是什麼?

感謝

+0

你能發佈確切的錯誤/例外,沒有內在的原因你不能序列化一個接口,想想有多少控制器的操作返回'IEnumerable '。 – 2014-10-06 13:40:42

+0

接口不可序列化。它們只是一個對象實現的契約。 – 2014-10-06 13:42:02

+0

也許我錯誤地敘述了它,但是您可以序列化一個實現接口的對象,而無需知道任何有關實現的信息。 – 2014-10-06 13:47:48

回答

0

編輯:使用您自己的MediaTypeFormatter

嘗試。您可以使用sharpSerializer或Json.NET。有資料如何做到這一點:

http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

http://www.asp.net/web-api/overview/advanced/configuring-aspnet-web-api

編輯注:下面的代碼是針對MVC控制器,不是的WebAPI ApiController。

如果你沒有綁定到DataContractSerializer,你可以使用其他的,比如json序列化。例如,你可以使用Json.NET。最方便的方法是重寫默認JSON結果的行爲:

public class JsonNetResult : JsonResult 
{ 

    public JsonSerializerSettings SerializerSettings { get; set; } 
    public Formatting Formatting { get; set; } 

    public JsonNetResult() 
    { 
     Formatting = Formatting.None; 
     SerializerSettings = new JsonSerializerSettings(); 
     JsonRequestBehavior = JsonRequestBehavior.DenyGet; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     if (context == null) 
      throw new ArgumentNullException("context"); 

     if (JsonRequestBehavior == JsonRequestBehavior.DenyGet 
      && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 
     { 
      throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet."); 
     } 

     HttpResponseBase response = context.HttpContext.Response; 

     response.ContentType = !string.IsNullOrEmpty(ContentType) 
            ? ContentType 
            : "application/json"; 

     if (ContentEncoding != null) 
      response.ContentEncoding = ContentEncoding; 

     if (Data != null) 
     { 
      var writer = new JsonTextWriter(response.Output) { Formatting = Formatting }; 

      var serializer = JsonSerializer.Create(SerializerSettings); 
      serializer.Serialize(writer, Data); 

      writer.Flush(); 
     } 
    } 

然後在您的控制器類重寫的Json方法:

protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding) 
    { 
     return new JsonNetResult 
     { 
      ContentType = contentType, 
      ContentEncoding = contentEncoding, 
      Data = data 
     }; 
    } 

    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior) 
    { 
     return new JsonNetResult 
     { 
      ContentType = contentType, 
      ContentEncoding = contentEncoding, 
      Data = data, 
      JsonRequestBehavior = behavior 
     }; 
    } 

而且使用這樣的:

public ActionResult GetObjectByNr(int id) 
{ 
    return Json(this._businessObject.SearchForObject(id), JsonRequestBehavior.AllowGet); 
} 
+0

但當客戶想要一個XML作爲迴應,這將無法正常工作? – dev01 2014-10-06 14:02:51

+0

這不起作用。即使當我包括NewtonSoft.JSON JsonResult不被識別 – dev01 2014-10-06 14:12:11

+0

那麼,Json當然不是XML。如果你需要XML,你可以使用sharpSerializer(http://www.sharpserializer.com)。 – 2014-10-06 14:12:18