Introduction
We’ll walk through a real-time ASP.NET Web API controller for handling market data and charting features. This API plays a crucial role in processing financial data, validating client headers, and returning structured JSON responses.
We'll maintain the original code and explain its structure, dependencies, and flow, making it easier for developers to extend or debug.
Key Libraries & Namespaces Used
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using AppBlock;
using FormatFunctions;
AppBlock
- This is most likely a custom wrapper around ADO.NET/SQL helper functions.
- Frequently used for SqlHelper.ExecuteDataset, parameter management, etc.
- Improves code reusability and readability by abstracting raw ADO.NET logic.
Why AppBlock?
Reduces boilerplate for SqlConnection, SqlCommand, and SqlDataAdapter. This abstraction simplifies DB calls, especially in large projects.
FormatFunctions (C_Format.M_FormatDate())
- Appears to be a custom formatting utility for converting DateTime to string formats (yyyy-MM-dd).
- Helpful when working with stored procedures or charting APIs expecting ISO-standard date strings.
Newtonsoft.Json & JArray
Popular .NET JSON serializer/deserializer library.
Used here to,
- Convert DataTable to JSON (JsonConvert.SerializeObject)
- Deserialize JSON back to C# object arrays (JsonConvert.DeserializeObject<>())
- Serialize error/status messages
Why Newtonsoft.Json?
Handles complex JSON scenarios easily, like camelCase, nested objects, and ignores nulls. More flexible than System.Text.Json in legacy or enterprise apps.
Overview of API Endpoints
public class ABCAPIController : ApiController
{
[HttpPost]
public resultbinddata Marketshare_price([FromBody] binddata passdata)
{
#region commented
resultbinddata refe = new resultbinddata();
string storeresult = "";
string Useridhead = "", Usernamehead = "";
DataTable dt = new DataTable();
string[] d = passdata.isin;
dt.Columns.Add("isin");
for (int i = 0; i < d.Length; i++)
{
DataRow dr = dt.NewRow();
dr["isin"] = d[i].ToString();
dt.Rows.Add(dr);
}
try
{
System.Net.Http.Headers.HttpRequestHeaders headers = this.Request.Headers;
if (headers.Contains("clientname"))
{
Usernamehead = headers.GetValues("clientname").First();
}
if (headers.Contains("clientkey"))
{
Useridhead = headers.GetValues("clientkey").First();
}
string sql = "SELECT * FROM ABCApiheader WHERE clientname='" + Usernamehead + "' AND clientkey='" + Useridhead + "'";
DataSet dshead = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["common165"].ToString(), CommandType.Text, sql);
if (dshead != null && dshead.Tables[0].Rows.Count > 0)
{
#region
if (dt != null && dt.Rows.Count > 0)
{
DataSet ds = new DataSet();
ds.Tables.Add(dt);
string convetXml = ds.GetXml().Replace("\r\n", "").Replace(" ", "");
SqlParameter[] param = { new SqlParameter("@XMLisin", convetXml) };
DataSet ds1 = SqlHelper.ExecuteDataset(
ConfigurationManager.ConnectionStrings["common165"].ToString(),
CommandType.StoredProcedure,
"pricedetailsBSENSE_arrayxml",
param
);
DataView dt4 = ds1.Tables[0].DefaultView;
storeresult = DataTableToJSONWithJSONNet(dt4.ToTable(true,
"Isin", "bseprice", "Nseprice", "Nsepercentage", "Bsepercentage", "Bsechange", "Nsechange",
"B52High", "N52High", "B52LOW", "N52LOW", "BSEMCAP", "NSEMCAP", "BSEMCAP_USD", "NSEMCAP_USD", "Company_Name"));
isindata[] obj = JsonConvert.DeserializeObject<isindata[]>(storeresult);
if (storeresult != "[]")
{
refe.Status = true;
refe.Message = "Sucessfully Updated";
refe.Data = obj;
return refe;
}
else
{
refe.Status = false;
refe.Message = "No Data Available..!!";
refe.Data = null;
return refe;
}
}
else
{
storeresult = JsonConvert.SerializeObject("ISIN Is Missing..!!");
refe.Status = false;
refe.Message = storeresult;
refe.Data = null;
return refe;
}
#endregion
}
else
{
storeresult = JsonConvert.SerializeObject("Invalid clientname Name or clientkey");
refe.Status = false;
refe.Message = storeresult;
refe.Data = null;
return refe;
}
}
catch (Exception ex)
{
Console.WriteLine("Please try again later: " + ex);
storeresult = JsonConvert.SerializeObject(" No Data Available..!!");
refe.Status = false;
refe.Message = storeresult;
refe.Data = null;
return refe;
}
#endregion
}
public string DataTableToJSONWithJSONNet(DataTable table)
{
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(table);
return JSONString;
}
public class binddata
{
public string[] isin { get; set; }
}
public class resultbinddata
{
public bool Status { get; set; }
public string Message { get; set; }
public isindata[] Data { get; set; }
}
public class isindata
{
public string Isin { get; set; }
public string Bseprice { get; set; }
public string Bsepercentage { get; set; }
public string Bsechange { get; set; }
public string B52HIGH { get; set; }
public string B52LOW { get; set; }
public string BSEMCAP { get; set; }
public string BSEMCAP_USD { get; set; }
public string Company_Name { get; set; }
}
}
1. Marketshare_price ([HttpPost])
public resultbinddata Marketshare_price([FromBody] binddata passdata).
Responsibilities
- Accepts an ISIN array from the body.
- Returns dummy success message (live logic is commented).
- Handles header validation (clientname, clientkey).
- Retrieves pricing data via the pricedetailsBSENSE_arrayxml stored procedure (commented).
- Converts DataTable to JSON using DataTableToJSONWithJSONNet().
Sample JSON Request: /Marketshare_price.
{
"isin": [
"INE123A01016",
"INE456B01024",
"INE456B01027"
]
}
Sample JSON Response: /Marketshare_price.
{
"Status": true,
"Message": "Sucessfully Updated",
"Data": [
{
"Isin": "INE123A01016",
"Bseprice": "452.65",
"Bsepercentage": "1.25",
"Bsechange": "5.60",
"B52HIGH": "480.00",
"B52LOW": "390.00",
"BSEMCAP": "15200000000",
"BSEMCAP_USD": "180000000",
"Company_Name": "ABC Industries Ltd"
},
{
"Isin": "INE456B01024",
"Bseprice": "312.40",
"Bsepercentage": "-0.75",
"Bsechange": "-2.35",
"B52HIGH": "340.00",
"B52LOW": "280.00",
"BSEMCAP": "9800000000",
"BSEMCAP_USD": "116000000",
"Company_Name": "XYZ Technologies Pvt Ltd"
}
]
}
If no data is found.
{
"Status": false,
"Message": "No Data Available..!!",
"Data": null
}
If the ISIN input is missing or empty.
{
"Status": false,
"Message": "No Data Available..!!",
"Data": null
}
2. Marketshare_chart
public chartresultbinddata Marketshare_chart([FromBody] chartRequest chartpassdata)
{
#region 2nd
chartresultbinddata refe = new chartresultbinddata();
string storeresult = string.Empty;
string Useridhead = "", Usernamehead = "";
DataTable dt = new DataTable();
string[] isinArray = chartpassdata.isin.Where(c => !string.IsNullOrWhiteSpace(c)).ToArray();
int isincount = isinArray.Length;
string isinString = string.Join("','", isinArray);
try
{
var headers = this.Request.Headers;
if (headers.Contains("clientname"))
Usernamehead = headers.GetValues("clientname").First();
if (headers.Contains("clientkey"))
Useridhead = headers.GetValues("clientkey").First();
string sql = $"select * from ABCApiheader where clientname='{Usernamehead}' and clientkey='{Useridhead}'";
DataSet dshead = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["common165"].ToString(), CommandType.Text, sql);
if (dshead != null && dshead.Tables[0].Rows.Count > 0)
{
if (!string.IsNullOrEmpty(chartpassdata.period) && isincount > 0)
{
string SQL = $"Select co_code from aliasmas where isin in ('{isinString}')";
DataSet ds = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["ClineOle"].ToString(), CommandType.Text, SQL);
if (ds.Tables[0].Rows.Count > 0)
{
string chartco_code = ds.GetXml().Replace("\r\n", "");
string perioddate = null;
string datef = chartpassdata.period;
if (datef.ToLower().Contains("day"))
{
SqlParameter[] param1 = {
new SqlParameter("@chartco_codeXML", chartco_code),
SqlHelper.MakeParam("@Excg", chartpassdata.exchange)
};
DataSet ds2 = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["Klsehist"].ToString(), CommandType.StoredProcedure, "cm_intradaystkprice_array", param1);
maraketchartdata[] objArr = new maraketchartdata[isinArray.Length];
for (int i = 0; i < isinArray.Length; i++)
{
maraketchartdata obje = new maraketchartdata { isin = isinArray[i] };
DataTable filtertbl = ds2.Tables[0].Select($"isin='{obje.isin}'").CopyToDataTable();
obje.isinData = filtertbl.Rows.Count > 0 ? JsonConvert.DeserializeObject<dataarray[]>(DataTableToJSONWithJSONNet2(filtertbl)) : null;
objArr[i] = obje;
}
return new chartresultbinddata { Status = true, Message = "Sucessfully Updated", Data = objArr };
}
else
{
if (datef.ToLower().Contains("week"))
perioddate = C_Format.M_FormatDate(DateTime.Now.AddDays(-(7 * Convert.ToInt32(datef.ToLower().Replace("week", "")))).ToShortDateString(), "yyyy-MM-dd");
if (datef.ToLower().Contains("month"))
perioddate = C_Format.M_FormatDate(DateTime.Now.AddMonths(-Convert.ToInt32(datef.ToLower().Replace("month", ""))).ToShortDateString(), "yyyy-MM-dd");
if (datef.ToLower().Contains("year"))
perioddate = C_Format.M_FormatDate(DateTime.Now.AddYears(-Convert.ToInt32(datef.ToLower().Replace("year", ""))).ToShortDateString(), "yyyy-MM-dd");
SqlParameter[] param = {
new SqlParameter("@chartco_codeXML", chartco_code),
SqlHelper.MakeParam("@exchg", chartpassdata.exchange),
new SqlParameter("@EndDate", perioddate)
};
DataSet ds1 = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings["common165"].ToString(), CommandType.StoredProcedure, "Marketshare_charts_array", param);
maraketchartdata[] objArr = new maraketchartdata[isinArray.Length];
for (int i = 0; i < isinArray.Length; i++)
{
maraketchartdata obje = new maraketchartdata { isin = isinArray[i] };
DataTable filtertbl = ds1.Tables[0].Select($"isin='{obje.isin}'").CopyToDataTable();
obje.isinData = filtertbl.Rows.Count > 0 ? JsonConvert.DeserializeObject<dataarray[]>(DataTableToJSONWithJSONNet2(filtertbl)) : null;
objArr[i] = obje;
}
return new chartresultbinddata
{
Status = storeresult != "[]",
Message = storeresult != "[]" ? "Sucessfully Updated" : "No Data Available..!!",
Data = storeresult != "[]" ? objArr : null
};
}
}
else
return new chartresultbinddata { Status = false, Message = "Invalid ISIN ..!!", Data = null };
}
else
return new chartresultbinddata { Status = false, Message = "ISIN or Period Is Missing..!!", Data = null };
}
else
return new chartresultbinddata { Status = false, Message = "Invalid clientname Name or clientkey", Data = null };
}
catch (Exception ex)
{
Console.WriteLine("Please try again later: " + ex);
return new chartresultbinddata { Status = false, Message = " No Data Available..!!", Data = null };
}
#endregion
}
public string DataTableToJSONWithJSONNet2(DataTable table)
{
table.Columns.Remove("isin");
return JsonConvert.SerializeObject(table);
}
public class chartRequest
{
public List<string> isin { get; set; }
public string period { get; set; }
public string exchange { get; set; }
}
public class chartresultbinddata
{
public bool Status { get; set; }
public string Message { get; set; }
public maraketchartdata[] Data { get; set; }
}
public class maraketchartdata
{
public string isin { get; set; }
public dataarray[] isinData { get; set; }
}
public class dataarray
{
public string ClosePrice { get; set; }
public string Date { get; set; }
}
Sample JSON Request
Marketshare_chart
{
"isin": [
"INE123A01016",
"INE456B01024"
],
"period": "3month",
"exchange": "BSE"
}
Sample Response
{
"isin": [
"INE123A01016",
"INE456B01024"
],
"period": "3month",
"exchange": "BSE"
}
{
"isin": [
"INE123A01016",
"INE456B01024"
],
"period": "3month",
"exchange": "BSE"
}
Responsibilities
- Accepts ISIN list, exchange, and period.
- Supports day, week, month, and year inputs.
- Queries multiple databases based on a period.
- Formats XML to pass as a parameter (chartco_codeXML) to stored procedures like cm_intradaystkprice_array or Marketshare_charts_array.
- Converts result set to object model (maraketchartdata[]) for response.
Highlights
- Performs row filtering (DataView.RowFilter) to return per-ISIN data.
- Supports multiple ISINs in a single request — dynamic, scalable, and cleanly filtered.
- Robust handling for missing/invalid inputs.
Utility Methods
DataTableToJSONWithJSONNet()
public string DataTableToJSONWithJSONNet(DataTable table)
{
// Method implementation goes here
}
- Converts the entire DataTable into a JSON string.
- Alternative versions (WithJSONNet1, WithJSONNet2) remove specific columns like isin or Volume before serialization.
Header Validation Strategy
if (headers.Contains("clientname"))
{
// ...
}
if (headers.Contains("clientkey"))
{
// ...
}
- The API checks for required headers.
- Validates against the DB table ABCApiheader.
- Prevents unauthorized API access basic but effective security layer.
Example Configuration
<connectionStrings>
<add name="common165"
connectionString="Data Source=SoftSQL;Initial Catalog=CommonDb;Connect TimeOut=60;Max Pool Size=10000;User ID=sa;Password=capmark@09"
providerName="System.Data.SqlClient" />
<add name="clientdb"
connectionString="Data Source=SoftSQL;Initial Catalog=ClineOle;Connect TimeOut=60;Max Pool Size=10000;User ID=sa;Password=capmark@09"
providerName="System.Data.SqlClient" />
<add name="hrclients"
connectionString="Data Source=SoftSQL;Initial Catalog=Klsehist;Connect TimeOut=60;Max Pool Size=10000;User ID=sa;Password=capmark@09"
providerName="System.Data.SqlClient" />
</connectionStrings>