C# Web API Parameter Always Returns All Values Instead of One - c#

I am working on a Web API in C# and am getting my data from a SQL Database. The Get method returns all rows of (student) data, however even when I put a single student number in the GET call, it still returns all rows of data instead of a single row for the specified student. In my Roles Class I have;
public class Roles
{
List<Roles> studentRoles = new List<Roles>();
public string UserName { get; set; }
public string PersonName { get; set; }
public string Profile { get; set; }
public string Level { get; set; }
public int Year { get; set; }
public string Department { get; set; }
}
public class readRoles : Roles
{
public readRoles(DataRow dataRow)
{
UserName = (string)dataRow["UserName"];
PersonName = (string)dataRow["PersonName"];
Profile = (string)dataRow["Profile"];
Level = (string)dataRow["Level"];
Year = Convert.ToInt32(dataRow["Year"]);
Department = (dataRow["Department"] == DBNull.Value) ? "No Department" : dataRow["Department"].ToString();
}
public string UserName { get; set; }
public string PersonName { get; set; }
public string Profile { get; set; }
public string Level { get; set; }
public int Year { get; set; }
public string Department { get; set; }
}
In my Controller I have this;
List<Roles> studentRoles = new List<Roles>();
private SqlDataAdapter _adapter;
public IEnumerable<Roles> Get()
{
//Create link to database
string connString;
SqlConnection con;
connString = #"XXX";
DataTable _dt = new DataTable();
con = new SqlConnection(connString);
con.Open();
var sql = "some sql here";
SqlCommand CMD = new SqlCommand();
CMD.Connection = con;
CMD.CommandText = sql;
CMD.CommandType = System.Data.CommandType.Text;
SqlDataReader dr = CMD.ExecuteReader();
_adapter = new SqlDataAdapter
{
SelectCommand = new SqlCommand(sql, con)
};
_adapter.Fill(_dt);
List<Roles> roles = new List<Roles>(_dt.Rows.Count);
if (_dt.Rows.Count > 0)
{
foreach (DataRow studentrole in _dt.Rows)
{
roles.Add(new readRoles(studentrole));
}
}
return roles;
}
The above returns all the data as it should. To return a single row of data, I have the below Method but it still returns every single row instead of the row for the specified one when I do e.g. https://localhost:XXXXX/custom-roles-api/campusCustomRoles/12345;
[HttpGet]
public IHttpActionResult Get(string userName)
{
string connString;
SqlConnection con;
connString = #"XXX";
DataTable _dt = new DataTable();
con = new SqlConnection(connString);
con.Open();
var sql = "select distinct .... where student_reference = " + userName +;
SqlCommand CMD = new SqlCommand();
CMD.Connection = con;
CMD.CommandText = sql;
CMD.CommandType = System.Data.CommandType.Text;
SqlDataReader dr = CMD.ExecuteReader();
_adapter = new SqlDataAdapter
{
SelectCommand = new SqlCommand(sql, con)
};
_adapter.Fill(_dt);
List<Roles> roles = new List<Roles>(_dt.Rows.Count);
if (_dt.Rows.Count > 0)
{
foreach (DataRow studentrole in _dt.Rows)
{
roles.Add(new readRoles(studentrole));
}
}
var singlestu = roles.FirstOrDefault(e => e.UserName == userName);
return Ok(singlestu)
;
}
In the above example, I expect only data for student 12345 to be returned, but alas, all records are retrieved. In my WebConfig file, I have a custom Route like so;
public static void Register(HttpConfiguration config)
{
// Web API routes
// This is the original Route
//config.MapHttpAttributeRoutes();
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{Controller}/{id}",
// //routeTemplate: "api/{controller}/{action}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
// Custom Route
config.MapHttpAttributeRoutes();
// Define route
System.Web.Http.Routing.IHttpRoute rolesRoute = config.Routes.CreateRoute("custom-roles-api/{controller}/{id}",
new { id = RouteParameter.Optional }, null);
// Add route
config.Routes.Add("DefaultApi", rolesRoute);
}
Not sure where I have gone wrong and would be grateful for any pointers.
Many thanks in advance.
EDIT: As requested, please see below code when I used parameters;
[HttpGet]
public IHttpActionResult Get(string userName)
{
string connString;
SqlConnection con;
connString = #"XXXX";
DataTable _dt = new DataTable();
con = new SqlConnection(connString);
con.Open();
var sql = "select distinct .... where student_reference =#UserName " +
"and department ='LAW' " +;
SqlParameter param = new SqlParameter();
param.ParameterName = "#UserName";
param.Value = UserName;
SqlCommand CMD = new SqlCommand();
CMD.Connection = con;
CMD.CommandText = sql;
CMD.CommandType = System.Data.CommandType.Text;
SqlDataReader dr = CMD.ExecuteReader();
_adapter = new SqlDataAdapter
{
SelectCommand = new SqlCommand(sql, con)
};
_adapter.Fill(_dt);
List<Roles> roles = new List<Roles>(_dt.Rows.Count);
if (_dt.Rows.Count > 0)
{
foreach (DataRow studentrole in _dt.Rows)
{
roles.Add(new readRoles(studentrole));
}
}
var singlestu = roles.FirstOrDefault(e => e.UserName == userName);
return Ok(singlestu)
;
}

