Charles Sugden
asked on
Create a WebAPI using a generic return parameter
Excuse me in advance for any failings in the knowledge of WEBAPI and Generics.
My jobs do not always allow me to concentrate on 1 particular topic.
Premise:
Using 3 MVC controller calls, each calling a different WEBAPI, passing same parameters
My question is:
I would like to compress multiple controller calls calling multiple webapi methods into a single webapi/
I have attached similar code to what I am using.
ExpertsExchange.txt
My jobs do not always allow me to concentrate on 1 particular topic.
Premise:
Using 3 MVC controller calls, each calling a different WEBAPI, passing same parameters
My question is:
I would like to compress multiple controller calls calling multiple webapi methods into a single webapi/
I have attached similar code to what I am using.
ExpertsExchange.txt
ASKER
The stored procedure call will be different in each case and the resultset may or may not conform to a specific class hence my thought of using the generic but let me give it a try.
ASKER
OH yeah, I need a different class to map the dataset to the rows variable. Nice try though.
What about something like this?
[Route("api/alerts/GetA/{subject}")]
[Route("api/alerts/GetB/{subject}")]
[Route("api/alerts/GetC/{subject}")]
[HttpGet]
public IHttpActionResult Get(string subject)
{
switch (Request.RequestUri.Segments[3])
{
case "GetA/":
return GetAlerts<a>("dbo.[A]", subject);
case "GetB/":
return GetAlerts<b>("dbo.[B]", subject);
case "GetC/":
return GetAlerts<c>("dbo.[C]", subject);
default:
return default(IHttpActionResult);
}
}
private IHttpActionResult GetAlerts<T>(string spName, string subject)
{
string cnnstr = System.Configuration.ConfigurationManager.ConnectionStrings["DB"].ToString();
DataTable dt = new DataTable();
SqlParameter[] prms = new SqlParameter[1];
prms[0] = new SqlParameter("@FilterArg", SqlDbType.VarChar) { Value = subject };
DAL.DataAccess da = new DAL.DataAccess();
dt = da.GetData(cnnstr, spName, prms);
return ResponseMessage(Request.CreateResponse(HttpStatusCode.OK, DAL.Helpers.DataTableToList<T>(dt)));
}
ASKER
was hoping we wouldn't get further into this but the culprit is DataTableToList when used within a generic method.
I get the following error:
Error 5 'T' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'DAL.Helpers.DataTableToLi st<T>(Syst em.Data.Da taTable)' c:\users\h188429\documents \visual studio 2013\projects\alertsmonito ringapi\al ertsmonito ringapi\co ntrollers\ alertscont roller.cs 564 82 AlertsMonitoringAPI
I get the following error:
Error 5 'T' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'DAL.Helpers.DataTableToLi
[/ public static List<T> DataTableToList<T>(this DataTable table) where T : class, new()
{
try
{
T tempT = new T();
var tType = tempT.GetType();
List<T> list = new List<T>();
foreach (var row in table.Rows.Cast<DataRow>())
{
T obj = new T();
foreach (var prop in obj.GetType().GetProperties())
{
var propertyInfo = tType.GetProperty(prop.Name);
var rowValue = row[prop.Name];
var t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
try
{
object safeValue = (rowValue == null || DBNull.Value.Equals(rowValue)) ? null : Convert.ChangeType(rowValue, t);
propertyInfo.SetValue(obj, safeValue, null);
}
catch (Exception ex)
{
throw ex; //for lack of a better way
}
}
list.Add(obj);
}
return list;
}
catch
{
return null;
}
That should still work if you decorate the GetAlerts<T>() method I included in my previous reply with a corresponding where. That is:
private IHttpActionResult GetAlerts<T>(string spName, string subject) where T : class, new()
ASKER
The code looked good until I ran into another error:
Cannot call action method 'System.Web.Http.IHttpActi onResult GetData[T](System.String, System.String, System.String, System.String, System.String)' on controller
This link seems to say that I cannot do what I am looking to do
http://stackoverflow.com/questions/23367295/can-you-use-generic-methods-in-a-controller/23367384#23367384
Cannot call action method 'System.Web.Http.IHttpActi
This link seems to say that I cannot do what I am looking to do
http://stackoverflow.com/questions/23367295/can-you-use-generic-methods-in-a-controller/23367384#23367384
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yes that is what I had to do.
The code want too bad.
Thanks for the guidance
The code want too bad.
Thanks for the guidance
Open in new window