从Web API

时间:2016-08-10 20:29:00

标签: c# json asp.net-mvc oracle asp.net-web-api

我们创建了一个Web API,用于查询Oracle数据库并以JSON格式返回结果。如果返回的数据非常大,则会抛出Out of Exception问题。因此在另一个question中建议问题是因为在将整个结果集序列化到HttpResponseMessage之前将其加载到内存中。

因此创建了以下类

[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 Oracle 连接的新手,我有点困在这里。非常感谢任何帮助

1 个答案:

答案 0 :(得分:1)

您必须明确打开连接。

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

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