I am having trouble with my web service in ASP.NET - sql

I have written a webservice to access my SQL database.
[WebMethod]
public void getRoomByBuildingID(int buildingID)
{
string cs = ConfigurationManager.ConnectionStrings["vetDatabase_Wizard"].ConnectionString;
List<Room> rooms = new List<Room>();
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand("spGetRoomsByBuildingID", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter()
{
ParameterName = "#buildingID",
Value = buildingID
};
cmd.Parameters.Add(param);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Room room = new Room();
room.ID = Convert.ToInt32(rdr["ID"]);
room.Name = rdr["Room"].ToString();
room.buildingID = Convert.ToInt32(rdr["Building"]);
rooms.Add(room);
}
}
JavaScriptSerializer js = new JavaScriptSerializer();
//Serialize list object into a JSON array and write in into the response stream
Context.Response.Write(js.Serialize(rooms));
}
I keep getting an indexOutOfRangeException at
room.building = Convert.ToInt32(rdr["Building"]);
I've been looking at my sql table, and the column names and types are correct (i.e. ID, Room, Building). I am totally clueless at this point and would greatly appreciate the community's feedback. Thank you!
EDIT:
ALTER PROCEDURE spGetRoomsByBuildingID
#buildingID int
AS
BEGIN
SELECT ID, Room, Building FROM tblRooms
WHERE Building = #buildingID
END
EXEC spGetRoomsByBuildingID

Related

ASP.NET 5 - DataSet, DataTable and friends