After much head-cracking, I go it to work by converting the UserName to type int in the Roles class and the source query.

Related

How to get many field on the Query of webservice

I am making a web service get data from sql server. I need to get many fields from the sql server, but I can only get one field, which is the Currancy Name
namespace WebApplication2
{
public class DataHelper
{
public static string GetCurrency(string currencyCode)
{
string currencyName = "";
SqlConnection con = new SqlConnection(#"Data Source=WEB3\SHAREPOINT;Initial Catalog=WSS_Search_WEB3;Integrated Security=True");
SqlCommand cmd = new SqlCommand("select PO_NUMBER,PO_STATUS from View_1 where PO_HEADER_ID ='" + currencyCode.ToUpper() + "'", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
currencyName = dr["PO_NUMBER"].ToString();
}
dr.Close();
con.Close();
return currencyName;
}
}
}
I need to get the PO_Number & PO Status from the Query
As I understand you need to return not only PO_NUMBER, but also PO_STATUS, and as I understand you want to return both values.
I suggest you make model that represent what you want to return.
So for that we make a model class call it for instance POModel:
public class POModel
{
public string currencyName { get; set; } // PO_Number
public string statusName { get; set; } // PO_Status
}
Than fetch the values from SQL as you did and return object in stead of string.
Here would you final code looks like, of course naming and all the stuff you can change the way if fits best:
public class DataHelper
{
public static POModel GetCurrency(string currencyCode)
{
//string currencyName = "";
var poModel = new POModel();
SqlConnection con = new SqlConnection(#"Data Source=WEB3\SHAREPOINT;Initial Catalog=WSS_Search_WEB3;Integrated Security=True");
SqlCommand cmd = new SqlCommand("select PO_NUMBER,PO_STATUS from View_1 where PO_HEADER_ID ='" + currencyCode.ToUpper() + "'", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
poModel.currencyName = dr["PO_NUMBER"].ToString();
poModel.statusName = dr["PO_STATUS"].ToString();
}
dr.Close();
con.Close();
//return currencyName;
return poModel;
}
}
public class POModel
{
public string currencyName { get; set; }
public string statusName { get; set; }
}
One option is to return an array that contains the two values. Notice string[]:
public static string[] GetCurrency(string currencyCode)
Similar to how you declared string currencyName = "";, instead make an array variable:
string[] poData = new string[2];
Since this looks like it should return a single row, I would not loop. Just do a Read():
dr.Read();
poData[0] = dr["PO_NUMBER"].ToString(); //poData[] will have to be declared in your method
poData[1] = dr["PO_STATUS"].ToString();
....
return poData;

Not all paths return a value error c#

I am getting error Not all paths return a value. Its a syntax error how to correct it. here is my code. I am writing this code in class.
public class Employees
{
public String emp_id { get; set; }
public String emp_name { get; set; }
public String u_name { get; set; }
public String pass { get; set; }
public String mail { get; set; }
public String address { get; set; }
public String city { get; set; }
public String dob { get; set; }
public String cnic { get; set; }
public String designation { get; set; }
public String ph_no { get; set; }
}
public class #object
{
public static List<Employees> GetAllEmployees()
{
List<Employee> listemp = new List<Employee>();
string cs = ConfigurationManager.ConnectionStrings[#"Data Source = localhost; Initial Catalog=fms; User=root; Pooling=false; Integrated Security = false"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(cs))
{
MySqlCommand cmd = new MySqlCommand("Select * from emp", con);
con.Open();
MySqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Employees em = new Employees();
em.emp_id = dr[0].ToString();
em.emp_name = dr[1].ToString();
em.u_name = dr[2].ToString();
em.pass = dr[3].ToString();
em.mail = dr[4].ToString();
em.address = dr[5].ToString();
em.city = dr[6].ToString();
em.dob = dr[7].ToString();
em.cnic = dr[8].ToString();
em.designation = dr[9].ToString();
em.ph_no = dr[10].ToString();
}
listemp.Add(em);
}
}
}
I attached a pic where I am getting this error.
You should return the List listemp . Also consider moving listemp.Add(em) inside while loop, otherwise you wont get a list
public static List<Employees> GetAllEmployees()
{
List<Employee> listemp = new List<Employee>();
string cs = ConfigurationManager.ConnectionStrings[#"Data Source = localhost; Initial Catalog=fms; User=root; Pooling=false; Integrated Security = false"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(cs))
{
MySqlCommand cmd = new MySqlCommand("Select * from emp", con);
con.Open();
MySqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Employees em = new Employees();
em.emp_id = dr[0].ToString();
em.emp_name = dr[1].ToString();
em.u_name = dr[2].ToString();
em.pass = dr[3].ToString();
em.mail = dr[4].ToString();
em.address = dr[5].ToString();
em.city = dr[6].ToString();
em.dob = dr[7].ToString();
em.cnic = dr[8].ToString();
em.designation = dr[9].ToString();
em.ph_no = dr[10].ToString();
listemp.Add(em);
}
}
return listemp;
}
You have two problems: GetAllEmployees() should return List<Employees> and you add em to the list outside the while scope
public static List<Employees> GetAllEmployees()
{
List<Employee> listemp = new List<Employee>();
string cs = ConfigurationManager.ConnectionStrings[#"Data Source = localhost; Initial Catalog=fms; User=root; Pooling=false; Integrated Security = false"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(cs))
{
MySqlCommand cmd = new MySqlCommand("Select * from emp", con);
con.Open();
MySqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Employees em = new Employees();
em.emp_id = dr[0].ToString();
em.emp_name = dr[1].ToString();
em.u_name = dr[2].ToString();
em.pass = dr[3].ToString();
em.mail = dr[4].ToString();
em.address = dr[5].ToString();
em.city = dr[6].ToString();
em.dob = dr[7].ToString();
em.cnic = dr[8].ToString();
em.designation = dr[9].ToString();
em.ph_no = dr[10].ToString();
listemp.Add(em);
}
}
return listemp;
}
You need to return the listemp at the end of the method GetAllEmployee()
return listemp
One more thing I noticed, the listemp.Add(em) should be inside the while loop. Since your select statement will yield more than one employee. You need to add the employee object each time to the list.

Is there a way i can reuse this code in C#

Is there a way i can reuse this codes in executing SQL transaction, i want to make it a method so i can put parameters to execute other stored procedures,
can you guys help me to design a good coding structure?
try {
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand("InsertUser2Sp", con) {
CommandType = CommandType.StoredProcedure
}) {
cmd.Parameters.AddWithValue("#UserID", useridStr);
cmd.Parameters.AddWithValue("#Firstname", firstnStr);
cmd.Parameters.AddWithValue("#Middlename", middleNstr);
cmd.Parameters.AddWithValue("#Lastname", lastnStr);
cmd.Parameters.AddWithValue("#UserAge", ageInt);
cmd.Parameters.AddWithValue("#HomeAddress", homeaddStr);
con.Open();
cmd.ExecuteNonQuery();
}
}
} catch (Exception ex) {
MessageBox.Show("Could not connect to database. Check settings. " + ex.Message, "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(ex.Message);
}
}
I will share a generic method here . All you need to do is to build an object with the same property names (including cases) same with the parameters in your SP.
protected internal string GetSingleValue_String(String spname, Object entity)
{
Object res = new Object();
String conString = String.Empty;
using (SqlConnection con = new SqlConnection(ConnectionString))
{
con.Open();
SqlCommand cmd = new SqlCommand(spname, con);
cmd.CommandType = CommandType.StoredProcedure;
if (entity != null)
{
SqlCommandBuilder.DeriveParameters(cmd);
PropertyInfo entitymember = default(PropertyInfo);
foreach (SqlParameter _param in cmd.Parameters)
{
if (_param.Direction == ParameterDirection.Input)
{
entitymember = entity.GetType().GetProperty(_param.ParameterName.Replace("#", ""));
var entityValue = entitymember.GetValue(entity, null);
String _paramvalue = entityValue != null ? entityValue.ToString() : null;
_param.Value = (string.IsNullOrEmpty(_paramvalue) || _paramvalue == string.Empty ? null : _paramvalue);
}
}
}
res = cmd.ExecuteScalar();
cmd.Connection.Close();
entity = null;
cmd = null;
if(res==null)
res = "";
else if (String.IsNullOrEmpty(res.ToString()))
res = "";
return res.ToString();
}
}
So in your example, create a new class that have the same definition as your SP parameters.
class NewClass()
{
public string UserID { get; set; }
public string Firstname { get; set; }
public string Middlename { get; set; }
public string Lastname { get; set; }
public string UserAge { get; set; }
public string HomeAddress { get; set; }
}
And will call the method like this.
var newClass = new NewClass
{
UserID = "UserId",
Firstname = "Firstname",
Middlename = "Middlename",
Lastname = "Lastname",
UserAge = "UserAge",
HomeAddress = "HomeAddress"
}
var res = GetSingleValue_String("InsertUser2Sp", newClass);
Don'd mind the return type.

