2017-10-19 16 views
0

他のサービスを呼び出し、応答の配列を返すWeb APIを作成しようとしています。呼び出されたサービスは応答を返します。私は呼び出されたサービスから個々のアイテムを得ることができます。しかし、どのように項目の配列を構築し、私が作成しているAPIからの応答として返すか分からない。Web APIからの応答配列を返すC#

JSONは

{ 
"cr_response": { 
    "details": [{ 
     "name": "Req", 
     "fields": [{ 
       "value": "Prj0\r\nPrj1", 
       "name": "Project" 
      }, 
      { 
       "value": "October 13, 2017 14:18", 
       "name": "Submitted" 
      }, 
      { 
       "value": "John", 
       "name": "Rec Name" 
      } 
     ] 
    }], 
    "cr_metadata": {} 
} 
} 

のように見え、

以下
public class Field 
{ 
    public string value { get; set; } 
    public string name { get; set; } 
} 

public class Detail 
{ 
    public string name { get; set; } 
    public List<Field> fields { get; set; } 
} 

public class CrMetadata 
{ 
} 

public class CrResponse 
{ 
    public List<Detail> details { get; set; } 
    public CrMetadata cr_metadata { get; set; } 
} 

public class RootObject 
{ 
     public CrResponse cr_response { get; set; } 
} 

がサービスを呼び出し、

サービスからの応答を取得するためのコードであるようにPOCOクラスが見えるサービスから返さ
var response = await iLab_client.GetAsync(uri); 
var datafile = await response.Content.ReadAsStringAsync(); 
var returnDataObj = JsonConvert.DeserializeObject<DTO.RootObject>(datafile); 

foreach (var form in returnDataObj.cr_response.details) 
{ 
    name_response = form.name; 
    return Ok(name_response); 
} 

ここでは詳細から名前にアクセスできますが、その方法はわかりませんフィールドからすべての名前と値にアクセスし、配列で構築できますか? JSONレスポンスとして送信します。 私は

  foreach (var form in returnDataObj.cr_response.details) 
      { 
       var id_response = form.fields; 
       return Ok(id_response); 
      } 

ようにしようとしたが、それはあなたがあなたの配列を記入し、foreachループの外にそれを返す必要がウェブAPIから配列を返すに

<Error> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
The 'ObjectContent`1' type failed to serialize the response body for content 
type 'application/xml; charset=utf-8'. 
</ExceptionMessage> 

のSystem.InvalidOperationException

+0

は、私は、エラーメッセージは、特にコンテンツタイプ 'アプリケーション/ xml'に言及していることに気づきます。有効なXMLでは、単一のルートノードが存在する必要があります。返されるオブジェクトをコレクションにすることはできません。代わりにJSONを要求するようにクライアントを変更できる場合は、問題が修正される可能性があります。それ以外の場合は、配列を直接返すのではなく、その配列を持つオブジェクトをそのプロパティの1つとして返すこともできます。 – StriplingWarrior

+0

@StriplingWarrior HttpClientの代わりに変更を求めていますか? – xyz

+0

いいえ、あなたのコードは、Webサービス( 'ilab_client.GetAsync(...)')と*クライアント( 'return Ok(...);')で*消費されます。 Web APIエンドポイントを消費しているクライアントがHTTP要求を送信しています。 Web APIはリクエストを見て、レスポンスをJSONではなくXMLとしてシリアライズする必要があると考えています。これは、Webリクエストのヘッダー(またはヘッダーがないため)が原因である可能性があります。または、[Web APIアプリケーションの設定方法](https://stackoverflow.com/q/12629144/120955)が原因である可能性があります。またはこれらの2つの組み合わせ。 – StriplingWarrior

答えて

0

のようなエラーがスローされます。

var list = new List<string>(); 
foreach (...){ 
    var name = ... 
    list.Add(name); 
} 
return Ok(list.ToArray()); // or just return Ok(list); 

これはhoですPOCOからJSONをデシリアライズし、名前のリストを取得するW:

[TestMethod] 
public void TestJsonToPocoAndGetNames() 
{ 
    const string Json = @" 
     { 
     ""cr_response"": { 
      ""details"": [{ 
       ""name"": ""Req"", 
       ""fields"": [{ 
         ""value"": ""Prj0\r\nPrj1"", 
         ""name"": ""Project"" 
        }, 
        { 
         ""value"": ""October 13, 2017 14:18"", 
         ""name"": ""Submitted"" 
        }, 
        { 
         ""value"": ""John"", 
         ""name"": ""Rec Name"" 
        } 
       ] 
      }], 
      ""cr_metadata"": {} 
     } 
    } 
    "; 

    var settings = new JsonSerializerSettings 
    { 
     MetadataPropertyHandling = MetadataPropertyHandling.Ignore, 
     DateParseHandling = DateParseHandling.None, 
    }; 
    var response = JsonConvert.DeserializeObject<RootJsonObject>(Json, settings); 

    var names = new List<string>(); 
    foreach (var detail in response.CrResponse.Details) 
    { 
     names.Add(detail.Name); 

     foreach (var field in detail.Fields) 
     { 
      names.Add(field.Name); 
     } 
    } 

    Assert.AreEqual(
     "Req, Project, Submitted, Rec Name", 
     string.Join(", ", names.ToArray())); 
} 

POCOクラスを:

public class RootJsonObject 
{ 
    [JsonProperty("cr_response")] 
    public CrResponse CrResponse { get; set; } 
} 

public class CrResponse 
{ 
    [JsonProperty("cr_metadata")] 
    public CrMetadata CrMetadata { get; set; } 

    [JsonProperty("details")] 
    public Detail[] Details { get; set; } 
} 

public class CrMetadata 
{ 
} 

public class Detail 
{ 
    [JsonProperty("fields")] 
    public Field[] Fields { get; set; } 

    [JsonProperty("name")] 
    public string Name { get; set; } 
} 

public class Field 
{ 
    [JsonProperty("name")] 
    public string Name { get; set; } 

    [JsonProperty("value")] 
    public string Value { get; set; } 
} 
+0

私たちは詳細とフィールドの両方に名前を持っています。私はフィールドから名前と値を取得したい。 – xyz

+0

JSONデータにアクセスするには(POCOクラスにデシリアライズせずに)、これをチェックしてください。https://stackoverflow.com/questions/6620165/how-can-i-parse-json-with-c/17842600#17842600 –

+0

POCOは私がファイルと名前の下にアクセスできないのですか? – xyz