I'm creating a new webservice in ASP.NET 5 using the new .NET Core library, so far I've only hit an issue with using DataSet and DataTable.
According to this site they are not included at this moment in time, which is fine, but I don't know what alternatives I have at this time, so I'm just looking for some guidance.
I have the following code:
public string Get(string p_sUserId, string p_sUserPassword, int p_iCustId)
{
Select qrySelect = new Select();
using (SqlConnection conn = new SqlConnection(Startup.ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(qrySelect.getData(), conn))
{
cmd.Parameters.AddWithValue("#Id", sTestId);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
using (DataSet ds = new DataSet())
{
// foo
// bar
}
}
}
}
return "value";
}
How should I handle the data that is being return from the query? I need to build and return a string using the above data fetched from the query. Any help and guidance would be appreciated.
I believe SqlDataReader should work.
string sql = "SELECT * FROM Table";
using (SqlConnection con = new SqlConnection(Startup.ConnectionString)) {
con.Open();
using (SqlCommand command = new SqlCommand(sql, con)) {
using (IDataReader dr = command.ExecuteReader()) {
while (dr.Read()) {
//process data
}
}
}
}
DataTable and SqlDBAdapter are now supported using .NET Standard 2.0. Upgrade to VS2017 Preview, add System.Data.Common and System.Data.SqlClient nugets, and the code below should work. More detail at the blog post here -> https://blogs.msdn.microsoft.com/devfish/2017/05/15/exploring-datatable-and-sqldbadapter-in-asp-net-core-2-0/ . GitHub repo here -> https://github.com/jhealy/aspdotnetcore/tree/master/SqlClientPlay20 .
public static DataTable ExecuteDataTableSqlDA(SqlConnection conn, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
{
System.Data.DataTable dt = new DataTable();
System.Data.SqlClient.SqlDataAdapter da = new SqlDataAdapter(cmdText, conn);
da.Fill(dt);
return dt;
}

Cannot insert numeric value into my SQL table

I currently have 2 tables in my database, 1 with an autonumeric value called ZoekcriteriaID which is the primary key off the table Zoekcriteria.
I want to add the primary key (ZoekcriteriaID) to my other table called Resultaten as a forgeign key but I keep getting the same error.
It seems like cmd1.Parameters.AddWithValue("#ZoekcriteriaID",Convert.ToInt32(sqlZoekcriteriaID)); keeps trying to add the entire query as a numeric value and I can't seem to figure out why.
Could anyone help me?
namespace Proftaak
{
class Mysearch
{
public string zoekterm = "";
int resultaat = 1;
public string Zoekterm
{
get
{
return zoekterm;
}
set
{
zoekterm = value;
}
}
public void InsertZoekcriteria()
{
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\martijn\Dropbox\Proftaak Periode 2 Identity\Database11.accdb;
Persist Security Info=False;";
connection.Open();
string sqlstring = "INSERT INTO Zoekcriteria (ZoekCriteria) values ('" + Zoekterm + "')";
OleDbCommand cmd = new OleDbCommand(sqlstring, connection);
cmd.ExecuteNonQuery();
connection.Close();
}
public void searchding()
{
const string apiKey = "AIzaSyDIm9ZOWD8Zd-2tHy5r3c0R-_XjdEFaXGE";
const string searchEngineId = "003470263288780838160:ty47piyybua";
string query = zoekterm;
CustomsearchService customSearchService = new CustomsearchService(new Google.Apis.Services.BaseClientService.Initializer() { ApiKey = apiKey });
Google.Apis.Customsearch.v1.CseResource.ListRequest listRequest = customSearchService.Cse.List(query);
listRequest.Cx = searchEngineId;
Search search = listRequest.Execute();
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\martijn\Dropbox\Proftaak Periode 2 Identity\Database11.accdb;
Persist Security Info=False;";
connection.Open();
string sqlZoekcriteriaID = "SELECT ZoekcriteriaID from Zoekcriteria where Zoekcriteria='" + query + "'";
OleDbCommand cmdZoekcriteria = new OleDbCommand(sqlZoekcriteriaID, connection);
cmdZoekcriteria.ExecuteNonQuery();
foreach (var item in search.Items)
{
string sqlstring1 = #"INSERT INTO Resultaat (ResultatenID,ZoekcriteriaID, Titel, Webadress) VALUES (#ResultatenID,#ZoekcriteriaID, #Titel, #Webadress)";
OleDbCommand cmd1 = new OleDbCommand(sqlstring1, connection);
cmd1.Parameters.AddWithValue("#ResultatenID", resultaat);
cmd1.Parameters.AddWithValue("#ZoekcriteriaID",Convert.ToInt32(sqlZoekcriteriaID));
cmd1.Parameters.AddWithValue("#Titel", item.Title);
cmd1.Parameters.AddWithValue("#Webadress", item.Link);
// string sqlstring2= "INSERT INTO Resultaat(Titel) values ('"+item.Title+"')";
// OleDbCommand cmd2 = new OleDbCommand(sqlstring2, connection);
resultaat++;
cmd1.ExecuteNonQuery();
}
connection.Close();
That's because it does:
string sqlZoekcriteriaID = "SELECT ZoekcriteriaID from Zoekcriteria where Zoekcriteria='" + query + "'";
cmd1.Parameters.AddWithValue("#ZoekcriteriaID",Convert.ToInt32(sqlZoekcriteriaID));
What you want is use the result of the query. What you should do is described in the answer to this question.
You should also rethink the naming of your variables; queryis not a query, for example, just a search condition.
Before close the connection, recover the identity number, like this:
OleDbCommand cmd = new OleDbCommand(sqlstring, connection);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT ##IDENTITY";
integer ZoekcriteriaID = cmd.ExecuteScalar()
connection.Close();
Than you can use the ZoekcriteriaID on the other insert.
Refer to this link

WCF SqlDataReader always returns last row times number of all rows

Here is my service code:
public List<Person> GetPersons()
{
string connstr = "Data Source=XXXXXX-PC;Initial Catalog=Database;Integrated Security=True";
using (SqlConnection con = new SqlConnection(connstr))
{
SqlCommand cmd = new SqlCommand("GetPersons", con);
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
SqlDataReader data = cmd.ExecuteReader();
List<Person> persons = new List<Person>();
Person one = new Person();
if (data.HasRows)
{
while(data.Read())
{
one.id = data.GetInt32(data.GetOrdinal("ID"));
one.name = data.GetString(data.GetOrdinal("Name"));
one.surname = data.GetString(data.GetOrdinal("Surname"));
one.fathername = data.GetString(data.GetOrdinal("FatherName"));
persons.Add(one);
}
data.Close();
}
return persons;
}
}
And here is the stored procedure in SQL Server:
SELECT
tbtp.ID, tbo.Name, tbo.Surname, ISNULL(tbo.FatherName,'unknown') FatherName
FROM
tbTechCh tbtp
JOIN
tbPersons tbo ON tbtp.PersonsID = tbo.ID
WHERE
tbtp.DateCh IS NULL
ORDER BY
tbo.Surname
That SqlDataReader always returns the last row so many times as there are rows in the stored procedure result. I can't find what is the problem... Help!
EDIT: stored procedure returns data as intended but this problem is only present in the service.
List.Add adds an object reference. In .NET reference types are never implicitly copied. References are copied. There isn't even a general way to copy an object.
Create a new object for each row.

Retrieve SQL Statement Does Not Go Into While Loop

I am having problem when doing retrieve function in 3-tier in C#. Here is the codes:
public DistributionStandardPackingUnits getSPUDetail(string distributionID)
{
DistributionStandardPackingUnits SPUFound = new DistributionStandardPackingUnits();
using (var connection = new SqlConnection(FoodBankDB.connectionString))
{
SqlCommand command = new SqlCommand("SELECT name, description, quantity FROM dbo.DistributionStandardPackingUnits WHERE distribution = '" + distributionID + "'", connection);
connection.Open();
using (var dr = command.ExecuteReader())
{
while (dr.Read())
{
string name = dr["name"].ToString();
string description = dr["description"].ToString();
string quantity = dr["quantity"].ToString();
SPUFound = new DistributionStandardPackingUnits(name, description, quantity);
}
}
}
return SPUFound;
}
When I run in browser, it just won't show up any retrieved data. When I run in debugging mode, I realized that when it hits the while loop, instead of executing the dr.Read(), it simply just skip the entire while loop and return null values. I wonder what problem has caused this. I tested my query using the test query, it returns me something that I wanted so I think the problem does not lies at the Sql statement.
Thanks in advance.
Edited Portion
public static SqlDataReader executeReader(string query)
{
SqlDataReader result = null;
System.Diagnostics.Debug.WriteLine("FoodBankDB executeReader: " + query);
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
result = command.ExecuteReader();
connection.Close();
return result;
}

silverlight C# code

This is coded in Service.svc.cs file
[OperationContract]
public List<Branch> GetAllBranch()
{
List<Branch> Br = new List<Branch>();
using (SqlConnection con = new SqlConnection(myConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "GetBranch";
cmd.Connection = con;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Branch BrName = new Branch();
BrName.Name = Convert.ToString(dr["BranchName"]);
Br.Add(BrName);
}
dr.Close();
}
}
return Br;
}
public class Branch
{
public string Name { get; set; }
}
End of Service file Code----
This is coded in the Form
ServiceClient client= new ServiceClient();
test.GetAllBranchCompleted += (s, ea) =>
{
cboBranch.ItemsSource = ea.Result;
};
client.GetAllBranchAsync();
My requirement is I want to populate all the Names of the Branches that are present in my database.With this code the combobox for BranchName is getting populated but not with the Database records but something like this CRUD.ServiceReference1.ServiceBranch.
CRUD is my solution Name.
Please correct me with this..
Thanks
To get just the name to appear in your ComboBox you need to result a List<string>. Here you are returning a List<Branch>.
So you either need to rework your service code or just extract a list of strings from your ea.Result.
cboBranch.ItemsSource = ea.Result.Select(b => b.Name).ToList();
(from memory)