I'm only using ASP.Net and MVC, no other libraries.
The code is the following:
//ExpensesController.cs - the controller
public IActionResult getExpenses()
{
List<ExpensesViewModel> list = new List<ExpensesViewModel>();
string connectionString = "Data Source=DESKTOP-72RT825;Initial Catalog=AccountingDB;Integrated Security=True;Pooling=False";
SqlConnection sqlConnection = new SqlConnection(connectionString);
sqlConnection.Open();
SqlCommand query = new SqlCommand("Select * from Expenses", sqlConnection);
try
{
SqlDataReader reader;
reader = query.ExecuteReader();
while (reader.Read())
{
String name = reader.GetValue(0).ToString();
String value = reader.GetValue(1).ToString();
String date = reader.GetValue(2).ToString();
list.Add(new ExpensesViewModel() { Name = name, Date=date, Value = value });
Debug.Print(name + " " + " " + value);
}
}
catch (SqlException ex)
{
Debug.Print(ex.Message);
return Json(ex.Message);
}
JsonResult jsonResult = null;
try
{
jsonResult = Json(list);
}
catch(Exception ex)
{
Debug.Write(ex.Message);
}
return jsonResult;
}
//The View Model
public class ExpensesViewModel
{
public string Name;
public string Value;
public string Date;
}
The data that Json(list) returns is null, even though the list is not, I looked in the debugger, the connection to the DB is good, the data arrives, it is put into the list, but when I try and convert it to Json it fails. I've tried adding elements into the list manually, the Json function still returns null.
Change your view model to use properties, not fields:
public class ExpensesViewModel
{
public string Name { get; set; }
public string Value { get; set; }
public string Date { get; set; }
}
The reason is that the default model binder binds to properties with public getters/setters.
Related
I am able to successfully pass string values, but having trouble passing integer value via Query String.
If I only pass string objects the URL looks like
www.website.com/mypage?ProductName=TestName&MahName=TestName (Correct)
However, if I pass Id (int) along with the query string the URL looks like
www.website.com/mypage/1?ProductName=TestName&MahName=TestName (Incorrect)
However, I would like it to be
www.website.com/mypage?Id=1&ProductName=TestName&MahName=TestName
Model
using System.Data.SqlClient;
using System.ComponentModel.DataAnnotations;
namespace SecureMedi.Models
{
public class CustomProductData
{
[Required]
public int Id { get; set; }
[StringLength(200)]
public string ProductName { get; set; }
[StringLength(100)]
public string MahName { get; set; }
public static CustomProductData FromSqlReader(SqlDataReader rdr)
{
return new CustomProductData
{
Id = (int)rdr["id"],
ProductName = rdr["product_name"].ToString(),
MahName = rdr["mah_name"].ToString()
};
}
}
}
Controller
[HttpGet]
public ActionResult CustomProductData(int Id, string ProductName, string MahName) {
var model = new CustomProductData() {
Id = Id,
ProductName = ProductName,
MahName = MahName
};
return View(model);
}
[HttpPost]
public ActionResult CustomProductData(CustomProductData cp) {
try {
using(ISecureMediDatabase db = new SecureMediDatabase(this)) {
CustomProductDataDAL cpd = new CustomProductDataDAL(db);
cpd.Edit(cp);
return RedirectToAction("LoadCustomProductData");
}
} catch (Exception ex) {
ModelState.AddModelError("", ex.Message);
return View(cp);
}
}
DAL
public void Edit(CustomProductData cp) {
try {
string sql = "UPDATE table_name SET product_name = #ProductName, mah_name = #MahName WHERE id = #Id";
if (cp.HasDetails()) {
using(SqlCommand cmd = new SqlCommand(sql, conn)) {
cmd.Parameters.Add(new SqlParameter("#Id", cp.Id));
cmd.Parameters.Add(new SqlParameter("#ProductName", cp.ProductName));
cmd.Parameters.Add(new SqlParameter("#MahName", cp.MahName));
PrepareCommand(cmd);
cmd.ExecuteNonQuery();
}
}
} catch {
closeConnection();
throw;
}
}
cshtml
Anchor link to pass the query string values to the edit page (which take the values from the QueryString)
<td class="text-secondary">#Html.ActionLink("Edit", "CustomProductData", "Home", new { Id = #item.Id, ProductName = #item.ProductName, MahName = #item.MahName }, new { #class = "text-info" })</td>
Apparently, the variable name Id was occupied in the routing and thus changing the variable name Id to RecordId solved the issue.
I am trying to retrieve a set of data from a MySQL database in a WebAPI application and access it through HTTP request from a mobile app. Hence I created a WebApi, a RestClient class and the class where I would show the data, this is my code.
Web API
[Produces("application/json")]
[Route("api/Blog")]
public class BlogController : Controller
{
// GET: api/Blog
[HttpGet]
public IEnumerable<string> Get()
{
}
// GET: api/Blog/5
[HttpGet("{id}", Name = "GetBlogItems")]
public string Get(int id)
{
}
// POST: api/Blog
[HttpPost]
public void Post([FromBody] RetrieveDataClass value)
{
string sqlstring = "server=; port= ; user id =;Password=;Database=;";
MySqlConnection conn = new MySqlConnection(sqlstring);
try
{
conn.Open();
}
catch (MySqlException ex)
{
throw ex;
}
string Query = "INSERT INTO test.blogtable (id,Telephone,CreatedSaved,Topic,Summary,Category,Body1,Body2,Body3,Body4)values('" + value.TopicSaved1 + "','" + Value.Telephone + "','" + Value.Created/Saved + "','" + value.TopicSaved1 + "','" +value.SummarySaved1 +"','" +value.CategoriesSaved1 +"','" +value.Body1 +"','" +value.Body2 +"','" +value.Body3 +"','" +value.Body4 +"');";
MySqlCommand cmd = new MySqlCommand(Query, conn);
cmd.ExecuteReader();
conn.Close();
}
// PUT: api/Blog/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE: api/ApiWithActions/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
So, in my database, I have three rows with a telephone number of +233892929292, after the filter I have to get three rows. and I would also filter to only the topic and summary column.
RestClient Class
public class BlogRestClient<T>
{
private const string WebServiceUrl = "http://localhost:57645/api/Blog/";
public async Task<List<T>> GetAsync()
{
var httpClient = new HttpClient();
var json = await httpClient.GetStringAsync(WebServiceUrl);
var taskModels = JsonConvert.DeserializeObject<List<T>>(json);
return taskModels;
}
public async Task<bool> PostAsync(T t)
{
var httpClient = new HttpClient();
var json = JsonConvert.SerializeObject(t);
HttpContent httpContent = new StringContent(json);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result = await httpClient.PostAsync(WebServiceUrl, httpContent);
return result.IsSuccessStatusCode;
}
public async Task<bool> PutAsync(int id, T t)
{
var httpClient = new HttpClient();
var json = JsonConvert.SerializeObject(t);
HttpContent httpContent = new StringContent(json);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result = await httpClient.PutAsync(WebServiceUrl + id, httpContent);
return result.IsSuccessStatusCode;
}
public async Task<bool> DeleteAsync(int id, T t)
{
var httpClient = new HttpClient();
var response = await httpClient.DeleteAsync(WebServiceUrl + id);
return response.IsSuccessStatusCode;
}
}
ModelData Class
public class ModelDataClass
{
public string Telephone ;
public string Created/Saved ;
public string TopicSaved1 ;
public string SummarySaved1 ;
public string CategoriesSaved1 ;
public string Body1 ;
public string Body2 ;
public string Body3 ;
public string Body4 ;
public ModelDataClass()
{
}
}
The Values for the strings in ModelDataClass are set in another class to post in MySQL database. Since that is not causing the problem in question, I have not included the code.
RetrieveDataClass
public class RetrieveDataClass
{
public string Topic ;
public string Summary ;
public RetrieveDataClass()
{
GetDataEvent();
AddBlog();
}
public void GetDataEvent()
{
BlogRestClient<ModelDataClass> restClient = new
BlogRestClient<ModelDataClass>();
await restClient.GetAsync();
}
public ObservableCollection<ModelDataClass> BlogItems = new
ObservableCollection<ModelDataClass>();
public void AddBlog()
{
BlogListView.ItemsSource = BlogItems;
}
}
Question1
How do I retrieve the data from, Mysql, to WebAPI accessed through the REST client class(It's for mobile so I have to use Http request)?
Question2
I would like to create a listView for each row I retrieve through the MySQL database. With the heading being the data in the topic column and the subheading is with the data in summary column.
Your application is designed with the Multitier Architecture pattern. As such, you need to ensure you have a separation of concerns.
The Web API will represent your presentation logic layer. It will parse the client's request, query for the data as required and format the returned data as needed.
The RetrieveClient can then handle the data access layer. It will manage access to the database, insert, update, delete as needed.
The key point here is to ensure that each layer talks to the other to perform actions and that you do not directly access the database in your presentation layer.
As such,
How to retrieve data?
In your Data Access Layer :
public class RetrieveDataClass
{
private IDbConnection connection;
public RetrieveDataClass(System.Data.IDbConnection connection)
{
// Setup class variables
this.connection = connection;
}
/// <summary>
/// <para>Retrieves the given record from the database</para>
/// </summary>
/// <param name="id">The identifier for the record to retrieve</param>
/// <returns></returns>
public EventDataModel GetDataEvent(int id)
{
EventDataModel data = new EventDataModel();
string sql = "SELECT id,Telephone,CreatedSaved,Topic,Summary,Category,Body1,Body2,Body3,Body4 WHERE id = #id";
using (IDbCommand cmd = connection.CreateCommand())
{
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
IDbDataParameter identity = cmd.CreateParameter();
identity.ParameterName = "#id";
identity.Value = id;
identity.DbType = DbType.Int32; // TODO: Change to the matching type for id column
cmd.Parameters.Add(identity);
try
{
connection.Open();
using (IDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
data.id = reader.GetInt32(reader.GetOrdinal("id"));
// TODO : assign the rest of the properties to the object
}
else
{
// TODO : if method should return null when data is not found
data = null;
}
}
// TODO : Catch db exceptions
} finally
{
// Ensure connection is always closed
if (connection.State != ConnectionState.Closed) connection.Close();
}
}
// TODO : Decide if you should return null, or empty object if target cannot be found.
return data;
}
// TODO : Insert, Update, Delete methods
}
The above will get a record from the database, and return it as an object. You can use ORM libraries such as EntityFramework or NHibernate instead but they have their own learning curve.
How to return the data?
Your client will call the WebAPI, which in turn query for the data from the data access layer.
[Produces("application/json")]
[Route("api/Blog")]
public class BlogController : Controller
{
// TODO : Move the connection string to configuration
string sqlstring = "server=; port= ; user id =;Password=;Database=;";
// GET: api/Blog
/// <summary>
/// <para>Retrieves the given record from the database</para>
/// </summary>
/// <param name="id">Identifier for the required record</param>
/// <returns>JSON object with the data for the requested object</returns>
[HttpGet]
public IEnumerable<string> Get(int id)
{
IDbConnection dbConnection = System.Data.Common.DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
RetrieveDataClass dal = new RetrieveDataClass(dbConnection);
EventDataModel data = dal.GetDataEvent(id);
if (data != null)
{
// Using Newtonsoft library to convert the object to JSON data
string output = Newtonsoft.Json.JsonConvert.SerializeObject(data);
// TODO : Not sure if you need IEnumerable<string> as return type
return new List<string>() { output };
} else
{
// TODO : handle a record not found - usually raises a 404
}
}
// TODO : other methods
}
There are lots of other examples online on how to access the data via API. Have a look on google and review. A few that come to mind are
https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-2.2&tabs=visual-studio
https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
i solved the problem.
WebApi
[Produces("application/json")]
[Route("api/Blog")]
public class BlogController : Controller
{
// GET: api/Blog
[HttpGet]
public List<BlogViews> Get()
{
string sqlstring = "server=; port= ; user id =;Password=;Database=;";
MySqlConnection conn = new MySqlConnection(sqlstring);
try
{
conn.Open();
}
catch (MySqlException ex)
{
throw ex;
}
string Query = "SELECT * FROM test.blogtable where `Telephone` ='Created'";
MySqlCommand cmd = new MySqlCommand(Query, conn);
MySqlDataReader MSQLRD = cmd.ExecuteReader();
List<BlogViews> GetBlogList = new List<BlogViews>();
if (MSQLRD.HasRows)
{
while (MSQLRD.Read())
{
BlogViews BV = new BlogViews();
BV.id = (MSQLRD["id"].ToString());
BV.DisplayTopic = (MSQLRD["Topic"].ToString());
BV.DisplayMain = (MSQLRD["Summary"].ToString());
GetBlogList.Add(BV);
}
}
conn.Close();
return GetBlogList;
}
// GET: api/Blog/5
[HttpGet("{id}", Name = "GetBlogItems")]
public string Get(int id)
{
}
// POST: api/Blog
[HttpPost]
public void Post([FromBody] RetrieveDataClass value)
{
string sqlstring = "server=; port= ; user id =;Password=;Database=;";
MySqlConnection conn = new MySqlConnection(sqlstring);
try
{
conn.Open();
}
catch (MySqlException ex)
{
throw ex;
}
string Query = "INSERT INTO test.blogtable (id,Telephone,CreatedSaved,Topic,Summary,Category,Body1,Body2,Body3,Body4)values('" + value.TopicSaved1 + "','" + Value.Telephone + "','" + Value.Created/Saved + "','" + value.TopicSaved1 + "','" +value.SummarySaved1 +"','" +value.CategoriesSaved1 +"','" +value.Body1 +"','" +value.Body2 +"','" +value.Body3 +"','" +value.Body4 +"');";
MySqlCommand cmd = new MySqlCommand(Query, conn);
cmd.ExecuteReader();
conn.Close();
}
// PUT: api/Blog/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE: api/ApiWithActions/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
RetriveDataClass
public class RetrieveDataClass
{
public RetrieveDataClass()
{
AddBlog();
}
public class BlogViews
{
public string id { get; set; }
public string DisplayTopic { get; set; }
public string DisplayMain { get; set; }
public ImageSource BlogImageSource { get; set; }
}
public List<BlogViews> BlogList1 = new List<BlogViews>();
public async Task< List<BlogViews>> GetBlogs()
{
BlogRestClient<BlogViews> restClient = new BlogRestClient<BlogViews>();
var BlogV = await restClient.GetAsync();
return BlogV;
}
public async void AddBlog()
{
BlogList1 = await GetBlogs();
BlogListView.ItemsSource = BlogList1;
}
}
so now i get a listview ,which contains each row from the database and each item in the listview heading is DisplayTopic and subheading is DisplayMain.
I am consuming wcf service into console application . I am trying to retrieve account information based on account number . But the problem is when i enter the account number and hit enter ,its only displaying account number and rest of the fields are empty.
Here is the base class.
[DataContract]
public class Current_Account_Details
{
string account_creation_date;
string account_type;
string branch_sort_code;
string account_fees;
string account_balance;
string over_draft_limit;
string account_holder_id;
[DataMember]
public string Account_Creation_Date
{
get { return account_creation_date; }
set { account_creation_date = value; }
}
[DataMember]
public string Account_Type
{
get { return account_type; }
set { account_type = value; }
}
[DataMember]
public string Branch_Sort_Code
{
get { return branch_sort_code; }
set { branch_sort_code = value; }
}
[DataMember]
public string Account_Fees
{
get { return account_fees; }
set { account_fees = value; }
}
[DataMember]
public string Account_Balance
{
get { return account_balance; }
set { account_balance = value; }
}
[DataMember]
public string Over_Draft_Limit
{
get { return over_draft_limit; }
set { over_draft_limit = value; }
}
[DataMember]
public string Account_Holder_Id
{
get { return account_holder_id; }
set { account_holder_id = value; }
}
}
}
Here is the inherited class.
[DataContract]
public class AccountBalanceRequest : Current_Account_Details
{
string account_number;
[DataMember]
public string Account_Number
{
get { return account_number; }
set { account_number = value; }
}
}
}
Here is the Interface .
[OperationContract]
AccountBalanceRequest AccountBalanceCheek(AccountBalanceRequest accountNumber);
Here is my Method .
public AccountBalanceRequest AccountBalanceCheek(AccountBalanceRequest accountNumber)
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
//use top 1 since you are only getting one record.
//let us use string interpolation, if you are working below C#6
//replace it with your previous value
var cmd = new SqlCommand($#"SELECT TOP 1
*
FROM
Current_Account_Details
WHERE
Account_Number ='{accountNumber.Account_Number}'", conn);
cmd.CommandType = CommandType.Text;
//use ExecuteReader to execute sql select
//ExecuteNonQuery is for update, delete, and insert.
var reader = cmd.ExecuteReader();
//read the result of the execute command.
while (reader.Read())
{
//assuming that your property is the same as your table schema. refer to your table schema Current_Account_Details
//assuming that your datatype are string... just do the conversion...
accountNumber.Account_Balance = reader["Account_Balance"].ToString();
accountNumber.Account_Fees = reader["Account_Fees"].ToString();
accountNumber.Account_Balance = reader["Account_Balance"].ToString();
accountNumber.Over_Draft_Limit = reader["Over_Draft_Limit"].ToString();
}
return accountNumber;
}
}
Here is the code in Console Application .
public static void Balance()
{
MyService.HalifaxCurrentAccountServiceClient currentAccount = new MyService.HalifaxCurrentAccountServiceClient("NetTcpBinding_IHalifaxCurrentAccountService");
MyService.AccountBalanceRequest cs = new MyService.AccountBalanceRequest();
string AccountNumber;
Console.WriteLine("\nEnter your Account Number--------:");
AccountNumber = Console.ReadLine();
cs.Account_Number = AccountNumber;
// MyService.AccountBalanceRequest cs1 = currentAccount.AccountBalanceCheek(AccountNumber);
MyService.AccountBalanceRequest AccountBalance = currentAccount.AccountBalanceCheek(cs);//error on this line
Console.WriteLine("Account Number is :" + cs.Account_Number);
Console.WriteLine("Account creation date :" + cs.Account_Creation_Date);
Console.WriteLine("Account Type :" + cs.Account_Type);
Console.WriteLine("Branch_Sort_Code:" + cs.Branch_Sort_Code);
Console.WriteLine("Account_Fee:" + cs.Account_Fees);
Console.WriteLine("Account Account_Balance :" + cs.Account_Balance);
Console.WriteLine("Account Over Draft Limit :" + cs.Over_Draft_Limit);
Console.Write("--------------------------");
Console.ReadLine();
//Console.Clear();
}
Here is the screen shot of the database.click here to record
Here is the screen shot when i run the applicationClick here to see the result.In this screen shot only the account number is displaying and rest of the fields are empty
your Current_Account_Details is the base class and AccountBalanceRequest is derived class from your question posted.
If we have classes related by inheritance, the wcf service generally accepts and returns the base type. If you expect the service to accept and return inherited types, then use KnownType attribute.
So its enough if you decorate the base class with contracts and try.
[KnownType(typeof(AccountBalanceRequest))]
[DataContract]
public class Current_Account_Details
{
string account_creation_date;
string account_type;
string branch_sort_code;
string account_fees;
string account_balance;
string over_draft_limit;
string account_holder_id;
[DataMember]
public string Account_Creation_Date
{
get { return account_creation_date; }
set { account_creation_date = value; }
}
[DataMember]
public string Account_Type
{
get { return account_type; }
set { account_type = value; }
}
[DataMember]
public string Branch_Sort_Code
{
get { return branch_sort_code; }
set { branch_sort_code = value; }
}
[DataMember]
public string Account_Fees
{
get { return account_fees; }
set { account_fees = value; }
}
[DataMember]
public string Account_Balance
{
get { return account_balance; }
set { account_balance = value; }
}
[DataMember]
public string Over_Draft_Limit
{
get { return over_draft_limit; }
set { over_draft_limit = value; }
}
[DataMember]
public string Account_Holder_Id
{
get { return account_holder_id; }
set { account_holder_id = value; }
}
}
}
public class AccountBalanceRequest : Current_Account_Details
{
string account_number;
public string Account_Number
{
get { return account_number; }
set { account_number = value; }
}
}
Just check whether account number that you read from console is passed in the accountnumber variable.
var cmd = new SqlCommand("SELECT * FROM Current_Account_Details WHERE Account_Number = '" + accountNumber + "'", conn);
Edit 1: Your service is failing to retrieve records because you are passing the AccountBalanceRequest object and the changes made to the object is not reflected outside the method.
MyService.AccountBalanceRequest cs = new MyService.AccountBalanceRequest();
Change it to.
public AccountBalanceRequest AccountBalanceCheek(AccountBalanceRequest accountNumber)
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
//use top 1 since you are only getting one record.
//let us use string interpolation, if you are working below C#6
//replace it with your previous value
var cmd = new SqlCommand($#"SELECT TOP 1
*
FROM
Current_Account_Details
WHERE
Account_Number ='{accountNumber.Account_Number}'", conn));
cmd.CommandType = CommandType.Text;
//use ExecuteReader to execute sql select
//ExecuteNonQuery is for update, delete, and insert.
var reader = cmd.ExecuteReader();
//read the result of the execute command.
while(reader.Read())
{
//assuming that your property is the same as your table schema. refer to your table schema Current_Account_Details
//assuming that your datatype are string... just do the conversion...
accountNumber.Account_Balance = reader["Account_Balance"].ToString();
accountNumber.Account_Fee = reader["Account_Fee"].ToString();
accountNumber.Account_Balance = reader["Account_Balance"].ToString();
accountNumber.Over_Draft_Limit = reader["Over_Draft_Limit"].ToString();
}
return accountNumber;
}
}
In your console retrieve it,
MyService.AccountBalanceRequest AccountBalance =currentAccount.AccountBalanceCheek(cs);
Console.WriteLine("Your Account Number is :" + cs.Account_Number)
...
I think your problem is that you're passing a reference to the WCF service method and changing it there instead of returning. The documentation says that:
Each operation has a return value and a parameter, even if these are void. However, unlike a local method, in which you can pass references to objects from one object to another, service operations do not pass references to objects. Instead, they pass copies of the objects.
Try to change your code so the method returns the changed object. At the end of AccountBalanceCheek method instead of returning true return accountNumber.
And then in Balance method - remove if statement and change to:
....
cs = currentAccount.AccountBalanceCheek(cs);
Console.WriteLine("Your Account Number is :" + cs.Account_Number);
Console.WriteLine("Your Account Type :" + cs.Account_Balance);
....
To read more about it: Is it possible to pass parameters by reference with WCF
This is my class.
I have a method called retrievecinemainfo which connects with my other class called Bioscoopinfo. This method (retrievecinemainfo) is declared at my main form.
The problem is that when I want to retrieve the data from the database, it doesn't return it into the textboxes, it does collect the right data because I have seen it in the debugger. But when it passes my class constructor called bioscoopinfo, the values are empty all of a sudden and it doesn't return anything.
Can anyone please help?
class sqlconnectie
{
public Bioscoopinfo retrievecinemainfo (string Locatie, string Bioscoop, string Tijd)
{
Bioscoopinfo biosinfo = null;
SqlDataReader myreader;
try
{
con.Open();
myreader = cmd.ExecuteReader();
if (myreader.Read())
{
Locatie = myreader.GetString(1);
Bioscoop = myreader.GetString(2);
Tijd = myreader.GetString(3);
biosinfo = new Bioscoopinfo(Locatie, Bioscoop, Tijd);
string strpath = Application.StartupPath;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return biosinfo;
}
}
and this here is my class where the values eventually return nothing:
class Bioscoopinfo
{
public string locatie { get; set; }
public string bioscoop { get; set; }
public string tijd { get; set; }
public Bioscoopinfo(string locatie, string bioscoop, string tijd)
{
this.locatie = "place";
this.bioscoop = "cinema";
this.tijd = "19:00";
}
}
and this here is the code where my code will actually get used
connectie = new sqlconnectie();
connectie.stringcommand("SELECT * FROM Bios where Locatie = '" + comboBox1.Text + "' ");
string bioscoop = tbbioscoop.Text;
string locatie = tblocatie.Text;
string tijd = tbtijd.Text;
connectie.retrievecinemainfo(bioscoop, locatie, tijd);
I am trying to insert data into a database using a three-tier architecture, but I am stuck and I cannot proceed further.
This is my code
First is UI part:
public void assignField()
{
string maritalCondition = "";
string sex = "";
assignObj.Registered_Date = dateTimePicker1_Date.Value;
assignObj.First_Name = txt_FirstName.Text;
if (comboBox2_MaritalStatus.SelectedIndex == 0)
{
maritalCondition = "Single";
}
else
maritalCondition = "Married";
assignObj.Marital_Status = maritalCondition;
if (RadioButton_Male.Checked == true)
sex = "Male";
else
sex = "Female";
assignObj.Gender = sex;
this.txt_Age.Text = Convert.ToInt32(age).ToString();
}
private void btnRegister_Click(object sender, EventArgs e)
{
assignField();
}
Next is the middle tier:
public class CustomerDataType
{
private DateTime registered_Date;
private string first_Name;
private int age;
private string marital_Status;
private string gender;
public DateTime Registered_Date
{
get { return registered_Date; }
set { registered_Date = value; }
}
public string First_Name
{
get { return first_Name; }
set { first_Name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public string Marital_Status
{
get { return marital_Status; }
set { marital_Status = value; }
}
public string Gender
{
get { return gender; }
set { gender = value; }
}
public void insertInfo()
{
CustomerDataAccess insertObj = new CustomerDataAccess(Registered_Date, First_Name, Age, Marital_Status, Gender);
insertObj.insertCustomerInfo();
}
}
and last is the data access tier:
public class CustomerDataAccess
{
public CustomerDataAccess(DateTime Registered_Date, string First_Name, int Age, string Marital_Status, string Gender)
{
this.registrationDate = Registered_Date;
this.fName = First_Name;
this.userAge = Age;
this.marriageStatus = Marital_Status;
this.userGender = Gender;
}
SqlConnection con;
SqlCommand cmd;
DateTime registrationDate;
string fName = "";
int userAge;
string marriageStatus;
string userGender;
public void insertCustomerInfo()
{
try
{
con = new SqlConnection("Data Source=LAKHE-PC;Initial Catalog=Sahakari;Integrated Security=True");
con.Open();
cmd = con.CreateCommand();
cmd.CommandText = "sp_registerCust";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Registered_Date", SqlDbType.DateTime);
cmd.Parameters["#Registered_Date"].Value = registrationDate;
cmd.Parameters.Add("#First_Name", SqlDbType.VarChar);
cmd.Parameters["#First_Name"].Value = fName;
cmd.Parameters.Add("#Age", SqlDbType.Int.ToString());
cmd.Parameters["#Age"].Value = userAge;
cmd.Parameters.Add("#Marital_Status", SqlDbType.VarChar);
cmd.Parameters["#Marital_Status"].Value = marriageStatus;
cmd.Parameters.Add("#Gender", SqlDbType.VarChar);
cmd.Parameters["#Gender"].Value = userGender;
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Here with the stored procedure, there is no problem and and from SQL Server I can insert data into table easily. But from windows form, it does not insert data in table. Plz help me.
I'll do something like below
UI
CustomerHandler custHandler = new CustomerHandler();
// create Customer object and pass to insert method
if (custHandler.InsertCustomer(new Customer(){
FirstName = txt_FirstName.Text, Registered_Date =dateTimePicker1_Date.Value,
//decalare other parameters....
))
{
// insert Success, show message or update label with succcess message
}
In my BL
public class CustomerHandler
{
// in BL you may have to call several DAL methods to perform one Task
// here i have added validation and insert
// in case of validation fail method return false
public bool InsertCustomer(Customer customer)
{
if (CustomerDataAccess.Validate(customer))
{
CustomerDataAccess.insertCustomer(customer);
return true;
}
return false;
}
}
In MY DAL
// this is the class you going to use to transfer data across the layers
public class Customer
{
public DateTime Registered_Date { get; set; }
public string FirstName { get; set; }
//so on...
}
public class CustomerDataAccess
{
public static void insertCustomer(Customer customer)
{
using (var con = new SqlConnection("Data Source=LAKHE-PC;Initial Catalog=Sahakari;Integrated Security=True"))
using (var cmd = con.CreateCommand())
{
con.Open();
cmd.CommandText = "sp_registerCust";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Registered_Date", customer.Registered_Date);
cmd.Parameters.AddWithValue("#FirstName", customer.FirstName);
// so on...
cmd.ExecuteNonQuery();
}
}
internal static bool Validate(Customer customer)
{
// some validations before insert
}
}
Your middle tier consists of classes holding the values you require in properties. Instead of writing the data access manually, try using the Entity Framework (EF) which does that for you.
Here (at MSDN) you can find a quickstart example which shows you how you can use it.
Instead of mapping the fields manually and executing a query, the Entity Framework does that which means you just have to assign the values to the object's properties and call SaveChanges() - the SQL code is created and executed automatically by the EF.
For further reading, there is also a lot to find here (at Stackoverflow).