Web API in ASP.net C# - asp.net-mvc

I want to create a web API controller that returns product details with id. Using stored procedure calls from a database class, not DB context. Sending Request with ID & getting a response with Jason's values.
I saw many examples but they are directly using stored procedures from the DB context. But I want to introduce a connection string & call that method in business class than a business class call to the controller with the response return.
Please help with a small example

Here is one example. You can choose between using SQL Command or SQL Adapter, try searching a little bit more about it.
Programming isn't only writing a code it's also googling for solutions.
// Setup connection string to access local SQL Server 2000
string connectionString = "server=localhost;" +
"database=Northwind;uid=sa;pwd=manager";
// Instantiate the connection, passing the
// connection string into the constructor
SqlConnection con = new SqlConnection(connectionString);
// Open the connection
con.Open();
// Create and execute the query
SqlCommand cmd = new SqlCommand("SELECT * FROM Customers",con);
SqlDataReader reader = cmd.ExecuteReader();
// Iterate through the DataReader and display row
while(reader.Read()) {
Console.WriteLine("{0} - {1}",
reader.GetString(0), reader.GetString(1));
}
Source

Related

Connect Azure MI SQL View to MVC app as read only code first

One aspect of an ASP.net core (6) MVC app I am working on needs to query an SQL View that already resides in an Azure SQL MI.
I need to be able to query this SQL View to be able to retrieve the data based on user input but with the following conditions.
I cannot use Entity Framework.
The connection has to be read only.
This has to be database first.
As of yet I do not have access to this View or any of the tables it draws from. However I am expected to have code ready to plug a connection string into.
Unfortunately any resources I have been able to find don't seem to apply to my specific conditions. So any advice in what direction or approach would work best would be appreciated.
Those are by no means "silly" conditions. You didn't specify the language or the database but I'll make assumptions
I cannot use Entity Framework
Just use standard ado.net
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ado-net-code-examples#sqlclient
(I know that Link only answers are frowned upon)
The connection has to be read only.
Ensure that the account you connect under is read only. In SQL Server this is achieved by making you a member of the db_datareader group. This is something that should be enforced by the DBA that gives you an account
This has to be database first.
That's not really relevant. Just use the linked sample code to read from the existing view.
Literal copy paste of code at the link above:
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString =
"Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=true";
// Provide the query string with a parameter placeholder.
string queryString =
"SELECT ProductID, UnitPrice, ProductName from dbo.products "
+ "WHERE UnitPrice > #pricePoint "
+ "ORDER BY UnitPrice DESC;";
// Specify the parameter value.
int paramValue = 5;
// Create and open the connection in a using block. This
// ensures that all resources will be closed and disposed
// when the code exits.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
// Create the Command and Parameter objects.
SqlCommand command = new SqlCommand(queryString, connection);
command.Parameters.AddWithValue("#pricePoint", paramValue);
// Open the connection in a try/catch block.
// Create and execute the DataReader, writing the result
// set to the console window.
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("\t{0}\t{1}\t{2}",
reader[0], reader[1], reader[2]);
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}

How to initialize and persist Castle ActiveRecordStarter per session for multi tenancy apps?

I am using Castle ActiveRecord in my Asp.net / MVC 2 / Multi-tenancy application with SQL Server as my backend.
For every user logging in, the app loads the corresponding DB, dynamically at run time like below:
IDictionary<string, string> properties = new Dictionary<string, string>();
properties.Add("connection.driver_class", "NHibernate.Driver.SqlClientDriver");
properties.Add("dialect", "NHibernate.Dialect.MsSql2005Dialect");
properties.Add("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
properties.Add("connection.connection_string", strDBConnection);
InPlaceConfigurationSource source = new InPlaceConfigurationSource();
source.Add(typeof(ActiveRecordBase), properties);
ActiveRecordStarter.Initialize(new System.Reflection.Assembly[] { asm1 }, source);
The strDBConnection string comes from another small database that holds the user info, corresponding DB, etc.
Scenario:
When a user logs in, his DB gets loaded, he can do his CRUD jobs -- No Probs !
Another user logs in (from another remote machine) his DB gets loaded -- No Probs !
Now, when the first user reads from DB, he sees new data from the second user's DB
My little understanding for this behavious is : ActiveRecordStarter is a Static object.
Could someone help me with a solution for this situation ?
The expected behaviour:
each user should access his own DB only, securely, in parallel / at the same time.
Thanks a lot !
ActiveRecordStarter.Initialize should only be called once in your app (in Application_Start in Global.asax).
To achieve what you want, create a class that inherits from NHibernate.Connection.DriverConnectionProvider:
public class MyCustomConnectionProvider : DriverConnectionProvider
{
protected override string GetNamedConnectionString(IDictionary<string, string> settings)
{
return string.Empty;
}
public override IDbConnection GetConnection()
{
// Get your connection here, based on the request
// You can use HttpContext.Current to get information about the current request
var conn = Driver.CreateConnection();
conn.ConnectionString = ... // Retrieve the connection string here;
conn.Open();
return conn;
}
}
Then set the connection.provider property to the name of your class:
properties.Add("connection.provider", "MyCompany.Domain.MyCustomConnectionProvider, MyCompany.AssemblyName");

Create Query without entity framework

I have the following code, but I can’t work out what I need to put in place of the // before .AddObject(Model); and .SaveChanges(); to get the method to work. It’s a create query but I’ve only ever done this while using the Entity Framework before now, in this case I’m not using EF.
[HttpPost]
public ActionResult Registration(UserDetailModel Model)
{
if (ModelState.IsValid)
{
Model.UserNameFK = User.Identity.Name;
Model.CompanyName = "CompanyName";
Model.IEMI = "IEMI";
//.AddObject(Model);
//.SaveChanges();
return RedirectToAction("Registration", "Home");
}
return View(Model);
}
Am I close?
Cheers,
Mike.
I hope you know Entity Framework is an Object Relational Mapping framework for .NET.
Basically it creates entity classes that map up to your database and make it easy to perform Create/Read/Update/Delete operations without writing any SQL.
If you're not using Entity Framework, you could use another ORM like NHinbernate.
OR
You could use plain ADO.NET classes with SQL to write/read data to/from your database.
Ex: If you're using SQL Server you would use the System.Data.SqlClient namespace for writing to your SQL DB, see the SQLCommand class (Writing to other supported DB's work the same way)
You would do something like this with the function below it:
CreateCommand(//just as an example you can use values from your model in sql
"INSERT INTO Users(Name, CompnayName, IMEI,) VALUES ("
+ Model.UserNameFK +", val2, val3,...)",
"your connection string"
);
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
See this for more documentation.