Insert null datetime from sql table into datagridview silverlight

I have problem with null values, I want to insert from sql table nulls ( from datetime column) into datagridview, and datagridview return error.
Communication Exception was unhandled by user code
Code:
public class Pismo
{
public int Id { get; set; }
public string PW { get; set; }
public DateTime? Data_Wysylki { get; set; }
}
public ObservableCollection<Pismo> ReadPisma(int id_pismo)
{
ObservableCollection<Pismo> result = new ObservableCollection<Pismo>();
string nwConn = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
SqlDataReader dr;
SqlConnection conn = new SqlConnection(nwConn);
try
{
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
cmd.CommandText = "INSERT";
cmd.Parameters.AddWithValue("#id", id);
conn.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
Pismo wiersz = new Pismo();
wi.Id = dr.GetInt32(0);
wi.PW = dr.GetString(1);
wi.Data_Wysylki = dr.GetDateTime(2);
result.Add(wi);
}
dr.Close();
return result;
}
catch (SqlException e)
{
Pismo wi = new Pismo();
wi.Id = e.Message;
result.Add(wi);
return result;
}
finally
{
conn.Close();
};
}
<sdk:DataGridTextColumn Header="Data WysyƂki" Binding="{Binding Data_Wysylki, StringFormat='yyyy/MM/dd'}"/>
I try to add this below
if (wi.Data_Wysylki.HasValue) wi.Data_Wysylki = dr.GetDateTime(16);
after that error didnt show but in datagridview all column (even with some dates) was null

