2016-08-10 74 views
0

我們創建了一個查詢Oracle數據庫並以JSON格式返回結果的Web API。如果返回的數據非常大,則會拋出異常問題。所以有人建議在其他question這個問題是因爲在將序列化到HttpResponseMessage之前將整個結果集加載到內存中。從Web API序列化結果集

所以創建以下類

[JsonConverter(typeof(OracleDataTableJsonResponseConverter))] 
public sealed class OracleDataTableJsonResponse 
{ 
    public string ConnectionString { get; private set; } 
    public string QueryString { get; private set; } 
    public OracleParameter[] Parameters { get; private set; } 

    public OracleDataTableJsonResponse(string connStr, string strQuery, OracleParameter[] prms) 
    { 
     this.ConnectionString = connStr; 
     this.QueryString = strQuery; 
     this.Parameters = prms; 
    } 
} 

class OracleDataTableJsonResponseConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(OracleDataTableJsonResponse); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException("OracleDataTableJsonResponse is only for writing JSON. To read, deserialize into a DataTable"); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var response = (OracleDataTableJsonResponse)value; 

     using (var dbconn = new OracleConnection(response.ConnectionString)) 
     { 
      using (var selectCommand = new OracleCommand(response.QueryString, dbconn)) 
      { 
       if (response.Parameters != null) 
        selectCommand.Parameters.AddRange(response.Parameters); 

       using (var reader = selectCommand.ExecuteReader()) 
       { 
        writer.WriteDataTable(reader, serializer); 
       } 
      } 
     } 
    } 
} 

public static class JsonExtensions 
{ 
    public static void WriteDataTable(this JsonWriter writer, IDataReader reader, JsonSerializer serializer) 
    { 
     if (writer == null || reader == null || serializer == null) 
      throw new ArgumentNullException(); 
     writer.WriteStartArray(); 

     while (reader.Read()) 
     { 
      writer.WriteStartObject(); 

      for (int i = 0; i < reader.FieldCount; i++) 
      { 
       writer.WritePropertyName(reader.GetName(i)); 
       serializer.Serialize(writer, reader[i]); 
      } 

      writer.WriteEndObject(); 
     } 

     writer.WriteEndArray(); 
    } 
} 

和API控制器是

public HttpResponseMessage Getdetails([FromUri] string[] id) 
{ 
    var prms = new List<OracleParameter>(); 
    var connStr = ConfigurationManager.ConnectionStrings["PDataConnection"].ConnectionString; 
    var inconditions = id.Distinct().ToArray(); 
    var strQuery = @"SELECT 
        STCD_PRIO_CATEGORY_DESCR.DESCR AS CATEGORY, 
        STCD_PRIO_CATEGORY_DESCR.SESSION_NUM AS SESSION_NUMBER, 
        Trunc(STCD_PRIO_CATEGORY_DESCR.START_DATE) AS SESSION_START_DATE, 
        STCD_PRIO_CATEGORY_DESCR.START_DATE AS SESSION_START_TIME , 
        Trunc(STCD_PRIO_CATEGORY_DESCR.END_DATE) AS SESSION_END_DATE, 
        FROM 
        STCD_PRIO_CATEGORY_DESCR, 
        WHERE 
        STCD_PRIO_CATEGORY_DESCR.STD_REF IN("; 
    var sb = new StringBuilder(strQuery); 
    for (int x = 0; x < inconditions.Length; x++) 
    { 
     sb.Append(":p" + x + ","); 
     var p = new OracleParameter(":p" + x, OracleDbType.NVarchar2); 
     p.Value = inconditions[x]; 
     prms.Add(p); 
    } 
    if (inconditions.Length>0) 
     sb.Length--; 
    strQuery = sb.Append(")").ToString(); 

    var returnObject = new { data = new OracleDataTableJsonResponse(connStr, strQuery, prms.ToArray()) }; 
    var response = Request.CreateResponse(HttpStatusCode.OK, returnObject, MediaTypeHeaderValue.Parse("application/json")); 
    ContentDispositionHeaderValue contentDisposition = null; 
    if (ContentDispositionHeaderValue.TryParse("inline; filename=PStudyData.json", out contentDisposition)) 
    { 
     response.Content.Headers.ContentDisposition = contentDisposition; 
    } 
    return response; 
} 

現在的問題是,當我調用API,它拋出了錯誤例外的例外是在class OracleDataTableJsonResponseConverter在聲明using(var reader = selectCommand.ExecuteReader())invalidOperationException Connection must be open for this operation

當我試圖調試我看到所有的連接字符串正在正確傳遞,但它在服務器版本類似下面拋出錯誤, enter image description here

可能是什麼問題,我是新來ASP.NET甲骨文連接,我有種陷在這裏。任何幫助非常感謝

+0

我建議你看一下微型ORM(如Dapper),它們可以解決連接狀態,參數和結果映射這些簡單的事情,所以你不需要手動處理。 – Husqvik

回答

1

你必須明確地打開連接。

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
{ 
    var response = (OracleDataTableJsonResponse)value; 

    using (var dbconn = new OracleConnection(response.ConnectionString)) 
    { 
     dbconn.Open(); 
     ... 
    } 
}