Query with ROWID via data provider

I am looking to query a table like the following sql:
select * from itd093 where rowid='Cumn99AAAAMzAAAAAJ'
It could find a unique record in the ADS architect client. However, when this query was sent from the code level through the .NET data provider, it return none result from the database server.
Does anyone have ideas on how I can make the sql above return the result through the .NET data provider?
Some sample code here:
public void DataProviderTest()
{
using (AdsConnection conn = new AdsConnection(#"Data Source=D:\Development\FDDB;ServerType=ADS_LOCAL_SERVER;TableType=ADS_CDX;TrimTrailingSpaces=TRUE;"))
{
conn.Open();
AdsCommand cmd = new AdsCommand("select * from itd093 where rowid='Cumn99AAAAMzAAAAAJ'", conn);
AdsDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
if (!reader.Read())
throw new Exception("no records");
}
}
Thanks Mark for pointing out that the .NET data provider and the Advantage Data Architect should return the same result.
The problem to be the different connection strings. From the help documentation, it says,the first six characters of the ROWID represent the database ID. It is based on the connection path.
I was mistakenly copy a rowid from the data architect to test with data provider, and the connection strings are different. That's why I couldn't get a result returned from the data provider as it does from the data architect.

Repository Connection Pooling

I'm in a hoo-ha with my boss as I can't shift to using newer technologies until I have proof of some outstanding issues. One of the main concerns is how repositories deal with connections. One of the supposedly largest overheads is connecting and disconnecting to/from the database. If I have a repository where I do the following:
public ContractsControlRepository()
: base(ConfigurationManager.ConnectionStrings["AccountsConnectionString"].ToString()) { }
with the class like so:
public class ContractsControlRepository : DataContext, IContractsControlRepository
with functions like:
public IEnumerable<COContractCostCentre> ListContractCostCentres(int contractID)
{
string query = "SELECT C.ContractID, C.CCCode, MAC.CostCentre, C.Percentage FROM tblCC_Contract_CC C JOIN tblMA_CostCentre MAC ON MAC.CCCode = C.CCCode WHERE C.ContractID = {0}";
return this.ExecuteQuery<COContractCostCentre>(query, contractID);
}
Now if in my controller action called _contractsControlRepository.ListContractCostCentres(2) followed immediately by another call to the repository, does it use the same connection? When does the connection open in the controller? When is it closed?
Cheers
EDIT
I'm using hand-written LINQ as suggested by Steve Sanderson in his ASP.NET MVC book.
EDIT EDIT
To clarify, I'm using LINQ as my ORM, but I'm using raw SQL queries (as shown in the extract above) for querying. For example, here's a controller action:
public ActionResult EditBusiness(string id)
{
Business business = _contractsControlRepository.FetchBusinessByID(id);
return View(business);
}
I'm not opening/closing connections.
Here's a larger, more complete extract of my repo:
public class ContractsControlRepository : DataContext, IContractsControlRepository
{
public ContractsControlRepository()
: base(ConfigurationManager.ConnectionStrings["AccountsConnectionString"].ToString()) { }
public IEnumerable<COContractCostCentre> ListContractCostCentres(int contractID)
{
string query = "SELECT C.ContractID, C.CCCode, MAC.CostCentre, C.Percentage FROM tblCC_Contract_CC C JOIN tblMA_CostCentre MAC ON MAC.CCCode = C.CCCode WHERE C.ContractID = {0}";
return this.ExecuteQuery<COContractCostCentre>(query, contractID);
}
Then ContractsControlRepository is instantiated in my controller and used like _contractsControlRepository.ListContractCostCentres(2). Connections aren't opened manually, DataContext deals with that for me.
Without knowing the details of your ORM and how it connects the SQL database drivers will connection pool. When a connection is closed it is released back to the pool and kept open for X number of seconds (where X is configurable). If another connection is opened and all the parameters match (the server name, the application name, the database name, the authentication details etc.) then any free, but open connections in the pool will get reused instead of opening a brand new connection.
Having not read the book in question I don't know what "manual linq" actually is. If it's manual means you're getting the tables back youself then obviously you're doing the connection open/close. Linq to SQL will use a new connection object when a statement is finally executed at which point connection pooling comes into play - which means a new connection object may not be an actual new connection.

Resources