I get the error 'not all code paths return a value' in a try catch block

Please see the code below, it is MVC, I'm trying to create a IEnumerable view. The error I'm getting is'not all code path return a value' how can I correct the error?
public class CustomerSummary
{
public string ContactName { get; set; } // Customer table
public string City { get; set; } // Customer table
public string PostalCode { get; set; } // Order table
public string ShipName { get; set; } // Order table
public string ProductName { get; set; } // Product table
public bool Discontinued { get; set; } // product table
}
Controller
public class CustomerSummaryController : Controller
{
//
// GET: /CustomerSummary/
private CustomerSummaries _customerSummaries = new CustomerSummaries();
public ViewResult Index()
{
IEnumerable<CustomerSummary> summaries = _customerSummaries.GetAll();
return View(summaries);
}
}
Data layer
public IEnumerable<CustomerSummaries> GetAll(/* to do put connection string here */)
{
try
{
SqlCommand cmd = new SqlCommand("GetAll", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
SqlDataReader sdr;
conn.Open();
sdr = cmd.ExecuteReader();
while (sdr.Read())
{
if (sdr.IsDBNull(sdr.GetOrdinal("ContactName")) != true)
{
sdr["ContactName"].ToString();
}
}
}
catch (Exception)
{
throw;
}
finally
{
conn.Close();
}
}
I'm making a fair amount of assumptions here, but I think this is what you want:
public IEnumerable<CustomerSummary> GetAll(SqlConnection conn)
{
var result = new List<CustomerSummary>();
try
{
SqlCommand cmd = new SqlCommand("GetAll", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
SqlDataReader sdr;
conn.Open();
sdr = cmd.ExecuteReader();
while (sdr.Read())
{
var cs = new CustomerSummary();
if (sdr.IsDBNull(sdr.GetOrdinal("ContactName")) != true)
{
cs.ContactName = sdr["ContactName"].ToString();
}
// repeat the above if-block to add more info if needed...
// add the CustomerSummary to the result
result.Add(cs);
}
}
catch (Exception)
{
throw;
}
finally
{
conn.Close();
}
return result;
}

Categories