2017-02-09 51 views
0

我有一個C#應用程序,通過RESTful服務接收並返回信息。 我之前處理這些操作的方式是方法簡單地返回JSON字符串,然後這些字符串被包裝在XML中。C#RESTful服務 - HTTP 504 /連接重置

爲了防止這種情況,我改變了ResponseFormat以JSON和我現在回到DataContracts,而這一切從一個抽象類派生:

using System.Runtime.Serialization; 

/// <summary> 
/// Abstract class for defining a standard definition of a command return result. 
/// A command is not required to return a result, however it is recommended. 
/// A return result must implement the properties defined in this abstract class. 
/// A command may return an anonymous object instead of an instance of this abstract class. 
/// </summary> 
[DataContract(Namespace = "")] 
public abstract class ICommandResult { 
// Don't let the name disturb you, this used to be an interface. 

    /// <summary> 
    /// Gets or sets the message. 
    /// </summary> 

    [DataMember] 
    public abstract string Message { get; set; } 

} 

要應用DataContract屬性,我改變了上述接口的(現在)抽象類。

每個派生也應用DataContract和DataMember屬性。

當我調用服務的路由時,命令被執行,我可以在控制檯中看到輸出。但是,返回返回值時,我在控制檯中看到以下內容,並且Web瀏覽器保持空白。 Fiddler(在Windows上)向我顯示HTTP 504錯誤,而我的Mac顯示連接重置。

XmlException (Dropped Connection?): On JSON writer data type 'type' must be specified. Object string is 'object', server type string is '__type'. 

具體方法我使用來測試此,如下:

IRestService:

[OperationContract] 
[WebGet(UriTemplate = Routing.GetRoutesRoute, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] 
ICommandResult GetAllRoutes(); 

RestService(實施):

public ICommandResult GetAllRoutes() { 
    var results = ExecuteCommand("print-routes", "--no-output"); 
    // ExecuteCommand returns an ICommandResult object 
    return results; 
} 

實際命令實現(所以也可以通過控制檯調用):

ICommandResult Command_PrintRoutes(Command sender, params string[] args) { 
     var fields = typeof(Routing).GetFields(); 
     var fieldValues = new Dictionary<string, string>(); 
     var outputToConsole = true; 

     if (args.Count(x => x.ToLowerInvariant().Equals("--no-output")) == 1) 
      outputToConsole = false; 

     foreach (var field in fields) 
      fieldValues.Add(field.Name, (string)field.GetRawConstantValue()); 

     var output = JsonConvert.SerializeObject(fieldValues, Formatting.Indented); 

     if (outputToConsole) 
      WriteLine(output); 

     //return new CommandResult<Dictionary<string, string>>("Found following routes", fieldValues); 
     return new CommandResult<string>("Found following routes (JSON-encoded)", output); // Trying out different return types 
    } 

這是如何解決和防止的?

回答

0

我認爲這是一個序列化問題,與您的抽象DataContract。

看這個:KnownTypeAttribute - Serialization

我認爲你需要使用KnownType屬性在抽象基類上指定所有的子類。

通過這種方式,DataContractSerializer可以在序列化和反序列化對象時識別所有類型。

[DataContract] 
[KnownType(typeof(SubClassName1))] <- 
[KnownType(typeof(SubClassName2))] <- 
[KnownType(typeof(SubClassName3))] <- 
public abstract class ClassName 
{ 
     ... 
} 

對不起,我的英語。我希望我是有幫助的,

斯特凡諾

+0

不是一個非常可擴展的方式做事情在這種情況下。 我會試一試,我會盡快回復您。 – SimonC

+0

這似乎並沒有解決問題。 除非我必須定義可能或不可以用在返回值中的每一種類型。 它必須比這更容易。 – SimonC

+0

@Beatsleigher是的,如果你想在wcf dto中使用抽象類,你必須定義所有這些屬性。 我試圖在vs中重新創建你的情況,如果我調用返回抽象類的OperationContract,我可以調試它,但是當它返回時,響應不會到達。 (就像你看到的)。 如果我把屬性[KnownType(typeof(SubClassName1))]我可以看到wcf響應。 – SteeBono