From 0961b720540e3d5583c95aa56e5be172e8b7ddcf Mon Sep 17 00:00:00 2001 From: "CMS4390\\marantalu" Date: Wed, 22 Nov 2017 14:56:22 +0100 Subject: [PATCH 1/4] Cambio del tipo di progetto da Web a Console application e pulizia app.config con rimozione del web.config --- .gitignore | 1 + Step.sln | 2 +- Step/App.config | 26 +++++++++++++++++++------- Step/Step.csproj | 28 +++++++--------------------- Step/Step.csproj.user | 37 +------------------------------------ Step/packages.config | 1 + 6 files changed, 30 insertions(+), 65 deletions(-) diff --git a/.gitignore b/.gitignore index eb2896a1..0f30bbf4 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ yarn-error.log* *.suo *.ntvs* *.njsproj +/ConsoleApp1 diff --git a/Step.sln b/Step.sln index 3629227e..0c4ffe7d 100644 --- a/Step.sln +++ b/Step.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.12 +VisualStudioVersion = 15.0.27004.2009 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step", "Step\Step.csproj", "{AFED34E1-77DB-4D81-830A-A8D0A190573D}" EndProject diff --git a/Step/App.config b/Step/App.config index 5e2866de..a8115dc3 100644 --- a/Step/App.config +++ b/Step/App.config @@ -1,20 +1,21 @@ - + + +
+ - - + + - - + - @@ -47,4 +48,15 @@ - + + + + + + + + + + + + \ No newline at end of file diff --git a/Step/Step.csproj b/Step/Step.csproj index fa4a1def..e0bd496a 100644 --- a/Step/Step.csproj +++ b/Step/Step.csproj @@ -11,20 +11,11 @@ 2.0 {AFED34E1-77DB-4D81-830A-A8D0A190573D} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} WinExe Properties Step Step v4.6.2 - false - true - - - - - - 2.3 @@ -49,6 +40,12 @@ 4 + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + ..\packages\Microsoft.AspNet.SignalR.Core.2.2.2\lib\net45\Microsoft.AspNet.SignalR.Core.dll @@ -317,18 +314,7 @@ - - - - - True - - - - - - - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. diff --git a/Step/Step.csproj.user b/Step/Step.csproj.user index c84e6ec1..5e69eaea 100644 --- a/Step/Step.csproj.user +++ b/Step/Step.csproj.user @@ -16,40 +16,5 @@ False - - - - - index.html - SpecificPage - True - False - False - False - - - - - - - - - True - True - False - True - 51998 - / - http://localhost - False - True - - - - - - - - - + \ No newline at end of file diff --git a/Step/packages.config b/Step/packages.config index 98b1b30c..0cc97219 100644 --- a/Step/packages.config +++ b/Step/packages.config @@ -1,5 +1,6 @@  + From 7a6e75ffd5a3d42800647471235940041895cff2 Mon Sep 17 00:00:00 2001 From: "CMS4390\\marantalu" Date: Thu, 23 Nov 2017 16:31:30 +0100 Subject: [PATCH 2/4] Added Bearer oAuth Authentication: * Create User with roles * Login * Authorization without roles --- Step.Database/App.config | 31 + Step.Database/Controllers/UsersController.cs | 71 + Step.Database/DatabaseContext.cs | 24 + Step.Database/Properties/AssemblyInfo.cs | 36 + Step.Database/Step.Database.csproj | 95 ++ Step.Database/docs/MySqlCommand.xml | 934 ++++++++++++ Step.Database/docs/MySqlCommandBuilder.xml | 321 +++++ Step.Database/docs/MySqlConnection.xml | 1248 +++++++++++++++++ .../docs/MySqlConnectionStringBuilder.xml | 55 + Step.Database/docs/MySqlDataAdapter.xml | 801 +++++++++++ Step.Database/docs/MySqlDataReader.xml | 452 ++++++ Step.Database/docs/MySqlException.xml | 53 + Step.Database/docs/MySqlHelper.xml | 53 + Step.Database/docs/MySqlParameter.xml | 45 + .../docs/MySqlParameterCollection.xml | 45 + Step.Database/docs/MySqlTransaction.xml | 329 +++++ Step.Database/packages.config | 9 + Step.Model/App.config | 17 + Step.Model/LoginViewModel.cs | 15 - Step.Model/LoginViewModel.cs.d.ts | 6 - Step.Model/RoleModel.cs | 23 + Step.Model/RoleModel.cs.d.ts | 8 + Step.Model/Step.Model.csproj | 37 +- Step.Model/TestModel.cs | 15 - Step.Model/TestModel.cs.d.ts | 5 - Step.Model/UserModel.cs | 33 + Step.Model/UserModel.cs.d.ts | 12 + Step.Model/packages.config | 6 + Step.sln | 6 + Step/App.config | 12 +- Step/App_Start/Startup.cs | 68 +- Step/Controllers/DataController.cs | 23 - Step/Controllers/LoginController.cs | 24 +- Step/Provider/ApplicationOAuthProvider.cs | 43 + Step/Step.csproj | 13 +- Step/packages.config | 2 + Step/wwwroot/src/@types/RoleModel.cs.d.ts | 8 + Step/wwwroot/src/@types/RolesModel.cs.d.ts | 7 + Step/wwwroot/src/@types/UserModel.cs.d.ts | 12 + 39 files changed, 4884 insertions(+), 113 deletions(-) create mode 100644 Step.Database/App.config create mode 100644 Step.Database/Controllers/UsersController.cs create mode 100644 Step.Database/DatabaseContext.cs create mode 100644 Step.Database/Properties/AssemblyInfo.cs create mode 100644 Step.Database/Step.Database.csproj create mode 100644 Step.Database/docs/MySqlCommand.xml create mode 100644 Step.Database/docs/MySqlCommandBuilder.xml create mode 100644 Step.Database/docs/MySqlConnection.xml create mode 100644 Step.Database/docs/MySqlConnectionStringBuilder.xml create mode 100644 Step.Database/docs/MySqlDataAdapter.xml create mode 100644 Step.Database/docs/MySqlDataReader.xml create mode 100644 Step.Database/docs/MySqlException.xml create mode 100644 Step.Database/docs/MySqlHelper.xml create mode 100644 Step.Database/docs/MySqlParameter.xml create mode 100644 Step.Database/docs/MySqlParameterCollection.xml create mode 100644 Step.Database/docs/MySqlTransaction.xml create mode 100644 Step.Database/packages.config create mode 100644 Step.Model/App.config delete mode 100644 Step.Model/LoginViewModel.cs delete mode 100644 Step.Model/LoginViewModel.cs.d.ts create mode 100644 Step.Model/RoleModel.cs create mode 100644 Step.Model/RoleModel.cs.d.ts delete mode 100644 Step.Model/TestModel.cs delete mode 100644 Step.Model/TestModel.cs.d.ts create mode 100644 Step.Model/UserModel.cs create mode 100644 Step.Model/UserModel.cs.d.ts create mode 100644 Step.Model/packages.config delete mode 100644 Step/Controllers/DataController.cs create mode 100644 Step/Provider/ApplicationOAuthProvider.cs create mode 100644 Step/wwwroot/src/@types/RoleModel.cs.d.ts create mode 100644 Step/wwwroot/src/@types/RolesModel.cs.d.ts create mode 100644 Step/wwwroot/src/@types/UserModel.cs.d.ts diff --git a/Step.Database/App.config b/Step.Database/App.config new file mode 100644 index 00000000..300c297c --- /dev/null +++ b/Step.Database/App.config @@ -0,0 +1,31 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Step.Database/Controllers/UsersController.cs b/Step.Database/Controllers/UsersController.cs new file mode 100644 index 00000000..eb3bb5f1 --- /dev/null +++ b/Step.Database/Controllers/UsersController.cs @@ -0,0 +1,71 @@ +using System; +using System.Linq; +using System.Web.Helpers; +using Step.Model; + +namespace Step.Database.Controllers +{ + public class UsersController : IDisposable + { + private DatabaseContext dbCtx; + + public UsersController() + { + // Initialize database context + dbCtx = new DatabaseContext(); + } + + public void Dispose() + { + // Clear database context + dbCtx.Dispose(); + } + + public void Create(string userName, string password, string firstName, string lastName, int roleId) + { + // Create a new user model with params + UserModel user = new UserModel() + { + Username = userName, + Password = Crypto.HashPassword(password), + FirstName = firstName, + LastName = lastName, + RoleId = roleId, + SecurityStamp = Guid.NewGuid().ToString() + }; + // Add to database + dbCtx.Users.Add(user); + // Commit changes + dbCtx.SaveChanges(); + } + + public UserModel Find(int id) + { + // Find user by Id with Role object included + return dbCtx.Users.Include("Role").Where(u => u.UserId == id).First(); + } + + public UserModel Find(string username) + { + // Find user by Id with Role object included + return dbCtx.Users.Include("Role").Where(u => u.Username == username).FirstOrDefault(); + } + + public UserModel Find(string username, string password) + { + // Find if username exists + UserModel user = Find(username); + + if (user != null) + { + // Check if the passwords match + if (Crypto.VerifyHashedPassword(user.Password, password) != true) + { + return null; + } + } + + return user; + } + } +} diff --git a/Step.Database/DatabaseContext.cs b/Step.Database/DatabaseContext.cs new file mode 100644 index 00000000..58340e7c --- /dev/null +++ b/Step.Database/DatabaseContext.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Data.Entity; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Step.Model; +using MySql.Data.Entity; + +namespace Step.Database +{ + + [DbConfigurationType(typeof(MySqlEFConfiguration))] + public class DatabaseContext : DbContext + { + public DbSet Users { get; set; } + public DbSet Roles { get; set; } + + public DatabaseContext() + : base("databaseConnection") + { + } + } +} diff --git a/Step.Database/Properties/AssemblyInfo.cs b/Step.Database/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..38bed75f --- /dev/null +++ b/Step.Database/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Le informazioni generali relative a un assembly sono controllate dal seguente +// set di attributi. Modificare i valori di questi attributi per modificare le informazioni +// associate a un assembly. +[assembly: AssemblyTitle("Step.Database")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Step.Database")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili +// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da +// COM, impostare su true l'attributo ComVisible per tale tipo. +[assembly: ComVisible(false)] + +// Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi +[assembly: Guid("357d5ee1-ffc8-489b-9232-22cf474d9a6f")] + +// Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: +// +// Versione principale +// Versione secondaria +// Numero di build +// Revisione +// +// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build +// usando l'asterisco '*' come illustrato di seguito: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Step.Database/Step.Database.csproj b/Step.Database/Step.Database.csproj new file mode 100644 index 00000000..83b7082b --- /dev/null +++ b/Step.Database/Step.Database.csproj @@ -0,0 +1,95 @@ + + + + + Debug + AnyCPU + {357D5EE1-FFC8-489B-9232-22CF474D9A6F} + Library + Properties + Step.Database + Step.Database + v4.6.2 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll + + + ..\packages\Microsoft.AspNet.Identity.EntityFramework.2.2.1\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll + + + ..\packages\MySql.Data.6.10.4\lib\net452\MySql.Data.dll + True + + + ..\packages\MySql.Data.Entity.6.9.10\lib\net45\MySql.Data.Entity.EF6.dll + + + + + + ..\packages\System.Web.Helpers.Crypto.3.2.3\lib\net40\System.Web.Helpers.Crypto.dll + + + + + + + + + + + + + + + + + + + + {631375dd-06d3-49bb-8130-d9ddb34c429d} + Step.Model + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlCommand.xml b/Step.Database/docs/MySqlCommand.xml new file mode 100644 index 00000000..4d891521 --- /dev/null +++ b/Step.Database/docs/MySqlCommand.xml @@ -0,0 +1,934 @@ + + + Represents a SQL statement to execute against a MySQL database. This class cannot be inherited. + + MySqlCommand features the following methods for executing commands at a MySQL database: + + + Item + Description + + + + ExecuteReader + + Executes commands that return rows. + + + + ExecuteNonQuery + + Executes commands such as SQL INSERT, DELETE, and UPDATE statements. + + + + ExecuteScalar + + Retrieves a single value (for example, an aggregate value) from a database. + + + + You can reset the CommandText property and reuse the MySqlCommand + object. However, you must close the MySqlDataReader + before you can execute a new or previous command. + + If a MySqlException is + generated by the method executing a MySqlCommand, the MySqlConnection + remains open. It is the responsibility of the programmer to close the connection. + + + Using the '@' symbol for paramters is now the preferred approach although the old pattern of using + '?' is still supported. Please be aware though that using '@' can cause conflicts when user variables + are also used. To help with this situation please see the documentation on the 'allow user variables' + connection string option. The 'old syntax' connection string option has now been deprecated. + + + + + The following example creates a MySqlCommand and + a MySqlConnection. The MySqlConnection is opened and set as the Connection + for the MySqlCommand. The example then calls ExecuteNonQuery, + and closes the connection. To accomplish this, the ExecuteNonQuery is + passed a connection string and a query string that is a SQL INSERT + statement. + + Public Sub InsertRow(myConnectionString As String) + " If the connection string is null, use a default. + If myConnectionString = "" Then + myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass" + End If + Dim myConnection As New MySqlConnection(myConnectionString) + Dim myInsertQuery As String = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)" + Dim myCommand As New MySqlCommand(myInsertQuery) + myCommand.Connection = myConnection + myConnection.Open() + myCommand.ExecuteNonQuery() + myCommand.Connection.Close() + End Sub + + + public void InsertRow(string myConnectionString) + { + // If the connection string is null, use a default. + if(myConnectionString == "") + { + myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass"; + } + MySqlConnection myConnection = new MySqlConnection(myConnectionString); + string myInsertQuery = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)"; + MySqlCommand myCommand = new MySqlCommand(myInsertQuery); + myCommand.Connection = myConnection; + myConnection.Open(); + myCommand.ExecuteNonQuery(); + myCommand.Connection.Close(); + } + + + + + + + + + + Initializes a new instance of the MySqlCommand class. + + + The following example creates a MySqlCommand and sets some of its properties. + + + This example shows how to use one of the overloaded + versions of the MySqlCommand constructor. For other examples that might be available, + see the individual overload topics. + + + + Public Sub CreateMySqlCommand() + Dim myConnection As New MySqlConnection _ + ("Persist Security Info=False;database=test;server=myServer") + myConnection.Open() + Dim myTrans As MySqlTransaction = myConnection.BeginTransaction() + Dim mySelectQuery As String = "SELECT * FROM MyTable" + Dim myCommand As New MySqlCommand(mySelectQuery, myConnection, myTrans) + myCommand.CommandTimeout = 20 + End Sub + + + public void CreateMySqlCommand() + { + MySqlConnection myConnection = new MySqlConnection("Persist Security Info=False; + database=test;server=myServer"); + myConnection.Open(); + MySqlTransaction myTrans = myConnection.BeginTransaction(); + string mySelectQuery = "SELECT * FROM myTable"; + MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection,myTrans); + myCommand.CommandTimeout = 20; + } + + + public: + void CreateMySqlCommand() + { + MySqlConnection* myConnection = new MySqlConnection(S"Persist Security Info=False; + database=test;server=myServer"); + myConnection->Open(); + MySqlTransaction* myTrans = myConnection->BeginTransaction(); + String* mySelectQuery = S"SELECT * FROM myTable"; + MySqlCommand* myCommand = new MySqlCommand(mySelectQuery, myConnection, myTrans); + myCommand->CommandTimeout = 20; + }; + + + + + + + Initializes a new instance of the MySqlCommand class. + + + The base constructor initializes all fields to their default values. The + following table shows initial property values for an instance of . + + + Properties + Initial Value + + + + + + empty string ("") + + + + + + 0 + + + + + + CommandType.Text + + + + + + Null + + + + You can change the value for any of these properties through a separate call to + the property. + + + + The following example creates a and + sets some of its properties. + + + Public Sub CreateMySqlCommand() + Dim myCommand As New MySqlCommand() + myCommand.CommandType = CommandType.Text + End Sub + + + public void CreateMySqlCommand() + { + MySqlCommand myCommand = new MySqlCommand(); + myCommand.CommandType = CommandType.Text; + } + + + + + + + Initializes a new instance of the class with the text of the query. + + The text of the query. + + When an instance of is created, + the following read/write properties are set to initial values. + + + + Properties + Initial Value + + + + + + + cmdText + + + + + + + 0 + + + + + + CommandType.Text + + + + + + Null + + + + You can change the value for any of these properties through a separate call to + the property. + + + + The following example creates a and + sets some of its properties. + + + Public Sub CreateMySqlCommand() + Dim sql as String = "SELECT * FROM mytable" + Dim myCommand As New MySqlCommand(sql) + myCommand.CommandType = CommandType.Text + End Sub + + + public void CreateMySqlCommand() + { + string sql = "SELECT * FROM mytable"; + MySqlCommand myCommand = new MySqlCommand(sql); + myCommand.CommandType = CommandType.Text; + } + + + + + + + Initializes a new instance of the class + with the text of the query and a . + + The text of the query. + + A that represents the + connection to an instance of SQL Server. + + + When an instance of is created, + the following read/write properties are set to initial values. + + + + Properties + Initial Value + + + + + + + cmdText + + + + + + + 0 + + + + + + CommandType.Text + + + + + + + connection + + + + + You can change the value for any of these properties through a separate call to + the property. + + + + The following example creates a and + sets some of its properties. + + + Public Sub CreateMySqlCommand() + Dim conn as new MySqlConnection("server=myServer") + Dim sql as String = "SELECT * FROM mytable" + Dim myCommand As New MySqlCommand(sql, conn) + myCommand.CommandType = CommandType.Text + End Sub + + + public void CreateMySqlCommand() + { + MySqlConnection conn = new MySqlConnection("server=myserver") + string sql = "SELECT * FROM mytable"; + MySqlCommand myCommand = new MySqlCommand(sql, conn); + myCommand.CommandType = CommandType.Text; + } + + + + + + + + + Initializes a new instance of the class + with the text of the query, a , and the + . + + + The text of the query. + + A that represents the + connection to an instance of SQL Server. + + + The in which the executes. + + + When an instance of is created, + the following read/write properties are set to initial values. + + + + Properties + Initial Value + + + + + + + cmdText + + + + + + + 0 + + + + + + CommandType.Text + + + + + + + connection + + + + + You can change the value for any of these properties through a separate call to + the property. + + + + The following example creates a and + sets some of its properties. + + + Public Sub CreateMySqlCommand() + Dim conn as new MySqlConnection("server=myServer") + conn.Open(); + Dim txn as MySqlTransaction = conn.BeginTransaction() + Dim sql as String = "SELECT * FROM mytable" + Dim myCommand As New MySqlCommand(sql, conn, txn) + myCommand.CommandType = CommandType.Text + End Sub + + + public void CreateMySqlCommand() + { + MySqlConnection conn = new MySqlConnection("server=myserver") + conn.Open(); + MySqlTransaction txn = conn.BeginTransaction(); + string sql = "SELECT * FROM mytable"; + MySqlCommand myCommand = new MySqlCommand(sql, conn, txn); + myCommand.CommandType = CommandType.Text; + } + + + + + + + + + + + Executes a SQL statement against the connection and returns the number of rows affected. + + Number of rows affected + + You can use ExecuteNonQuery to perform any type of database operation, + however any resultsets returned will not be available. Any output parameters + used in calling a stored procedure will be populated with data and can be + retrieved after execution is complete. + For UPDATE, INSERT, and DELETE statements, the return value is the number + of rows affected by the command. For all other types of statements, the return + value is -1. + + + The following example creates a MySqlCommand and then + executes it using ExecuteNonQuery. The example is passed a string that is a + SQL statement (such as UPDATE, INSERT, or DELETE) and a string to use to + connect to the data source. + + Public Sub CreateMySqlCommand(myExecuteQuery As String, myConnection As MySqlConnection) + Dim myCommand As New MySqlCommand(myExecuteQuery, myConnection) + myCommand.Connection.Open() + myCommand.ExecuteNonQuery() + myConnection.Close() + End Sub + + + public void CreateMySqlCommand(string myExecuteQuery, MySqlConnection myConnection) + { + MySqlCommand myCommand = new MySqlCommand(myExecuteQuery, myConnection); + myCommand.Connection.Open(); + myCommand.ExecuteNonQuery(); + myConnection.Close(); + } + + + + + + + Sends the to the Connection, + and builds a using one of the values. + + + One of the values. + + + + When the property is set to StoredProcedure, + the property should be set to the name of the stored + procedure. The command executes this stored procedure when you call + ExecuteReader. + + + The supports a special mode that enables large binary + values to be read efficiently. For more information, see the SequentialAccess + setting for . + + + While the is in use, the associated + is busy serving the MySqlDataReader. + While in this state, no other operations can be performed on the + MySqlConnection other than closing it. This is the case until the + method of the MySqlDataReader is called. + If the MySqlDataReader is created with CommandBehavior set to + CloseConnection, closing the MySqlDataReader closes the connection + automatically. + + + When calling ExecuteReader with the SingleRow behavior, you should be aware that using a limit + clause in your SQL will cause all rows (up to the limit given) to be retrieved by the client. The + method will still return false after the first row but pulling all rows of data + into the client will have a performance impact. If the limit clause is not necessary, it should + be avoided. + + + + A object. + + + + + + + Sends the to the Connection + and builds a . + + + A object. + + + + When the property is set to StoredProcedure, + the property should be set to the name of the stored + procedure. The command executes this stored procedure when you call + ExecuteReader. + + + While the is in use, the associated + is busy serving the MySqlDataReader. + While in this state, no other operations can be performed on the + MySqlConnection other than closing it. This is the case until the + method of the MySqlDataReader is called. + + + + The following example creates a , then executes it by + passing a string that is a SQL SELECT statement, and a string to use to connect to the + data source. + + Public Sub CreateMySqlDataReader(mySelectQuery As String, myConnection As MySqlConnection) + Dim myCommand As New MySqlCommand(mySelectQuery, myConnection) + myConnection.Open() + Dim myReader As MySqlDataReader + myReader = myCommand.ExecuteReader() + Try + While myReader.Read() + Console.WriteLine(myReader.GetString(0)) + End While + Finally + myReader.Close + myConnection.Close + End Try + End Sub + + + public void CreateMySqlDataReader(string mySelectQuery, MySqlConnection myConnection) + { + MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection); + myConnection.Open(); + MMySqlDataReader myReader; + myReader = myCommand.ExecuteReader(); + try + { + while(myReader.Read()) + { + Console.WriteLine(myReader.GetString(0)); + } + } + finally + { + myReader.Close(); + myConnection.Close(); + } + } + + + + + + + + Creates a prepared version of the command on an instance of MySQL Server. + + + + Prepared statements are only supported on MySQL version 4.1 and higher. Calling + prepare while connected to earlier versions of MySQL will succeed but will execute + the statement in the same way as unprepared. + + + + The following example demonstrates the use of the Prepare method. + + public sub PrepareExample() + Dim cmd as New MySqlCommand("INSERT INTO mytable VALUES (@val)", myConnection) + cmd.Parameters.Add( "@val", 10 ) + cmd.Prepare() + cmd.ExecuteNonQuery() + + cmd.Parameters(0).Value = 20 + cmd.ExecuteNonQuery() + end sub + + + private void PrepareExample() + { + MySqlCommand cmd = new MySqlCommand("INSERT INTO mytable VALUES (@val)", myConnection); + cmd.Parameters.Add( "@val", 10 ); + cmd.Prepare(); + cmd.ExecuteNonQuery(); + + cmd.Parameters[0].Value = 20; + cmd.ExecuteNonQuery(); + } + + + + + + + Executes the query, and returns the first column of the first row in the + result set returned by the query. Extra columns or rows are ignored. + + + The first column of the first row in the result set, or a null reference if the + result set is empty + + + + Use the ExecuteScalar method to retrieve a single value (for example, + an aggregate value) from a database. This requires less code than using the + method, and then performing the operations necessary + to generate the single value using the data returned by a + + + + The following example creates a and then + executes it using ExecuteScalar. The example is passed a string that is a + SQL statement that returns an aggregate result, and a string to use to + connect to the data source. + + + Public Sub CreateMySqlCommand(myScalarQuery As String, myConnection As MySqlConnection) + Dim myCommand As New MySqlCommand(myScalarQuery, myConnection) + myCommand.Connection.Open() + myCommand.ExecuteScalar() + myConnection.Close() + End Sub + + + public void CreateMySqlCommand(string myScalarQuery, MySqlConnection myConnection) + { + MySqlCommand myCommand = new MySqlCommand(myScalarQuery, myConnection); + myCommand.Connection.Open(); + myCommand.ExecuteScalar(); + myConnection.Close(); + } + + + public: + void CreateMySqlCommand(String* myScalarQuery, MySqlConnection* myConnection) + { + MySqlCommand* myCommand = new MySqlCommand(myScalarQuery, myConnection); + myCommand->Connection->Open(); + myCommand->ExecuteScalar(); + myConnection->Close(); + } + + + + + + + + Gets or sets the SQL statement to execute at the data source. + + + The SQL statement or stored procedure to execute. The default is an empty string. + + + + When the property is set to StoredProcedure, + the CommandText property should be set to the name of the stored procedure. + The user may be required to use escape character syntax if the stored procedure name + contains any special characters. The command executes this stored procedure when + you call one of the Execute methods. Starting with Connector/Net 5.0, having both a stored function + and stored procedure with the same name in the same database is not supported. It is + suggested that you provide unqiue names for your stored routines. + + + + The following example creates a and sets some of its properties. + + Public Sub CreateMySqlCommand() + Dim myCommand As New MySqlCommand() + myCommand.CommandText = "SELECT * FROM Mytable ORDER BY id" + myCommand.CommandType = CommandType.Text + End Sub + + + public void CreateMySqlCommand() + { + MySqlCommand myCommand = new MySqlCommand(); + myCommand.CommandText = "SELECT * FROM mytable ORDER BY id"; + myCommand.CommandType = CommandType.Text; + } + + + + + + + Gets or sets the wait time before terminating the attempt to execute a command + and generating an error. + + + The time (in seconds) to wait for the command to execute. The default is 30 + seconds. + + + CommandTimeout is dependent on the ability of MySQL to cancel an executing query. + Because of this, CommandTimeout is only supported when connected to MySQL + version 5.0.0 or higher. + + + + + + Gets or sets a value indicating how the property is to be interpreted. + + + One of the values. The default is Text. + + + + When you set the CommandType property to StoredProcedure, you + should set the property to the name of the stored + procedure. The command executes this stored procedure when you call one of the + Execute methods. + + + + The following example creates a and sets some of its properties. + + Public Sub CreateMySqlCommand() + Dim myCommand As New MySqlCommand() + myCommand.CommandType = CommandType.Text + End Sub + + + public void CreateMySqlCommand() + { + MySqlCommand myCommand = new MySqlCommand(); + myCommand.CommandType = CommandType.Text; + } + + + + + + + + + + + Gets or sets the used by this instance of the + . + + + The connection to a data source. The default value is a null reference + (Nothing in Visual Basic). + + + + If you set Connection while a transaction is in progress and the + property is not null, an + is generated. If the Transaction property is not null and the transaction + has already been committed or rolled back, Transaction is set to + null. + + + + The following example creates a and sets some of its properties. + + Public Sub CreateMySqlCommand() + Dim mySelectQuery As String = "SELECT * FROM mytable ORDER BY id" + Dim myConnectString As String = "Persist Security Info=False;database=test;server=myServer" + Dim myCommand As New MySqlCommand(mySelectQuery) + myCommand.Connection = New MySqlConnection(myConnectString) + myCommand.CommandType = CommandType.Text + End Sub + + + public void CreateMySqlCommand() + { + string mySelectQuery = "SELECT * FROM mytable ORDER BY id"; + string myConnectString = "Persist Security Info=False;database=test;server=myServer"; + MySqlCommand myCommand = new MySqlCommand(mySelectQuery); + myCommand.Connection = new MySqlConnection(myConnectString); + myCommand.CommandType = CommandType.Text; + } + + + + + + + + + Provides the id of the last inserted row. + + Id of the last inserted row. -1 if none exists. + + + An important point to remember is that this property can be used + in batch SQL scenarios but it's important to remember that it will + only reflect the insert id from the last insert statement in the batch. + + This property can also be used when the batch includes select statements + and ExecuteReader is used. This property can be consulted during result set + processing. + + + + + + Get the + + + The parameters of the SQL statement or stored procedure. The default is + an empty collection. + + + Connector/Net does not support unnamed parameters. Every parameter added to the collection must + have an associated name. + + + The following example creates a and displays its parameters. + To accomplish this, the method is passed a , a query string + that is a SQL SELECT statement, and an array of objects. + + Public Sub CreateMySqlCommand(myConnection As MySqlConnection, _ + mySelectQuery As String, myParamArray() As MySqlParameter) + Dim myCommand As New MySqlCommand(mySelectQuery, myConnection) + myCommand.CommandText = "SELECT id, name FROM mytable WHERE age=@age" + myCommand.UpdatedRowSource = UpdateRowSource.Both + myCommand.Parameters.Add(myParamArray) + Dim j As Integer + For j = 0 To myCommand.Parameters.Count - 1 + myCommand.Parameters.Add(myParamArray(j)) + Next j + Dim myMessage As String = "" + Dim i As Integer + For i = 0 To myCommand.Parameters.Count - 1 + myMessage += myCommand.Parameters(i).ToString() & ControlChars.Cr + Next i + Console.WriteLine(myMessage) + End Sub + + + public void CreateMySqlCommand(MySqlConnection myConnection, string mySelectQuery, + MySqlParameter[] myParamArray) + { + MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection); + myCommand.CommandText = "SELECT id, name FROM mytable WHERE age=@age"; + myCommand.Parameters.Add(myParamArray); + for (int j=0; j<myParamArray.Length; j++) + { + myCommand.Parameters.Add(myParamArray[j]) ; + } + string myMessage = ""; + for (int i = 0; i < myCommand.Parameters.Count; i++) + { + myMessage += myCommand.Parameters[i].ToString() + "\n"; + } + MessageBox.Show(myMessage); + } + + + + + + + Gets or sets the within which the executes. + + + The . The default value is a null reference (Nothing in Visual Basic). + + + You cannot set the Transaction property if it is already set to a + specific value, and the command is in the process of executing. If you set the + transaction property to a object that is not connected + to the same as the object, + an exception will be thrown the next time you attempt to execute a statement. + + + + + + Gets or sets how command results are applied to the + when used by the method + of the . + + + One of the values. + + + + The default value is + Both unless the command is automatically generated (as in the case of the + ), in which case the default is None. + + + + + diff --git a/Step.Database/docs/MySqlCommandBuilder.xml b/Step.Database/docs/MySqlCommandBuilder.xml new file mode 100644 index 00000000..3a2da92d --- /dev/null +++ b/Step.Database/docs/MySqlCommandBuilder.xml @@ -0,0 +1,321 @@ + + + + Automatically generates single-table commands used to reconcile changes made to a DataSet with the associated MySQL database. This class cannot be inherited. + + + + The does not automatically generate the SQL statements required to + reconcile changes made to a DataSet with the associated instance of MySQL. + However, you can create a MySqlCommandBuilder object to automatically generate SQL statements for + single-table updates if you set the SelectCommand property + of the MySqlDataAdapter. Then, any additional SQL statements that you do not set are generated by the + MySqlCommandBuilder. + + + + The MySqlCommandBuilder registers itself as a listener for RowUpdating + events whenever you set the property. You can only associate one + MySqlDataAdapter or MySqlCommandBuilder object with each other at one time. + + + + To generate INSERT, UPDATE, or DELETE statements, the MySqlCommandBuilder uses the + SelectCommand property to retrieve a required set of metadata automatically. If you change + the SelectCommand after the metadata has is retrieved (for example, after the first update), you + should call the method to update the metadata. + + + + The SelectCommand must also return at least one primary key or unique + column. If none are present, an InvalidOperation exception is generated, + and the commands are not generated. + + + + The MySqlCommandBuilder also uses the Connection, + CommandTimeout, and Transaction + properties referenced by the SelectCommand. The user should call + RefreshSchema if any of these properties are modified, or if the + SelectCommand itself is replaced. Otherwise the InsertCommand, + UpdateCommand, and + DeleteCommand properties retain + their previous values. + + + + If you call Dispose, the MySqlCommandBuilder is disassociated + from the MySqlDataAdapter, and the generated commands are no longer used. + + + + Caution must be used when using MySqlCOmmandBuilder on MySql 4.0 systems. With MySql 4.0, + database/schema information is not provided to the connector for a query. This means that + a query that pulls columns from two identically named tables in two or more different databases + will not cause an exception to be thrown but will not work correctly. Even more dangerous + is the situation where your select statement references database X but is executed in + database Y and both databases have tables with similar layouts. This situation can cause + unwanted changes or deletes. + This note does not apply to MySQL versions 4.1 and later. + + + + + + The following example uses the , along + and , to + select rows from a data source. The example is passed an initialized + , a connection string, a + query string that is a SQL SELECT statement, and a string that is the + name of the database table. The example then creates a MySqlCommandBuilder. + + + Public Shared Function SelectRows(myConnection As String, mySelectQuery As String, myTableName As String) As DataSet + Dim myConn As New MySqlConnection(myConnection) + Dim myDataAdapter As New MySqlDataAdapter() + myDataAdapter.SelectCommand = New MySqlCommand(mySelectQuery, myConn) + Dim cb As SqlCommandBuilder = New MySqlCommandBuilder(myDataAdapter) + + myConn.Open() + + Dim ds As DataSet = New DataSet + myDataAdapter.Fill(ds, myTableName) + + ' Code to modify data in DataSet here + + ' Without the MySqlCommandBuilder this line would fail. + myDataAdapter.Update(ds, myTableName) + + myConn.Close() + End Function 'SelectRows + + + public static DataSet SelectRows(string myConnection, string mySelectQuery, string myTableName) + { + MySqlConnection myConn = new MySqlConnection(myConnection); + MySqlDataAdapter myDataAdapter = new MySqlDataAdapter(); + myDataAdapter.SelectCommand = new MySqlCommand(mySelectQuery, myConn); + MySqlCommandBuilder cb = new MySqlCommandBuilder(myDataAdapter); + + myConn.Open(); + + DataSet ds = new DataSet(); + myDataAdapter.Fill(ds, myTableName); + + //code to modify data in DataSet here + + //Without the MySqlCommandBuilder this line would fail + myDataAdapter.Update(ds, myTableName); + + myConn.Close(); + + return ds; + } + + + + + + + + Initializes a new instance of the class. + + + + + + Initializes a new instance of the class + with the associated object. + + + The to use. + + + + The registers itself as a listener for + events that are generated by the + specified in this property. + + + When you create a new instance MySqlCommandBuilder, any existing + MySqlCommandBuilder associated with this MySqlDataAdapter + is released. + + + + + + + + Gets or sets a object for which SQL statements are automatically generated. + + + A object. + + + + The registers itself as a listener for + events that are generated by the + specified in this property. + + + When you create a new instance MySqlCommandBuilder, any existing + MySqlCommandBuilder associated with this MySqlDataAdapter + is released. + + + + + + + Gets or sets the beginning character or characters to use when specifying MySQL + database objects (for example, tables or columns) whose names contain + characters such as spaces or reserved tokens. + + + The beginning character or characters to use. The default value is `. + + + Database objects in MySQL can contain special characters such as spaces that would + make normal SQL strings impossible to correctly parse. Use of the QuotePrefix + and the properties allows the + to build SQL commands that handle this situation. + + + + + + Gets or sets the beginning character or characters to use when specifying MySQL + database objects (for example, tables or columns) whose names contain + characters such as spaces or reserved tokens. + + + The beginning character or characters to use. The default value is `. + + + Database objects in MySQL can contain special characters such as spaces that would + make normal SQL strings impossible to correctly parse. Use of the + and the QuoteSuffix properties allows the + to build SQL commands that handle this situation. + + + + + + + + + + + + + + Gets the automatically generated object + required to perform deletions on the database. + + + The object generated to handle delete operations. + + + + An application can use the GetDeleteCommand method for informational + or troubleshooting purposes because it returns the + object to be executed. + + + You can also use GetDeleteCommand as the basis of a modified command. + For example, you might call GetDeleteCommand and modify the + value, and then explicitly set that on the + . + + + After the SQL statement is first generated, the application must explicitly + call if it changes the statement in any way. + Otherwise, the GetDeleteCommand will be still be using information + from the previous statement, which might not be correct. The SQL statements + are first generated either when the application calls + or GetDeleteCommand. + + + + + + + Gets the automatically generated object + required to perform insertions on the database. + + + The object generated to handle insert operations. + + + + An application can use the GetInsertCommand method for informational + or troubleshooting purposes because it returns the + object to be executed. + + + You can also use the GetInsertCommand as the basis of a modified command. + For example, you might call GetInsertCommand and modify the + value, and then explicitly set that on the + . + + + After the SQL statement is first generated, the application must explicitly + call if it changes the statement in any way. + Otherwise, the GetInsertCommand will be still be using information + from the previous statement, which might not be correct. The SQL statements + are first generated either when the application calls + or GetInsertCommand. + + + + + + + Gets the automatically generated object + required to perform updates on the database. + + + The object generated to handle update operations. + + + + An application can use the GetUpdateCommand method for informational + or troubleshooting purposes because it returns the + object to be executed. + + + You can also use GetUpdateCommand as the basis of a modified command. + For example, you might call GetUpdateCommand and modify the + value, and then explicitly set that on the + . + + + After the SQL statement is first generated, the application must explicitly + call if it changes the statement in any way. + Otherwise, the GetUpdateCommand will be still be using information + from the previous statement, which might not be correct. The SQL statements + are first generated either when the application calls + or GetUpdateCommand. + + + + + + + Refreshes the database schema information used to generate INSERT, UPDATE, or + DELETE statements. + + + + An application should call RefreshSchema whenever the SELECT statement + associated with the changes. + + + An application should call RefreshSchema whenever the + value of the changes. + + + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlConnection.xml b/Step.Database/docs/MySqlConnection.xml new file mode 100644 index 00000000..8fad39de --- /dev/null +++ b/Step.Database/docs/MySqlConnection.xml @@ -0,0 +1,1248 @@ + + + + Initializes a new instance of the class. + + + When a new instance of is created, the read/write + properties are set to the following initial values unless they are specifically + set using their associated keywords in the property. + + + + Properties + Initial Value + + + + + + empty string ("") + + + + + + 15 + + + + + + empty string ("") + + + + + + empty string ("") + + + + + + empty string ("") + + + + You can change the value for these properties only by using the ConnectionString property. + + + + + + Initializes a new instance of the class. + + + + + + + Initializes a new instance of the class when given a string containing the connection string. + + + When a new instance of is created, the read/write + properties are set to the following initial values unless they are specifically + set using their associated keywords in the property. + + + + Properties + Initial Value + + + + + + empty string ("") + + + + + + 15 + + + + + + empty string ("") + + + + + + empty string ("") + + + + + + empty string ("") + + + + You can change the value for these properties only by using the ConnectionString property. + + + + The connection properties used to open the MySQL database. + + + + Opens a database connection with the property settings specified by the ConnectionString. + Cannot open a connection without specifying a data source or server. + A connection-level error occurred while opening the connection. + + + The draws an open connection from the connection pool if one is available. + Otherwise, it establishes a new connection to an instance of MySQL. + + + + The following example creates a , opens it, + displays some of its properties, then closes the connection. + + + Public Sub CreateMySqlConnection(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + MessageBox.Show("ServerVersion: " + myConnection.ServerVersion _ + + ControlChars.Cr + "State: " + myConnection.State.ToString()) + myConnection.Close() + End Sub + + + public void CreateMySqlConnection(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + MessageBox.Show("ServerVersion: " + myConnection.ServerVersion + + "\nState: " + myConnection.State.ToString()); + myConnection.Close(); + } + + + + + + Gets the name of the current database or the database to be used after a connection is opened. + The name of the current database or the name of the database to be used after a connection is opened. The default value is an empty string. + + + The Database property does not update dynamically. + If you change the current database using a SQL statement, then this property + may reflect the wrong value. If you change the current database using the + method, this property is updated to reflect the new database. + + + + The following example creates a and displays + some of its read-only properties. + + + Public Sub CreateMySqlConnection() + Dim myConnString As String = _ + "Persist Security Info=False;database=test;server=localhost;user id=joeuser;pwd=pass" + Dim myConnection As New MySqlConnection( myConnString ) + myConnection.Open() + MessageBox.Show( "Server Version: " + myConnection.ServerVersion _ + + ControlChars.NewLine + "Database: " + myConnection.Database ) + myConnection.ChangeDatabase( "test2" ) + MessageBox.Show( "ServerVersion: " + myConnection.ServerVersion _ + + ControlChars.NewLine + "Database: " + myConnection.Database ) + myConnection.Close() + End Sub + + + + public void CreateMySqlConnection() + { + string myConnString = + "Persist Security Info=False;database=test;server=localhost;user id=joeuser;pwd=pass"; + MySqlConnection myConnection = new MySqlConnection( myConnString ); + myConnection.Open(); + MessageBox.Show( "Server Version: " + myConnection.ServerVersion + + "\nDatabase: " + myConnection.Database ); + myConnection.ChangeDatabase( "test2" ); + MessageBox.Show( "ServerVersion: " + myConnection.ServerVersion + + "\nDatabase: " + myConnection.Database ); + myConnection.Close(); + } + + + + + + Gets the current state of the connection. + + A bitwise combination of the values. The default is Closed. + + + The allowed state changes are: + + + From Closed to Open, using the Open method of the connection object. + + + From Open to Closed, using either the Close method or the Dispose method of the connection object. + + + + + The following example creates a , opens it, + displays some of its properties, then closes the connection. + + + Public Sub CreateMySqlConnection(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + MessageBox.Show("ServerVersion: " + myConnection.ServerVersion _ + + ControlChars.Cr + "State: " + myConnection.State.ToString()) + myConnection.Close() + End Sub + + + public void CreateMySqlConnection(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + MessageBox.Show("ServerVersion: " + myConnection.ServerVersion + + "\nState: " + myConnection.State.ToString()); + myConnection.Close(); + } + + + + + + Gets a string containing the version of the MySQL server to which the client is connected. + The version of the instance of MySQL. + The connection is closed. + + The following example creates a , opens it, + displays some of its properties, then closes the connection. + + + Public Sub CreateMySqlConnection(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + MessageBox.Show("ServerVersion: " + myConnection.ServerVersion _ + + ControlChars.Cr + "State: " + myConnection.State.ToString()) + myConnection.Close() + End Sub + + + public void CreateMySqlConnection(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + MessageBox.Show("ServerVersion: " + myConnection.ServerVersion + + "\nState: " + myConnection.State.ToString()); + myConnection.Close(); + } + + + + + + Closes the connection to the database. This is the preferred method of closing any open connection. + + + The Close method rolls back any pending transactions. It then releases + the connection to the connection pool, or closes the connection if connection + pooling is disabled. + + + An application can call Close more than one time. No exception is + generated. + + + + The following example creates a , opens it, + displays some of its properties, then closes the connection. + + + Public Sub CreateMySqlConnection(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + MessageBox.Show("ServerVersion: " + myConnection.ServerVersion _ + + ControlChars.Cr + "State: " + myConnection.State.ToString()) + myConnection.Close() + End Sub + + + public void CreateMySqlConnection(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + MessageBox.Show("ServerVersion: " + myConnection.ServerVersion + + "\nState: " + myConnection.State.ToString()); + myConnection.Close(); + } + + + + + + + Creates and returns a object associated with the . + + + A object. + + + + + Begins a database transaction. + An object representing the new transaction. + Parallel transactions are not supported. + + This command is equivalent to the MySQL BEGIN TRANSACTION command. + + You must explicitly commit or roll back the transaction using the or + method. + + If you do not specify an isolation level, the default isolation level is used. To specify an isolation + level with the method, use the overload that takes the iso parameter. Also + note that any attempt to begin a transaction while a transaction is in progress will throw an exception on MySQL 4.1 and higher. + On MySQL 4.0, an exception will not be thrown because servers 4.0 and earlier did not report their transacation status. + + + + + The following example creates a and a + . It also demonstrates how to use the BeginTransaction, a + , and methods. + + Public Sub RunTransaction(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + + Dim myCommand As MySqlCommand = myConnection.CreateCommand() + Dim myTrans As MySqlTransaction + + ' Start a local transaction + myTrans = myConnection.BeginTransaction() + ' Must assign both transaction object and connection + ' to Command object for a pending local transaction + myCommand.Connection = myConnection + myCommand.Transaction = myTrans + + Try + myCommand.CommandText = "Insert into Test (id, desc) VALUES (100, 'Description')" + myCommand.ExecuteNonQuery() + myCommand.CommandText = "Insert into Test (id, desc) VALUES (101, 'Description')" + myCommand.ExecuteNonQuery() + myTrans.Commit() + Console.WriteLine("Both records are written to database.") + Catch e As Exception + Try + myTrans.Rollback() + Catch ex As MySqlException + If Not myTrans.Connection Is Nothing Then + Console.WriteLine("An exception of type " + ex.GetType().ToString() + _ + " was encountered while attempting to roll back the transaction.") + End If + End Try + + Console.WriteLine("An exception of type " + e.GetType().ToString() + _ + "was encountered while inserting the data.") + Console.WriteLine("Neither record was written to database.") + Finally + myConnection.Close() + End Try + End Sub + + + public void RunTransaction(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + + MySqlCommand myCommand = myConnection.CreateCommand(); + MySqlTransaction myTrans; + + // Start a local transaction + myTrans = myConnection.BeginTransaction(); + // Must assign both transaction object and connection + // to Command object for a pending local transaction + myCommand.Connection = myConnection; + myCommand.Transaction = myTrans; + + try + { + myCommand.CommandText = "insert into Test (id, desc) VALUES (100, 'Description')"; + myCommand.ExecuteNonQuery(); + myCommand.CommandText = "insert into Test (id, desc) VALUES (101, 'Description')"; + myCommand.ExecuteNonQuery(); + myTrans.Commit(); + Console.WriteLine("Both records are written to database."); + } + catch(Exception e) + { + try + { + myTrans.Rollback(); + } + catch (SqlException ex) + { + if (myTrans.Connection != null) + { + Console.WriteLine("An exception of type " + ex.GetType() + + " was encountered while attempting to roll back the transaction."); + } + } + + Console.WriteLine("An exception of type " + e.GetType() + + " was encountered while inserting the data."); + Console.WriteLine("Neither record was written to database."); + } + finally + { + myConnection.Close(); + } + } + + + + + + Begins a database transaction with the specified isolation level. + The isolation level under which the transaction should run. + An object representing the new transaction. + Parallel exceptions are not supported. + + This command is equivalent to the MySQL BEGIN TRANSACTION command. + + You must explicitly commit or roll back the transaction using the or + method. + + If you do not specify an isolation level, the default isolation level is used. To specify an isolation + level with the method, use the overload that takes the iso parameter. + Also note that any attempt to begin a transaction while a transaction is in progress will throw an exception on MySQL 4.1 and higher. + On MySQL 4.0, an exception will not be thrown because servers 4.0 and earlier did not report their transacation status. + + + + + The following example creates a and a + . It also demonstrates how to use the BeginTransaction, a + , and methods. + + Public Sub RunTransaction(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + + Dim myCommand As MySqlCommand = myConnection.CreateCommand() + Dim myTrans As MySqlTransaction + + ' Start a local transaction + myTrans = myConnection.BeginTransaction() + ' Must assign both transaction object and connection + ' to Command object for a pending local transaction + myCommand.Connection = myConnection + myCommand.Transaction = myTrans + + Try + myCommand.CommandText = "Insert into Test (id, desc) VALUES (100, 'Description')" + myCommand.ExecuteNonQuery() + myCommand.CommandText = "Insert into Test (id, desc) VALUES (101, 'Description')" + myCommand.ExecuteNonQuery() + myTrans.Commit() + Console.WriteLine("Both records are written to database.") + Catch e As Exception + Try + myTrans.Rollback() + Catch ex As MySqlException + If Not myTrans.Connection Is Nothing Then + Console.WriteLine("An exception of type " + ex.GetType().ToString() + _ + " was encountered while attempting to roll back the transaction.") + End If + End Try + + Console.WriteLine("An exception of type " + e.GetType().ToString() + _ + "was encountered while inserting the data.") + Console.WriteLine("Neither record was written to database.") + Finally + myConnection.Close() + End Try + End Sub + + + public void RunTransaction(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + + MySqlCommand myCommand = myConnection.CreateCommand(); + MySqlTransaction myTrans; + + // Start a local transaction + myTrans = myConnection.BeginTransaction(); + // Must assign both transaction object and connection + // to Command object for a pending local transaction + myCommand.Connection = myConnection; + myCommand.Transaction = myTrans; + + try + { + myCommand.CommandText = "insert into Test (id, desc) VALUES (100, 'Description')"; + myCommand.ExecuteNonQuery(); + myCommand.CommandText = "insert into Test (id, desc) VALUES (101, 'Description')"; + myCommand.ExecuteNonQuery(); + myTrans.Commit(); + Console.WriteLine("Both records are written to database."); + } + catch(Exception e) + { + try + { + myTrans.Rollback(); + } + catch (SqlException ex) + { + if (myTrans.Connection != null) + { + Console.WriteLine("An exception of type " + ex.GetType() + + " was encountered while attempting to roll back the transaction."); + } + } + + Console.WriteLine("An exception of type " + e.GetType() + + " was encountered while inserting the data."); + Console.WriteLine("Neither record was written to database."); + } + finally + { + myConnection.Close(); + } + } + + + + + + Changes the current database for an open MySqlConnection. + The name of the database to use. + + + The value supplied in the database parameter must be a valid database + name. The database parameter cannot contain a null value, an empty + string, or a string with only blank characters. + + + + When you are using connection pooling against MySQL, and you close + the connection, it is returned to the connection pool. The next time the + connection is retrieved from the pool, the reset connection request + executes before the user performs any operations. + + + The database name is not valid. + The connection is not open. + Cannot change the database. + + The following example creates a and displays + some of its read-only properties. + + + Public Sub CreateMySqlConnection() + Dim myConnString As String = _ + "Persist Security Info=False;database=test;server=localhost;user id=joeuser;pwd=pass" + Dim myConnection As New MySqlConnection( myConnString ) + myConnection.Open() + MessageBox.Show( "Server Version: " + myConnection.ServerVersion _ + + ControlChars.NewLine + "Database: " + myConnection.Database ) + myConnection.ChangeDatabase( "test2" ) + MessageBox.Show( "ServerVersion: " + myConnection.ServerVersion _ + + ControlChars.NewLine + "Database: " + myConnection.Database ) + myConnection.Close() + End Sub + + + + public void CreateMySqlConnection() + { + string myConnString = + "Persist Security Info=False;database=test;server=localhost;user id=joeuser;pwd=pass"; + MySqlConnection myConnection = new MySqlConnection( myConnString ); + myConnection.Open(); + MessageBox.Show( "Server Version: " + myConnection.ServerVersion + + "\nDatabase: " + myConnection.Database ); + myConnection.ChangeDatabase( "test2" ); + MessageBox.Show( "ServerVersion: " + myConnection.ServerVersion + + "\nDatabase: " + myConnection.Database ); + myConnection.Close(); + } + + + + + + Occurs when the state of the connection changes. + + + The StateChange event fires whenever the changes from + closed to opened, or from opened to closed. StateChange fires immediately + after the transitions. + + + + If an event handler throws an exception from within the StateChange + event, the exception propagates to the caller of the or + method. + + + + The StateChange event is not raised unless you explicitly call + Close or Dispose. + + + + Raised. + + + The event handler receives an argument of type + containing data related to this event. The following StateChangeEventArgs + properties provide information specific to this event. + + + + Property + Description + + + + + + + Gets the new state of the connection. The connection object will + be in the new state already when the event is fired. + + + + + + + Gets the original state of the connection. + + + + + + + + Occurs when MySQL returns warnings as a result of executing a command or query. + + + + + + + Represents an open connection to a MySQL Server database. This class cannot be inherited. + + + + A MySqlConnection object represents a session to a MySQL Server + data source. When you create an instance of MySqlConnection, all + properties are set to their initial values. For a list of these values, see the + MySqlConnection constructor. + + + + If the MySqlConnection goes out of scope, it is not closed. Therefore, + you must explicitly close the connection by calling + or . + + + + + The following example creates a and + a MySqlConnection. The MySqlConnection is opened and set as the + for the MySqlCommand. The example then calls + , and closes the connection. To accomplish this, the ExecuteNonQuery is + passed a connection string and a query string that is a SQL INSERT + statement. + + + Public Sub InsertRow(myConnectionString As String) + ' If the connection string is null, use a default. + If myConnectionString = "" Then + myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass" + End If + Dim myConnection As New MySqlConnection(myConnectionString) + Dim myInsertQuery As String = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)" + Dim myCommand As New MySqlCommand(myInsertQuery) + myCommand.Connection = myConnection + myConnection.Open() + myCommand.ExecuteNonQuery() + myCommand.Connection.Close() + End Sub + + + + + public void InsertRow(string myConnectionString) + { + // If the connection string is null, use a default. + if(myConnectionString == "") + { + myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass"; + } + MySqlConnection myConnection = new MySqlConnection(myConnectionString); + string myInsertQuery = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)"; + MySqlCommand myCommand = new MySqlCommand(myInsertQuery); + myCommand.Connection = myConnection; + myConnection.Open(); + myCommand.ExecuteNonQuery(); + myCommand.Connection.Close(); + } + + + + + + + + Gets the time to wait while trying to establish a connection before terminating the attempt and generating an error. + + The value set is less than 0. + + A value of 0 indicates no limit, and should be avoided in a + because an attempt to connect + will wait indefinitely. + + + The following example creates a MySqlConnection + and sets some of its properties in the connection string. + + Public Sub CreateSqlConnection() + Dim myConnection As New MySqlConnection() + myConnection.ConnectionString = "Persist Security Info=False;Username=user;Password=pass;database=test1;server=localhost;Connect Timeout=30" + myConnection.Open() + End Sub + + + public void CreateSqlConnection() + { + MySqlConnection myConnection = new MySqlConnection(); + myConnection.ConnectionString = "Persist Security Info=False;Username=user;Password=pass;database=test1;server=localhost;Connect Timeout=30"; + myConnection.Open(); + } + + + + + + + + Gets or sets the string used to connect to a MySQL Server database. + + + + The ConnectionString returned may not be exactly like what was originally + set but will be indentical in terms of keyword/value pairs. Security information + will not be included unless the Persist Security Info value is set to true. + + + You can use the ConnectionString property to connect to a database. + The following example illustrates a typical connection string. + + "Persist Security Info=False;database=MyDB;server=MySqlServer;user id=myUser;Password=myPass" + + The ConnectionString property can be set only when the connection is + closed. Many of the connection string values have corresponding read-only + properties. When the connection string is set, all of these properties are + updated, except when an error is detected. In this case, none of the properties + are updated. properties return only those settings contained in the + ConnectionString. + + + To connect to a local machine, specify "localhost" for the server. If you do not + specify a server, localhost is assumed. + + + Resetting the ConnectionString on a closed connection resets all + connection string values (and related properties) including the password. For + example, if you set a connection string that includes "Database= MyDb", and + then reset the connection string to "Data Source=myserver;User Id=myUser;Password=myPass", + the property is no longer set to MyDb. + + + The connection string is parsed immediately after being set. If errors in + syntax are found when parsing, a runtime exception, such as , + is generated. Other errors can be found only when an attempt is made to open the + connection. + + + The basic format of a connection string consists of a series of keyword/value + pairs separated by semicolons. The equal sign (=) connects each keyword and its + value. To include values that contain a semicolon, single-quote character, or + double-quote character, the value must be enclosed in double quotes. If the + value contains both a semicolon and a double-quote character, the value can be + enclosed in single quotes. The single quote is also useful if the value begins + with a double-quote character. Conversely, the double quote can be used if the + value begins with a single quote. If the value contains both single-quote and + double-quote characters, the quote character used to enclose the value must be + doubled each time it occurs within the value. + + + To include preceding or trailing spaces in the string value, the value must + be enclosed in either single quotes or double quotes. Any leading or trailing + spaces around integer, Boolean, or enumerated values are ignored, even if + enclosed in quotes. However, spaces within a string literal keyword or value are + preserved. Using .NET Framework version 1.1, single or double quotes may be used + within a connection string without using delimiters (for example, Data Source= + my'Server or Data Source= my"Server), unless a quote character is the first or + last character in the value. + + + To include an equal sign (=) in a keyword or value, it must be preceded by + another equal sign. For example, in the hypothetical connection string + + "key==word=value" + + the keyword is "key=word" and the value is "value". + + If a specific keyword in a keyword= value pair occurs multiple times in a + connection string, the last occurrence listed is used in the value set. + + Keywords are not case sensitive. + + The following table lists the valid names for keyword values within the + ConnectionString. + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDefaultDescription
+ Connect Timeout -or- Connection Timeout + 15 + The length of time (in seconds) to wait for a connection to the server before + terminating the attempt and generating an error. +
+ Host -or- Server -or- Data Source -or- + DataSource -or- Address -or- Addr -or- + Network Address + localhost + + The name or network address of the instance of MySQL to which to connect. Multiple hosts can be + specified separated by &. This can be useful where multiple MySQL servers are configured for replication + and you are not concerned about the precise server you are connecting to. No attempt is made by the provider to + synchronize writes to the database so care should be taken when using this option. + + + In Unix environment with Mono, this can be a fully qualified path to MySQL socket filename. With this configuration, the Unix socket will be used instead of TCP/IP socket. + Currently only a single socket name can be given so accessing MySQL in a replicated environment using Unix sockets is not currently supported. + +
Port3306 + The port MySQL is using to listen for connections. This value is ignored if the connection protocol + is anything but socket. +
Protocolsocket + Specifies the type of connection to make to the server.Values can be: + socket or tcp for a socket connection
+ pipe for a named pipe connection
+ unix for a Unix socket connection
+ memory to use MySQL shared memory +
+ CharSet -or Character Set + + Specifies the character set that should be used to encode all queries sent to the server. + Resultsets are still returned in the character set of the data returned. +
LoggingfalseWhen true, various pieces of information is output to any configured TraceListeners.
Allow Batchtrue + When true, multiple SQL statements can be sent with one command execution.

+ -Note-
+ Starting with MySQL 4.1.1, batch statements should be separated by the server-defined seperator character.
+ Commands sent to earlier versions of MySQL should be seperated with ';'. +
Encryptfalse + When true, SSL/TLS encryption is used for all data sent between the + client and server if the server has a certificate installed. Recognized values + are true, false, yes, and no. +
+ Initial Catalog -or- Database + mysqlThe name of the database to use intially
+ Password -or- pwd + The password for the MySQL account being used.
Persist Security Infofalse + When set to false or no (strongly recommended), security-sensitive + information, such as the password, is not returned as part of the connection if + the connection is open or has ever been in an open state. Resetting the + connection string resets all connection string values including the password. + Recognized values are true, false, yes, and no. +
+ User Id -or- Username -or- Uid -or- User name + The MySQL login account being used.
Shared Memory NameMYSQLThe name of the shared memory object to use for communication if the connection protocol is set to memory.
Allow Zero Datetimefalse + True to have MySqlDataReader.GetValue() return a MySqlDateTime for date or datetime columns that have illegal values. + False will cause a DateTime object to be returned for legal values and an exception will be thrown for illegal values. +
Convert Zero Datetimefalse + True to have MySqlDataReader.GetValue() and MySqlDataReader.GetDateTime() + return DateTime.MinValue for date or datetime columns that have illegal values. +
+ Pipe Name -or- Pipe + mysql + When set to the name of a named pipe, the MySqlConnection will attempt to connect to MySQL + on that named pipe.

This settings only applies to the Windows platform. +
+ Use Performance Monitor -or- UsePerformanceMonitor + false + Posts performance data that can be tracked using perfmon +
+ Procedure Cache Size + 25 + How many stored procedure definitions can be held in the cache +
+ Ignore Prepare + true + Instructs the provider to ignore any attempts to prepare commands. This option + was added to allow a user to disable prepared statements in an entire application + without modifying the code. A user might want to do this if errors or bugs are + encountered with MySQL prepared statements. +
Use Procedure Bodiestrue + Instructs the provider to attempt to call the procedure without first resolving the metadata. This + is useful in situations where the calling user does not have access to the mysql.proc table. To + use this mode, the parameters for the procedure must be added to the command in the same order + as they appear in the procedure definition and their types must be explicitly set. +
Auto Enlisttrue + Indicates whether the connection should automatically enlist in the current transaction, + if there is one. +
Respect Binary Flagstrue + Indicates whether the connection should respect all binary flags sent to the client + as part of column metadata. False will cause the connector to behave like + Connector/Net 5.0 and earlier. +
BlobAsUTF8IncludePatternnull + Pattern that should be used to indicate which blob columns should be treated as UTF-8. +
BlobAsUTF8ExcludePatternnull + Pattern that should be used to indicate which blob columns should not be treated as UTF-8. +
Default Command Timeout30 + The default timeout that new MySqlCommand objects will use unless changed. +
Allow User Variablesfalse + Should the provider expect user variables in the SQL. +
Interactive -or- Interactive Sessionfalse + Should this session be considered interactive? +
Functions Return Stringfalse + Set this option to true to force the return value of SQL functions to be string. +
Use Affected Rowsfalse + Set this option to true to cause the affected rows reported to reflect only the + rows that are actually changed. By default, the number of rows that are matched + is returned. +
+
+ + The following table lists the valid names for connection pooling values within + the ConnectionString. For more information about connection pooling, see + Connection Pooling for the MySql Data Provider. + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDefaultDescription
Connection Lifetime0 + When a connection is returned to the pool, its creation time is compared with + the current time, and the connection is destroyed if that time span (in seconds) + exceeds the value specified by Connection Lifetime. This is useful in + clustered configurations to force load balancing between a running server and a + server just brought online. + + A value of zero (0) causes pooled connections to have the maximum connection + timeout. + +
Max Pool Size100The maximum number of connections allowed in the pool.
Min Pool Size0The minimum number of connections allowed in the pool.
Poolingtrue + When true, the MySqlConnection object is drawn from the appropriate + pool, or if necessary, is created and added to the appropriate pool. Recognized + values are true, false, yes, and no. +
Connection Resetfalse + Specifies whether the database connection should be reset when being + drawn from the pool. Leaving this as false will yeild much faster + connection opens but the user should understand the side effects + of doing this such as temporary tables and user variables from the previous + session not being cleared out. +
Cache Server Propertiesfalse + Specifies whether the server variables are cached between pooled connections. + On systems where the variables change infrequently and there are lots of + connection attempts, this can speed up things dramatically. +
+
+ + When setting keyword or connection pooling values that require a Boolean + value, you can use 'yes' instead of 'true', and 'no' instead of 'false'. + + + Note The MySql Data Provider uses the native socket protocol to + communicate with MySQL. Therefore, it does not support the use of an ODBC data source name (DSN) when + connecting to MySQL because it does not add an ODBC layer. + + + CAUTION In this release, the application should use caution when constructing a + connection string based on user input (for example when retrieving user ID and password information from a + dialog box, and appending it to the connection string). The application should + ensure that a user cannot embed extra connection string parameters in these + values (for example, entering a password as "validpassword;database=somedb" in + an attempt to attach to a different database). + +
+ + The following example creates a and sets some of its properties + + Public Sub CreateConnection() + Dim myConnection As New MySqlConnection() + myConnection.ConnectionString = "Persist Security Info=False;database=myDB;server=myHost;Connect Timeout=30;user id=myUser; pwd=myPass" + myConnection.Open() + End Sub 'CreateConnection + + + public void CreateConnection() + { + MySqlConnection myConnection = new MySqlConnection(); + myConnection.ConnectionString = "Persist Security Info=False;database=myDB;server=myHost;Connect Timeout=30;user id=myUser; pwd=myPass"; + myConnection.Open(); + } + + + + The following example creates a in Unix environment with Mono installed. MySQL socket filename used in this example is "/var/lib/mysql/mysql.sock". The actual filename depends on your MySQL configuration. + + Public Sub CreateConnection() + Dim myConnection As New MySqlConnection() + myConnection.ConnectionString = "database=myDB;server=/var/lib/mysql/mysql.sock;user id=myUser; pwd=myPass" + myConnection.Open() + End Sub 'CreateConnection + + + public void CreateConnection() + { + MySqlConnection myConnection = new MySqlConnection(); + myConnection.ConnectionString = "database=myDB;server=/var/lib/mysql/mysql.sock;user id=myUser; pwd=myPass"; + myConnection.Open(); + } + + +
+ + Empties the connection pool associated with the specified connection. + + The associated with the pool to be cleared. + + + + ClearPool clears the connection pool that is associated with the connection. + If additional connections associated with connection are in use at the time of the call, + they are marked appropriately and are discarded (instead of being returned to the pool) + when Close is called on them. + + + + + + Clears all connection pools. + + + ClearAllPools essentially performs a on all current connection + pools. + + + + +
diff --git a/Step.Database/docs/MySqlConnectionStringBuilder.xml b/Step.Database/docs/MySqlConnectionStringBuilder.xml new file mode 100644 index 00000000..bbfab116 --- /dev/null +++ b/Step.Database/docs/MySqlConnectionStringBuilder.xml @@ -0,0 +1,55 @@ + + + + Gets or sets the name or address of the MySQL instance to connect to. + + + If this property is not set, then the provider will attempt to + connect to localhost even though this property will return + String.Empty. + + + + + + + + Gets or sets the name of the database that should be selected + when the connection is first opened. + + + There is no default for this property and, if not set, the + connection will not have a current database until one is set + using the method. + + + + + + + + Gets or sets the connection protocol that is being used for this + connection. + + + + + + + + + + + Gets or sets the name of the named pipe object that the provider + should use. + + + This property has no effect unless the + property has been set to NamedPipe. + + + + + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlDataAdapter.xml b/Step.Database/docs/MySqlDataAdapter.xml new file mode 100644 index 00000000..03f9d787 --- /dev/null +++ b/Step.Database/docs/MySqlDataAdapter.xml @@ -0,0 +1,801 @@ + + + + Represents a set of data commands and a database connection that are used to fill a dataset and update a MySQL database. This class cannot be inherited. + + + + The MySQLDataAdapter, serves as a bridge between a + and MySQL for retrieving and saving data. The MySQLDataAdapter provides this + bridge by mapping , which changes the data in the + DataSet to match the data in the data source, and , + which changes the data in the data source to match the data in the DataSet, + using the appropriate SQL statements against the data source. + + + When the MySQLDataAdapter fills a DataSet, it will create the necessary + tables and columns for the returned data if they do not already exist. However, primary + key information will not be included in the implicitly created schema unless the + property is set to . + You may also have the MySQLDataAdapter create the schema of the DataSet, + including primary key information, before filling it with data using . + + + MySQLDataAdapter is used in conjunction with + and to increase performance when connecting to a MySQL database. + + + The MySQLDataAdapter also includes the , + , , + , and + properties to facilitate the loading and updating of data. + + + When an instance of MySQLDataAdapter is created, the read/write properties + are set to initial values. For a list of these values, see the MySQLDataAdapter + constructor. + + + Please be aware that the class allows only + Int16, Int32, and Int64 to have the AutoIncrement property set. + If you plan to use autoincremement columns with MySQL, you should consider + using signed integer columns. + + + + + The following example creates a and a . + The MySqlConnection is opened and set as the for the + MySqlCommand. The example then calls , and closes + the connection. To accomplish this, the ExecuteNonQuery is + passed a connection string and a query string that is a SQL INSERT + statement. + + Public Function SelectRows(dataSet As DataSet, connection As String, query As String) As DataSet + Dim conn As New MySqlConnection(connection) + Dim adapter As New MySqlDataAdapter() + adapter.SelectCommand = new MySqlCommand(query, conn) + adapter.Fill(dataset) + Return dataset + End Function + + + public DataSet SelectRows(DataSet dataset,string connection,string query) + { + MySqlConnection conn = new MySqlConnection(connection); + MySqlDataAdapter adapter = new MySqlDataAdapter(); + adapter.SelectCommand = new MySqlCommand(query, conn); + adapter.Fill(dataset); + return dataset; + } + + + + + + + + Initializes a new instance of the MySqlDataAdapter class. + + + + When an instance of is created, + the following read/write properties are set to the following initial + values. + + + + Properties + Initial Value + + + + + + + MissingMappingAction.Passthrough + + + + + + + + MissingSchemaAction.Add + + + + + You can change the value of any of these properties through a separate call + to the property. + + + + The following example creates a and sets some of + its properties. + + Public Sub CreateSqlDataAdapter() + Dim conn As MySqlConnection = New MySqlConnection("Data Source=localhost;" & _ + "database=test") + Dim da As MySqlDataAdapter = New MySqlDataAdapter + da.MissingSchemaAction = MissingSchemaAction.AddWithKey + + da.SelectCommand = New MySqlCommand("SELECT id, name FROM mytable", conn) + da.InsertCommand = New MySqlCommand("INSERT INTO mytable (id, name) " & _ + "VALUES (@id, @name)", conn) + da.UpdateCommand = New MySqlCommand("UPDATE mytable SET id=@id, name=@name " & _ + "WHERE id=@oldId", conn) + da.DeleteCommand = New MySqlCommand("DELETE FROM mytable WHERE id=@id", conn) + + da.InsertCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + da.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name") + + da.UpdateCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + da.UpdateCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name") + da.UpdateCommand.Parameters.Add("@oldId", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original + + da.DeleteCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original + End Sub + + + public static void CreateSqlDataAdapter() + { + MySqlConnection conn = new MySqlConnection("Data Source=localhost;database=test"); + MySqlDataAdapter da = new MySqlDataAdapter(); + da.MissingSchemaAction = MissingSchemaAction.AddWithKey; + + da.SelectCommand = new MySqlCommand("SELECT id, name FROM mytable", conn); + da.InsertCommand = new MySqlCommand("INSERT INTO mytable (id, name) " + + "VALUES (@id, @name)", conn); + da.UpdateCommand = new MySqlCommand("UPDATE mytable SET id=@id, name=@name " + + "WHERE id=@oldId", conn); + da.DeleteCommand = new MySqlCommand("DELETE FROM mytable WHERE id=@id", conn); + + da.InsertCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + da.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name"); + + da.UpdateCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + da.UpdateCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name"); + da.UpdateCommand.Parameters.Add("@oldId", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original; + + da.DeleteCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original; + } + + + + + + + Initializes a new instance of the class with + the specified as the + property. + + + that is a SQL SELECT statement or stored procedure and is set + as the property of the . + + + + When an instance of is created, + the following read/write properties are set to the following initial + values. + + + + Properties + Initial Value + + + + + + + MissingMappingAction.Passthrough + + + + + + + + MissingSchemaAction.Add + + + + + You can change the value of any of these properties through a separate call + to the property. + + + When SelectCommand (or any of the other command properties) is assigned + to a previously created , the MySqlCommand is not cloned. + The SelectCommand maintains a reference to the previously created MySqlCommand + object. + + + + The following example creates a and sets some of + its properties. + + Public Sub CreateSqlDataAdapter() + Dim conn As MySqlConnection = New MySqlConnection("Data Source=localhost;" & _ + "database=test") + Dim cmd as new MySqlCommand("SELECT id, name FROM mytable", conn) + Dim da As MySqlDataAdapter = New MySqlDataAdapter(cmd) + da.MissingSchemaAction = MissingSchemaAction.AddWithKey + + da.InsertCommand = New MySqlCommand("INSERT INTO mytable (id, name) " & _ + "VALUES (@id, @name)", conn) + da.UpdateCommand = New MySqlCommand("UPDATE mytable SET id=@id, name=@name " & _ + "WHERE id=@oldId", conn) + da.DeleteCommand = New MySqlCommand("DELETE FROM mytable WHERE id=@id", conn) + + da.InsertCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + da.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name") + + da.UpdateCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + da.UpdateCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name") + da.UpdateCommand.Parameters.Add("@oldId", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original + + da.DeleteCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original + End Sub + + + public static void CreateSqlDataAdapter() + { + MySqlConnection conn = new MySqlConnection("Data Source=localhost;database=test"); + MySqlCommand cmd = new MySqlCommand("SELECT id, name FROM mytable", conn); + MySqlDataAdapter da = new MySqlDataAdapter(cmd); + da.MissingSchemaAction = MissingSchemaAction.AddWithKey; + + da.InsertCommand = new MySqlCommand("INSERT INTO mytable (id, name) " + + "VALUES (@id, @name)", conn); + da.UpdateCommand = new MySqlCommand("UPDATE mytable SET id=@id, name=@name " + + "WHERE id=@oldId", conn); + da.DeleteCommand = new MySqlCommand("DELETE FROM mytable WHERE id=@id", conn); + + da.InsertCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + da.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name"); + + da.UpdateCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + da.UpdateCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name"); + da.UpdateCommand.Parameters.Add("@oldId", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original; + + da.DeleteCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original; + } + + + + + + + Initializes a new instance of the class with + a and a object. + + + A String that is a SQL SELECT statement or stored procedure to be used by + the property of the . + + + A that represents the connection. + + + + This implementation of the opens and closes a + if it is not already open. This can be useful in a an application that must call the + method for two or more MySqlDataAdapter objects. + If the MySqlConnection is already open, you must explicitly call + or to close it. + + + When an instance of is created, + the following read/write properties are set to the following initial + values. + + + + Properties + Initial Value + + + + + + + MissingMappingAction.Passthrough + + + + + + + + MissingSchemaAction.Add + + + + + You can change the value of any of these properties through a separate call + to the property. + + + + The following example creates a and sets some of + its properties. + + Public Sub CreateSqlDataAdapter() + Dim conn As MySqlConnection = New MySqlConnection("Data Source=localhost;" & _ + "database=test") + Dim da As MySqlDataAdapter = New MySqlDataAdapter("SELECT id, name FROM mytable", conn) + da.MissingSchemaAction = MissingSchemaAction.AddWithKey + + da.InsertCommand = New MySqlCommand("INSERT INTO mytable (id, name) " & _ + "VALUES (@id, @name)", conn) + da.UpdateCommand = New MySqlCommand("UPDATE mytable SET id=@id, name=@name " & _ + "WHERE id=@oldId", conn) + da.DeleteCommand = New MySqlCommand("DELETE FROM mytable WHERE id=@id", conn) + + da.InsertCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + da.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name") + + da.UpdateCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + da.UpdateCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name") + da.UpdateCommand.Parameters.Add("@oldId", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original + + da.DeleteCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original + End Sub + + + public static void CreateSqlDataAdapter() + { + MySqlConnection conn = new MySqlConnection("Data Source=localhost;database=test"); + MySqlDataAdapter da = new MySqlDataAdapter("SELECT id, name FROM mytable", conn); + da.MissingSchemaAction = MissingSchemaAction.AddWithKey; + + da.InsertCommand = new MySqlCommand("INSERT INTO mytable (id, name) " + + "VALUES (@id, @name)", conn); + da.UpdateCommand = new MySqlCommand("UPDATE mytable SET id=@id, name=@name " + + "WHERE id=@oldId", conn); + da.DeleteCommand = new MySqlCommand("DELETE FROM mytable WHERE id=@id", conn); + + da.InsertCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + da.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name"); + + da.UpdateCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + da.UpdateCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name"); + da.UpdateCommand.Parameters.Add("@oldId", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original; + + da.DeleteCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original; + } + + + + + + + Initializes a new instance of the class with + a and a connection string. + + + A that is a SQL SELECT statement or stored procedure to + be used by the property of the . + + The connection string + + + When an instance of is created, + the following read/write properties are set to the following initial + values. + + + + Properties + Initial Value + + + + + + + MissingMappingAction.Passthrough + + + + + + + + MissingSchemaAction.Add + + + + + You can change the value of any of these properties through a separate call + to the property. + + + + The following example creates a and sets some of + its properties. + + Public Sub CreateSqlDataAdapter() + Dim da As MySqlDataAdapter = New MySqlDataAdapter("SELECT id, name FROM mytable", "Data Source=localhost;database=test") + Dim conn As MySqlConnection = da.SelectCommand.Connection + da.MissingSchemaAction = MissingSchemaAction.AddWithKey + + da.InsertCommand = New MySqlCommand("INSERT INTO mytable (id, name) " & _ + "VALUES (@id, @name)", conn) + da.UpdateCommand = New MySqlCommand("UPDATE mytable SET id=@id, name=@name " & _ + "WHERE id=@oldId", conn) + da.DeleteCommand = New MySqlCommand("DELETE FROM mytable WHERE id=@id", conn) + + da.InsertCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + da.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name") + + da.UpdateCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + da.UpdateCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name") + da.UpdateCommand.Parameters.Add("@oldId", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original + + da.DeleteCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original + End Sub + + + public static void CreateSqlDataAdapter() + { + MySqlDataAdapter da = new MySqlDataAdapter("SELECT id, name FROM mytable", "Data Source=localhost;database=test"); + MySqlConnection conn = da.SelectCommand.Connection; + da.MissingSchemaAction = MissingSchemaAction.AddWithKey; + + da.InsertCommand = new MySqlCommand("INSERT INTO mytable (id, name) " + + "VALUES (@id, @name)", conn); + da.UpdateCommand = new MySqlCommand("UPDATE mytable SET id=@id, name=@name " + + "WHERE id=@oldId", conn); + da.DeleteCommand = new MySqlCommand("DELETE FROM mytable WHERE id=@id", conn); + + da.InsertCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + da.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name"); + + da.UpdateCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + da.UpdateCommand.Parameters.Add("@name", MySqlDbType.VarChar, 40, "name"); + da.UpdateCommand.Parameters.Add("@oldId", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original; + + da.DeleteCommand.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id").SourceVersion = DataRowVersion.Original; + } + + + + + + + Gets or sets a SQL statement or stored procedure used to delete records from the data set. + + + A used during to delete records in the + database that correspond to deleted rows in the . + + + + During , if this property is not set and primary key information + is present in the , the DeleteCommand can be generated + automatically if you set the property and use the + . Then, any additional commands that you do not set are + generated by the MySqlCommandBuilder. This generation logic requires key column + information to be present in the DataSet. + + + When DeleteCommand is assigned to a previously created , + the MySqlCommand is not cloned. The DeleteCommand maintains a reference + to the previously created MySqlCommand object. + + + + The following example creates a and sets the + and DeleteCommand properties. It assumes you have already + created a object. + + Public Shared Function CreateCustomerAdapter(conn As MySqlConnection) As MySqlDataAdapter + + Dim da As MySqlDataAdapter = New MySqlDataAdapter() + Dim cmd As MySqlCommand + Dim parm As MySqlParameter + + ' Create the SelectCommand. + cmd = New MySqlCommand("SELECT * FROM mytable WHERE id=@id AND name=@name", conn) + + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15) + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15) + + da.SelectCommand = cmd + + ' Create the DeleteCommand. + cmd = New MySqlCommand("DELETE FROM mytable WHERE id=@id", conn) + + parm = cmd.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id") + parm.SourceVersion = DataRowVersion.Original + + da.DeleteCommand = cmd + + Return da + End Function + + + public static MySqlDataAdapter CreateCustomerAdapter(MySqlConnection conn) + { + MySqlDataAdapter da = new MySqlDataAdapter(); + MySqlCommand cmd; + MySqlParameter parm; + + // Create the SelectCommand. + cmd = new MySqlCommand("SELECT * FROM mytable WHERE id=@id AND name=@name", conn); + + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15); + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15); + + da.SelectCommand = cmd; + + // Create the DeleteCommand. + cmd = new MySqlCommand("DELETE FROM mytable WHERE id=@id", conn); + + parm = cmd.Parameters.Add("@id", MySqlDbType.VarChar, 5, "id"); + parm.SourceVersion = DataRowVersion.Original; + + da.DeleteCommand = cmd; + + return da; + } + + + + + + + Gets or sets a SQL statement or stored procedure used to insert records into the data set. + + + A used during to insert records into the + database that correspond to new rows in the . + + + + During , if this property is not set and primary key information + is present in the , the InsertCommand can be generated + automatically if you set the property and use the + . Then, any additional commands that you do not set are + generated by the MySqlCommandBuilder. This generation logic requires key column + information to be present in the DataSet. + + + When InsertCommand is assigned to a previously created , + the MySqlCommand is not cloned. The InsertCommand maintains a reference + to the previously created MySqlCommand object. + + + If execution of this command returns rows, these rows may be added to the DataSet + depending on how you set the property of the MySqlCommand object. + + + + The following example creates a and sets the + and InsertCommand properties. It assumes you have already + created a object. + + Public Shared Function CreateCustomerAdapter(conn As MySqlConnection) As MySqlDataAdapter + + Dim da As MySqlDataAdapter = New MySqlDataAdapter() + Dim cmd As MySqlCommand + Dim parm As MySqlParameter + + ' Create the SelectCommand. + cmd = New MySqlCommand("SELECT * FROM mytable WHERE id=@id AND name=@name", conn) + + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15) + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15) + + da.SelectCommand = cmd + + ' Create the InsertCommand. + cmd = New MySqlCommand("INSERT INTO mytable (id,name) VALUES (@id, @name)", conn) + + cmd.Parameters.Add( "@id", MySqlDbType.VarChar, 15, "id" ) + cmd.Parameters.Add( "@name", MySqlDbType.VarChar, 15, "name" ) + da.InsertCommand = cmd + + Return da + End Function + + + public static MySqlDataAdapter CreateCustomerAdapter(MySqlConnection conn) + { + MySqlDataAdapter da = new MySqlDataAdapter(); + MySqlCommand cmd; + MySqlParameter parm; + + // Create the SelectCommand. + cmd = new MySqlCommand("SELECT * FROM mytable WHERE id=@id AND name=@name", conn); + + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15); + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15); + + da.SelectCommand = cmd; + + // Create the InsertCommand. + cmd = new MySqlCommand("INSERT INTO mytable (id,name) VALUES (@id,@name)", conn); + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15, "id" ); + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15, "name" ); + + da.InsertCommand = cmd; + + return da; + } + + + + + + + Gets or sets a SQL statement or stored procedure used to updated records in the data source. + + + A used during to update records in the + database with data from the . + + + + During , if this property is not set and primary key information + is present in the , the UpdateCommand can be generated + automatically if you set the property and use the + . Then, any additional commands that you do not set are + generated by the MySqlCommandBuilder. This generation logic requires key column + information to be present in the DataSet. + + + When UpdateCommand is assigned to a previously created , + the MySqlCommand is not cloned. The UpdateCommand maintains a reference + to the previously created MySqlCommand object. + + + If execution of this command returns rows, these rows may be merged with the DataSet + depending on how you set the property of the MySqlCommand object. + + + + The following example creates a and sets the + and UpdateCommand properties. It assumes you have already + created a object. + + Public Shared Function CreateCustomerAdapter(conn As MySqlConnection) As MySqlDataAdapter + + Dim da As MySqlDataAdapter = New MySqlDataAdapter() + Dim cmd As MySqlCommand + Dim parm As MySqlParameter + + ' Create the SelectCommand. + cmd = New MySqlCommand("SELECT * FROM mytable WHERE id=@id AND name=@name", conn) + + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15) + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15) + + da.SelectCommand = cmd + + ' Create the UpdateCommand. + cmd = New MySqlCommand("UPDATE mytable SET id=@id, name=@name WHERE id=@oldId", conn) + + cmd.Parameters.Add( "@id", MySqlDbType.VarChar, 15, "id" ) + cmd.Parameters.Add( "@name", MySqlDbType.VarChar, 15, "name" ) + + parm = cmd.Parameters.Add("@oldId", MySqlDbType.VarChar, 15, "id") + parm.SourceVersion = DataRowVersion.Original + + da.UpdateCommand = cmd + + Return da + End Function + + + public static MySqlDataAdapter CreateCustomerAdapter(MySqlConnection conn) + { + MySqlDataAdapter da = new MySqlDataAdapter(); + MySqlCommand cmd; + MySqlParameter parm; + + // Create the SelectCommand. + cmd = new MySqlCommand("SELECT * FROM mytable WHERE id=@id AND name=@name", conn); + + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15); + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15); + + da.SelectCommand = cmd; + + // Create the UpdateCommand. + cmd = new MySqlCommand("UPDATE mytable SET id=@id, name=@name WHERE id=@oldId", conn); + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15, "id" ); + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15, "name" ); + + parm = cmd.Parameters.Add( "@oldId", MySqlDbType.VarChar, 15, "id" ); + parm.SourceVersion = DataRowVersion.Original; + + da.UpdateCommand = cmd; + + return da; + } + + + + + + + Gets or sets a SQL statement or stored procedure used to select records in the data source. + + + A used during to select records from the + database for placement in the . + + + + When SelectCommand is assigned to a previously created , + the MySqlCommand is not cloned. The SelectCommand maintains a reference to the + previously created MySqlCommand object. + + + If the SelectCommand does not return any rows, no tables are added to the + , and no exception is raised. + + + + The following example creates a and sets the + and InsertCommand properties. It assumes you have already + created a object. + + Public Shared Function CreateCustomerAdapter(conn As MySqlConnection) As MySqlDataAdapter + + Dim da As MySqlDataAdapter = New MySqlDataAdapter() + Dim cmd As MySqlCommand + Dim parm As MySqlParameter + + ' Create the SelectCommand. + cmd = New MySqlCommand("SELECT * FROM mytable WHERE id=@id AND name=@name", conn) + + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15) + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15) + + da.SelectCommand = cmd + + ' Create the InsertCommand. + cmd = New MySqlCommand("INSERT INTO mytable (id,name) VALUES (@id, @name)", conn) + + cmd.Parameters.Add( "@id", MySqlDbType.VarChar, 15, "id" ) + cmd.Parameters.Add( "@name", MySqlDbType.VarChar, 15, "name" ) + da.InsertCommand = cmd + + Return da + End Function + + + public static MySqlDataAdapter CreateCustomerAdapter(MySqlConnection conn) + { + MySqlDataAdapter da = new MySqlDataAdapter(); + MySqlCommand cmd; + MySqlParameter parm; + + // Create the SelectCommand. + cmd = new MySqlCommand("SELECT * FROM mytable WHERE id=@id AND name=@name", conn); + + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15); + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15); + + da.SelectCommand = cmd; + + // Create the InsertCommand. + cmd = new MySqlCommand("INSERT INTO mytable (id,name) VALUES (@id,@name)", conn); + cmd.Parameters.Add("@id", MySqlDbType.VarChar, 15, "id" ); + cmd.Parameters.Add("@name", MySqlDbType.VarChar, 15, "name" ); + + da.InsertCommand = cmd; + + return da; + } + + + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlDataReader.xml b/Step.Database/docs/MySqlDataReader.xml new file mode 100644 index 00000000..911723b2 --- /dev/null +++ b/Step.Database/docs/MySqlDataReader.xml @@ -0,0 +1,452 @@ + + + + Provides a means of reading a forward-only stream of rows from a MySQL database. This class cannot be inherited. + + + + To create a MySQLDataReader, you must call the + method of the object, rather than directly using a constructor. + + + While the MySqlDataReader is in use, the associated + is busy serving the MySqlDataReader, and no other operations can be performed + on the MySqlConnection other than closing it. This is the case until the + method of the MySqlDataReader is called. + + + and + are the only properties that you can call after the MySqlDataReader is + closed. Though the RecordsAffected property may be accessed at any time + while the MySqlDataReader exists, always call Close before returning + the value of RecordsAffected to ensure an accurate return value. + + + For optimal performance, MySqlDataReader avoids creating + unnecessary objects or making unnecessary copies of data. As a result, multiple calls + to methods such as return a reference to the + same object. Use caution if you are modifying the underlying value of the objects + returned by methods such as GetValue. + + + + + The following example creates a , + a , and a MySqlDataReader. The example reads through + the data, writing it out to the console. Finally, the example closes the MySqlDataReader, then the + MySqlConnection. + + Public Sub ReadMyData(myConnString As String) + Dim mySelectQuery As String = "SELECT OrderID, CustomerID FROM Orders" + Dim myConnection As New MySqlConnection(myConnString) + Dim myCommand As New MySqlCommand(mySelectQuery, myConnection) + myConnection.Open() + Dim myReader As MySqlDataReader + myReader = myCommand.ExecuteReader() + ' Always call Read before accessing data. + While myReader.Read() + Console.WriteLine((myReader.GetInt32(0) & ", " & myReader.GetString(1))) + End While + ' always call Close when done reading. + myReader.Close() + ' Close the connection when done with it. + myConnection.Close() + End Sub 'ReadMyData + + + public void ReadMyData(string myConnString) { + string mySelectQuery = "SELECT OrderID, CustomerID FROM Orders"; + MySqlConnection myConnection = new MySqlConnection(myConnString); + MySqlCommand myCommand = new MySqlCommand(mySelectQuery,myConnection); + myConnection.Open(); + MySqlDataReader myReader; + myReader = myCommand.ExecuteReader(); + // Always call Read before accessing data. + while (myReader.Read()) { + Console.WriteLine(myReader.GetInt32(0) + ", " + myReader.GetString(1)); + } + // always call Close when done reading. + myReader.Close(); + // Close the connection when done with it. + myConnection.Close(); + } + + + + + + + + GetBytes returns the number of available bytes in the field. In most + cases this is the exact length of the field. However, the number returned may be + less than the true length of the field if GetBytes has already been used + to obtain bytes from the field. This may be the case, for example, if the + is reading a large data structure into a buffer. + For more information, see the SequentialAccess setting for + . + + + If you pass a buffer that is a null reference (Nothing in Visual + Basic), GetBytes returns the length of the field in bytes. + + + No conversions are performed; therefore the data retrieved must already be a + byte array. + + + + + + + + Gets the value of the specified column as a object. + + + + No conversions are performed; therefore, the data retrieved must already be a Time value. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal or column name. + The value of the specified column. + + + + + Gets the value of the specified column as a object. + + + + No conversions are performed; therefore, the data retrieved must already be a DateTime object. + + + Call IsDBNull to check for null values before calling this method. + + + + MySql allows date columns to contain the value '0000-00-00' and datetime + columns to contain the value '0000-00-00 00:00:00'. The DateTime structure cannot contain + or represent these values. To read a datetime value from a column that might + contain zero values, use . + + + The behavior of reading a zero datetime column using this method is defined by the + ZeroDateTimeBehavior connection string option. For more information on this option, + please refer to . + + + + The zero-based column ordinal. + The value of the specified column. + + + + + Gets the value of the specified column as a object. + + + + No conversions are performed; therefore, the data retrieved must already be a DateTime object. + + + Call IsDBNull to check for null values before calling this method. + + + + MySql allows date columns to contain the value '0000-00-00' and datetime + columns to contain the value '0000-00-00 00:00:00'. The DateTime structure cannot contain + or represent these values. To read a datetime value from a column that might + contain zero values, use . + + + The behavior of reading a zero datetime column using this method is defined by the + ZeroDateTimeBehavior connection string option. For more information on this option, + please refer to . + + + + The column name. + The value of the specified column. + + + + + Gets the value of the specified column as a object. + + + + No conversions are performed; therefore, the data retrieved must already be a DateTime object. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal or column name. + The value of the specified column. + + + + + Gets the value of the specified column as a object. + + + + No conversions are performed; therefore, the data retrieved must already be a String object. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal. + The value of the specified column. + + + + + Gets the value of the specified column as a object. + + + + No conversions are performed; therefore, the data retrieved must already be a String object. + + + Call IsDBNull to check for null values before calling this method. + + + The column name. + The value of the specified column. + + + + + Gets the value of the specified column as a object. + + + + No conversions are performed; therefore, the data retrieved must already be a Decimal object. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal + The value of the specified column. + + + + + Gets the value of the specified column as a object. + + + + No conversions are performed; therefore, the data retrieved must already be a Decimal object. + + + Call IsDBNull to check for null values before calling this method. + + + The column name + The value of the specified column. + + + + Gets the value of the specified column as a double-precision floating point number. + + + No conversions are performed; therefore, the data retrieved must already be a Double object. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal. + The value of the specified column. + + + + Gets the value of the specified column as a double-precision floating point number. + + + No conversions are performed; therefore, the data retrieved must already be a Double object. + + + Call IsDBNull to check for null values before calling this method. + + + The column name + The value of the specified column. + + + + + Gets the value of the specified column as a single-precision floating point number. + + + + No conversions are performed; therefore, the data retrieved must already be a Float object. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal. + The value of the specified column. + + + + + Gets the value of the specified column as a single-precision floating point number. + + + + No conversions are performed; therefore, the data retrieved must already be a Float object. + + + Call IsDBNull to check for null values before calling this method. + + + The column name + The value of the specified column. + + + + Gets the value of the specified column as a globally-unique identifier (GUID). + The zero-based column ordinal. + The value of the specified column. + + + + Gets the value of the specified column as a globally-unique identifier (GUID). + The column name + The value of the specified column. + + + + Gets the value of the specified column as a 16-bit signed integer. + + + No conversions are performed; therefore, the data retrieved must already be a 16 bit integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal. + The value of the specified column. + + + + Gets the value of the specified column as a 16-bit signed integer. + + + No conversions are performed; threfore, the data retrieved must already be a 16 bit integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The column name + The value of the specified column. + + + + Gets the value of the specified column as a 32-bit signed integer. + + + No conversions are performed; therefore, the data retrieved must already be a 32 bit integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal. + The value of the specified column. + + + + Gets the value of the specified column as a 32-bit signed integer. + + + No conversions are performed; therefore, the data retrieved must already be a 32 bit integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The column name. + The value of the specified column. + + + + Gets the value of the specified column as a 64-bit signed integer. + + + No conversions are performed; therefore, the data retrieved must already be a 64 bit integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal. + The value of the specified column. + + + + Gets the value of the specified column as a 64-bit signed integer. + + + No conversions are performed; therefore, the data retrieved must already be a 64 bit integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The column name. + The value of the specified column. + + + + Gets the value of the specified column as a 16-bit unsigned integer. + + + No conversions are performed; therefore, the data retrieved must already be a 16 bit unsigned integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal or column name. + The value of the specified column. + + + + Gets the value of the specified column as a 32-bit unsigned integer. + + + No conversions are performed; therefore, the data retrieved must already be a 32 bit unsigned integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal or column name. + The value of the specified column. + + + + Gets the value of the specified column as a 64-bit unsigned integer. + + + No conversions are performed; therefore, the data retrieved must already be a 64 bit unsigned integer value. + + + Call IsDBNull to check for null values before calling this method. + + + The zero-based column ordinal or column name. + The value of the specified column. + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlException.xml b/Step.Database/docs/MySqlException.xml new file mode 100644 index 00000000..48308051 --- /dev/null +++ b/Step.Database/docs/MySqlException.xml @@ -0,0 +1,53 @@ + + + + + This class is created whenever the MySql Data Provider encounters an error generated from the server. + + + Any open connections are not automatically closed when an exception is thrown. If + the client application determines that the exception is fatal, it should close any open + objects or objects. + + + + + The following example generates a MySqlException due to a missing server, + and then displays the exception. + + + Public Sub ShowException() + Dim mySelectQuery As String = "SELECT column1 FROM table1" + Dim myConnection As New MySqlConnection ("Data Source=localhost;Database=Sample;") + Dim myCommand As New MySqlCommand(mySelectQuery, myConnection) + + Try + myCommand.Connection.Open() + Catch e As MySqlException + MessageBox.Show( e.Message ) + End Try + End Sub + + + public void ShowException() + { + string mySelectQuery = "SELECT column1 FROM table1"; + MySqlConnection myConnection = + new MySqlConnection("Data Source=localhost;Database=Sample;"); + MySqlCommand myCommand = new MySqlCommand(mySelectQuery,myConnection); + + try + { + myCommand.Connection.Open(); + } + catch (MySqlException e) + { + MessageBox.Show( e.Message ); + } + } + + + + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlHelper.xml b/Step.Database/docs/MySqlHelper.xml new file mode 100644 index 00000000..48308051 --- /dev/null +++ b/Step.Database/docs/MySqlHelper.xml @@ -0,0 +1,53 @@ + + + + + This class is created whenever the MySql Data Provider encounters an error generated from the server. + + + Any open connections are not automatically closed when an exception is thrown. If + the client application determines that the exception is fatal, it should close any open + objects or objects. + + + + + The following example generates a MySqlException due to a missing server, + and then displays the exception. + + + Public Sub ShowException() + Dim mySelectQuery As String = "SELECT column1 FROM table1" + Dim myConnection As New MySqlConnection ("Data Source=localhost;Database=Sample;") + Dim myCommand As New MySqlCommand(mySelectQuery, myConnection) + + Try + myCommand.Connection.Open() + Catch e As MySqlException + MessageBox.Show( e.Message ) + End Try + End Sub + + + public void ShowException() + { + string mySelectQuery = "SELECT column1 FROM table1"; + MySqlConnection myConnection = + new MySqlConnection("Data Source=localhost;Database=Sample;"); + MySqlCommand myCommand = new MySqlCommand(mySelectQuery,myConnection); + + try + { + myCommand.Connection.Open(); + } + catch (MySqlException e) + { + MessageBox.Show( e.Message ); + } + } + + + + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlParameter.xml b/Step.Database/docs/MySqlParameter.xml new file mode 100644 index 00000000..c3cc2639 --- /dev/null +++ b/Step.Database/docs/MySqlParameter.xml @@ -0,0 +1,45 @@ + + + + Parameter names are not case sensitive. + + + + The following example creates multiple instances of MySqlParameter through the + collection within the . + These parameters are used to select data from the data source and place the data + in the . This example assumes that a DataSet and a + MySqlDataAdapter have already been created with the appropriate schema, commands, + and connection. + + Public Sub AddSqlParameters() + ' ... + ' create myDataSet and myDataAdapter + ' ... + myDataAdapter.SelectCommand.Parameters.Add("@CategoryName", MySqlDbType.VarChar, 80).Value = "toasters" + myDataAdapter.SelectCommand.Parameters.Add("@SerialNum", MySqlDbType.Long).Value = 239 + + myDataAdapter.Fill(myDataSet) + End Sub 'AddSqlParameters + + + public void AddSqlParameters() + { + // ... + // create myDataSet and myDataAdapter + // ... + + myDataAdapter.SelectCommand.Parameters.Add("@CategoryName", MySqlDbType.VarChar, 80).Value = "toasters"; + myDataAdapter.SelectCommand.Parameters.Add("@SerialNum", MySqlDbType.Long).Value = 239; + myDataAdapter.Fill(myDataSet); + + } + + + + + + + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlParameterCollection.xml b/Step.Database/docs/MySqlParameterCollection.xml new file mode 100644 index 00000000..19c0ca59 --- /dev/null +++ b/Step.Database/docs/MySqlParameterCollection.xml @@ -0,0 +1,45 @@ + + + + The number of the parameters in the collection must be equal to the number of + parameter placeholders within the command text, or an exception will be generated. + + + + The following example creates multiple instances of + through the MySqlParameterCollection collection within the . + These parameters are used to select data within the data source and place the data in + the . This code assumes that a DataSet and a MySqlDataAdapter + have already been created with the appropriate schema, commands, and connection. + + Public Sub AddParameters() + ' ... + ' create myDataSet and myDataAdapter + ' ... + myDataAdapter.SelectCommand.Parameters.Add("@CategoryName", MySqlDbType.VarChar, 80).Value = "toasters" + myDataAdapter.SelectCommand.Parameters.Add("@SerialNum", MySqlDbType.Long).Value = 239 + + myDataAdapter.Fill(myDataSet) + End Sub 'AddSqlParameters + + + public void AddSqlParameters() + { + // ... + // create myDataSet and myDataAdapter + // ... + + myDataAdapter.SelectCommand.Parameters.Add("@CategoryName", MySqlDbType.VarChar, 80).Value = "toasters"; + myDataAdapter.SelectCommand.Parameters.Add("@SerialNum", MySqlDbType.Long).Value = 239; + myDataAdapter.Fill(myDataSet); + + } + + + + + + + + + \ No newline at end of file diff --git a/Step.Database/docs/MySqlTransaction.xml b/Step.Database/docs/MySqlTransaction.xml new file mode 100644 index 00000000..c6ed857a --- /dev/null +++ b/Step.Database/docs/MySqlTransaction.xml @@ -0,0 +1,329 @@ + + + + Represents a SQL transaction to be made in a MySQL database. This class cannot be inherited. + + + + The application creates a MySqlTransaction object by calling + on the object. All subsequent operations associated with the + transaction (for example, committing or aborting the transaction), are performed on the + MySqlTransaction object. + + + + The following example creates a and a MySqlTransaction. + It also demonstrates how to use the , + , and methods. + + Public Sub RunTransaction(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + + Dim myCommand As MySqlCommand = myConnection.CreateCommand() + Dim myTrans As MySqlTransaction + + ' Start a local transaction + myTrans = myConnection.BeginTransaction() + ' Must assign both transaction object and connection + ' to Command object for a pending local transaction + myCommand.Connection = myConnection + myCommand.Transaction = myTrans + + Try + myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')" + myCommand.ExecuteNonQuery() + myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')" + myCommand.ExecuteNonQuery() + myTrans.Commit() + Console.WriteLine("Both records are written to database.") + Catch e As Exception + Try + myTrans.Rollback() + Catch ex As MySqlException + If Not myTrans.Connection Is Nothing Then + Console.WriteLine("An exception of type " & ex.GetType().ToString() & _ + " was encountered while attempting to roll back the transaction.") + End If + End Try + + Console.WriteLine("An exception of type " & e.GetType().ToString() & _ + "was encountered while inserting the data.") + Console.WriteLine("Neither record was written to database.") + Finally + myConnection.Close() + End Try + End Sub 'RunTransaction + + + public void RunTransaction(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + + MySqlCommand myCommand = myConnection.CreateCommand(); + MySqlTransaction myTrans; + + // Start a local transaction + myTrans = myConnection.BeginTransaction(); + // Must assign both transaction object and connection + // to Command object for a pending local transaction + myCommand.Connection = myConnection; + myCommand.Transaction = myTrans; + + try + { + myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')"; + myCommand.ExecuteNonQuery(); + myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')"; + myCommand.ExecuteNonQuery(); + myTrans.Commit(); + Console.WriteLine("Both records are written to database."); + } + catch(Exception e) + { + try + { + myTrans.Rollback(); + } + catch (MySqlException ex) + { + if (myTrans.Connection != null) + { + Console.WriteLine("An exception of type " + ex.GetType() + + " was encountered while attempting to roll back the transaction."); + } + } + + Console.WriteLine("An exception of type " + e.GetType() + + " was encountered while inserting the data."); + Console.WriteLine("Neither record was written to database."); + } + finally + { + myConnection.Close(); + } + } + + + + + + + + + Rolls back a transaction from a pending state. + + + The Rollback method is equivalent to the MySQL statement ROLLBACK. + The transaction can only be rolled back from a pending state + (after BeginTransaction has been called, but before Commit is + called). + + + The following example creates a and a + . It also demonstrates how to use the + , , and Rollback + methods. + + Public Sub RunSqlTransaction(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + + Dim myCommand As MySqlCommand = myConnection.CreateCommand() + Dim myTrans As MySqlTransaction + + ' Start a local transaction + myTrans = myConnection.BeginTransaction() + + ' Must assign both transaction object and connection + ' to Command object for a pending local transaction + myCommand.Connection = myConnection + myCommand.Transaction = myTrans + + Try + myCommand.CommandText = "Insert into mytable (id, desc) VALUES (100, 'Description')" + myCommand.ExecuteNonQuery() + myCommand.CommandText = "Insert into mytable (id, desc) VALUES (101, 'Description')" + myCommand.ExecuteNonQuery() + myTrans.Commit() + Console.WriteLine("Success.") + Catch e As Exception + Try + myTrans.Rollback() + Catch ex As MySqlException + If Not myTrans.Connection Is Nothing Then + Console.WriteLine("An exception of type " & ex.GetType().ToString() & _ + " was encountered while attempting to roll back the transaction.") + End If + End Try + + Console.WriteLine("An exception of type " & e.GetType().ToString() & _ + "was encountered while inserting the data.") + Console.WriteLine("Neither record was written to database.") + Finally + myConnection.Close() + End Try + End Sub + + + public void RunSqlTransaction(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + + MySqlCommand myCommand = myConnection.CreateCommand(); + MySqlTransaction myTrans; + + // Start a local transaction + myTrans = myConnection.BeginTransaction(); + // Must assign both transaction object and connection + // to Command object for a pending local transaction + myCommand.Connection = myConnection; + myCommand.Transaction = myTrans; + + try + { + myCommand.CommandText = "Insert into mytable (id, desc) VALUES (100, 'Description')"; + myCommand.ExecuteNonQuery(); + myCommand.CommandText = "Insert into mytable (id, desc) VALUES (101, 'Description')"; + myCommand.ExecuteNonQuery(); + myTrans.Commit(); + Console.WriteLine("Both records are written to database."); + } + catch(Exception e) + { + try + { + myTrans.Rollback(); + } + catch (MySqlException ex) + { + if (myTrans.Connection != null) + { + Console.WriteLine("An exception of type " + ex.GetType() + + " was encountered while attempting to roll back the transaction."); + } + } + + Console.WriteLine("An exception of type " + e.GetType() + + " was encountered while inserting the data."); + Console.WriteLine("Neither record was written to database."); + } + finally + { + myConnection.Close(); + } + } + + + + + + + Commits the database transaction. + + + The Commit method is equivalent to the MySQL SQL statement + COMMIT. + + + The following example creates a and a + . It also demonstrates how to use the + , , and Rollback + methods. + + Public Sub RunSqlTransaction(myConnString As String) + Dim myConnection As New MySqlConnection(myConnString) + myConnection.Open() + + Dim myCommand As MySqlCommand = myConnection.CreateCommand() + Dim myTrans As MySqlTransaction + + ' Start a local transaction + myTrans = myConnection.BeginTransaction() + + ' Must assign both transaction object and connection + ' to Command object for a pending local transaction + myCommand.Connection = myConnection + myCommand.Transaction = myTrans + + Try + myCommand.CommandText = "Insert into mytable (id, desc) VALUES (100, 'Description')" + myCommand.ExecuteNonQuery() + myCommand.CommandText = "Insert into mytable (id, desc) VALUES (101, 'Description')" + myCommand.ExecuteNonQuery() + myTrans.Commit() + Console.WriteLine("Success.") + Catch e As Exception + Try + myTrans.Rollback() + Catch ex As MySqlException + If Not myTrans.Connection Is Nothing Then + Console.WriteLine("An exception of type " & ex.GetType().ToString() & _ + " was encountered while attempting to roll back the transaction.") + End If + End Try + + Console.WriteLine("An exception of type " & e.GetType().ToString() & _ + "was encountered while inserting the data.") + Console.WriteLine("Neither record was written to database.") + Finally + myConnection.Close() + End Try + End Sub + + + public void RunSqlTransaction(string myConnString) + { + MySqlConnection myConnection = new MySqlConnection(myConnString); + myConnection.Open(); + + MySqlCommand myCommand = myConnection.CreateCommand(); + MySqlTransaction myTrans; + + // Start a local transaction + myTrans = myConnection.BeginTransaction(); + // Must assign both transaction object and connection + // to Command object for a pending local transaction + myCommand.Connection = myConnection; + myCommand.Transaction = myTrans; + + try + { + myCommand.CommandText = "Insert into mytable (id, desc) VALUES (100, 'Description')"; + myCommand.ExecuteNonQuery(); + myCommand.CommandText = "Insert into mytable (id, desc) VALUES (101, 'Description')"; + myCommand.ExecuteNonQuery(); + myTrans.Commit(); + Console.WriteLine("Both records are written to database."); + } + catch(Exception e) + { + try + { + myTrans.Rollback(); + } + catch (MySqlException ex) + { + if (myTrans.Connection != null) + { + Console.WriteLine("An exception of type " + ex.GetType() + + " was encountered while attempting to roll back the transaction."); + } + } + + Console.WriteLine("An exception of type " + e.GetType() + + " was encountered while inserting the data."); + Console.WriteLine("Neither record was written to database."); + } + finally + { + myConnection.Close(); + } + } + + + + + \ No newline at end of file diff --git a/Step.Database/packages.config b/Step.Database/packages.config new file mode 100644 index 00000000..ff002506 --- /dev/null +++ b/Step.Database/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Step.Model/App.config b/Step.Model/App.config new file mode 100644 index 00000000..2dd636aa --- /dev/null +++ b/Step.Model/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/Step.Model/LoginViewModel.cs b/Step.Model/LoginViewModel.cs deleted file mode 100644 index 61c31442..00000000 --- a/Step.Model/LoginViewModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Step.Model -{ - public class LoginViewModel - { - public string Username { get; set; } - public string Password { get; set; } - - } -} diff --git a/Step.Model/LoginViewModel.cs.d.ts b/Step.Model/LoginViewModel.cs.d.ts deleted file mode 100644 index 1d395c40..00000000 --- a/Step.Model/LoginViewModel.cs.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module server { - interface loginViewModel { - username: string; - password: string; - } -} diff --git a/Step.Model/RoleModel.cs b/Step.Model/RoleModel.cs new file mode 100644 index 00000000..b17b88c9 --- /dev/null +++ b/Step.Model/RoleModel.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Step.Model +{ + [Table("roles")] + public class RoleModel + { + [Key] + [Column("id")] + public int RoleId { get; set; } + [Column("name")] + public string Name { get; set; } + [Column("level")] + public int Level { get; set; } + public List Users { get; set; } + } +} diff --git a/Step.Model/RoleModel.cs.d.ts b/Step.Model/RoleModel.cs.d.ts new file mode 100644 index 00000000..8082b3c7 --- /dev/null +++ b/Step.Model/RoleModel.cs.d.ts @@ -0,0 +1,8 @@ +declare module server { + interface roleModel { + roleId: number; + name: string; + level: number; + users: server.UserModel[]; + } +} diff --git a/Step.Model/Step.Model.csproj b/Step.Model/Step.Model.csproj index 3f8fb08a..2f3f59a4 100644 --- a/Step.Model/Step.Model.csproj +++ b/Step.Model/Step.Model.csproj @@ -30,7 +30,20 @@ 4 + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll + + + ..\packages\Microsoft.AspNet.Identity.EntityFramework.2.2.1\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll + + @@ -40,28 +53,32 @@ - + DtsGenerator - LoginViewModel.cs.d.ts - - - DtsGenerator - TestModel.cs.d.ts + RoleModel.cs.d.ts + + DtsGenerator + UserModel.cs.d.ts + - + True True - LoginViewModel.cs + RoleModel.cs - + True True - TestModel.cs + UserModel.cs + + + + XCOPY $(ProjectDir)*.d.ts $(SolutionDir)Step\wwwroot\src\@types /C /Y /O diff --git a/Step.Model/TestModel.cs b/Step.Model/TestModel.cs deleted file mode 100644 index 2b89fa93..00000000 --- a/Step.Model/TestModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Step.Model -{ - public class TestModel - { - - public int Id { get; set; } - - } -} diff --git a/Step.Model/TestModel.cs.d.ts b/Step.Model/TestModel.cs.d.ts deleted file mode 100644 index 0b823ff8..00000000 --- a/Step.Model/TestModel.cs.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module server { - interface testModel { - id: number; - } -} diff --git a/Step.Model/UserModel.cs b/Step.Model/UserModel.cs new file mode 100644 index 00000000..7848f4a1 --- /dev/null +++ b/Step.Model/UserModel.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Step.Model +{ + [Table("user")] + public class UserModel + { + [Key] + [Column("id")] + public int UserId { get; set; } + [Required] + [Column("username")] + public string Username { get; set; } + [Column("first_name")] + public string FirstName { get; set; } + [Column("last_name")] + public string LastName { get; set; } + [Column("password")] + public string Password { get; set; } + [Column("security_stamp")] + public string SecurityStamp { get; set; } + [Column("role_id")] + public int RoleId { get; set; } + [ForeignKey("RoleId")] + public RoleModel Role { get; set; } + } +} diff --git a/Step.Model/UserModel.cs.d.ts b/Step.Model/UserModel.cs.d.ts new file mode 100644 index 00000000..1a48fd35 --- /dev/null +++ b/Step.Model/UserModel.cs.d.ts @@ -0,0 +1,12 @@ +declare module server { + interface userModel { + userId: number; + username: string; + firstName: string; + lastName: string; + password: string; + securityStamp: string; + roleId: number; + role: server.RoleModel; + } +} diff --git a/Step.Model/packages.config b/Step.Model/packages.config new file mode 100644 index 00000000..847fed35 --- /dev/null +++ b/Step.Model/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Step.sln b/Step.sln index 0c4ffe7d..daa81b9e 100644 --- a/Step.sln +++ b/Step.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step.Model", "Step.Model\St EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step.UI", "Step.UI\Step.UI.csproj", "{20FC0937-E7CA-4693-95F9-7A948EFD173B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step.Database", "Step.Database\Step.Database.csproj", "{357D5EE1-FFC8-489B-9232-22CF474D9A6F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {20FC0937-E7CA-4693-95F9-7A948EFD173B}.Debug|Any CPU.Build.0 = Debug|Any CPU {20FC0937-E7CA-4693-95F9-7A948EFD173B}.Release|Any CPU.ActiveCfg = Release|Any CPU {20FC0937-E7CA-4693-95F9-7A948EFD173B}.Release|Any CPU.Build.0 = Release|Any CPU + {357D5EE1-FFC8-489B-9232-22CF474D9A6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {357D5EE1-FFC8-489B-9232-22CF474D9A6F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {357D5EE1-FFC8-489B-9232-22CF474D9A6F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {357D5EE1-FFC8-489B-9232-22CF474D9A6F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Step/App.config b/Step/App.config index a8115dc3..37004edd 100644 --- a/Step/App.config +++ b/Step/App.config @@ -46,9 +46,19 @@ + + + + + + + + - + + + diff --git a/Step/App_Start/Startup.cs b/Step/App_Start/Startup.cs index e1faa9ba..209fe53b 100644 --- a/Step/App_Start/Startup.cs +++ b/Step/App_Start/Startup.cs @@ -1,5 +1,4 @@ using System; -using System.Threading.Tasks; using Microsoft.Owin; using Owin; using System.Web.Http; @@ -8,41 +7,62 @@ using System.IO; using System.Reflection; using Microsoft.Owin.FileSystems; using System.Configuration; +using Microsoft.Owin.Security.OAuth; +using Step.Provider; [assembly: OwinStartup(typeof(Step.App_Start.Startup))] namespace Step.App_Start { - public class Startup - { - public void Configuration(IAppBuilder app) + public class Startup { - // Configurazione HTTP di avvio - HttpConfiguration config = new HttpConfiguration(); + public void Configuration(IAppBuilder app) + { + // Configure HTTP + HttpConfiguration config = new HttpConfiguration(); - // Registrazione delle Web API - WebApiConfig.Register(config); + // Register Web API config + WebApiConfig.Register(config); - // Registrazione di Swagger - SwaggerConfig.Register(config); + // Register Swagger config + SwaggerConfig.Register(config); - // Registrazione di SignalR - app.MapSignalR(); + // Configure authentication + ConfigureOAuth(app); - app.UseWebApi(config); + // Register SignalR + app.MapSignalR(); - var directoryBrowsing = ConfigurationManager.AppSettings["enableDirectoryBrowsing"] == "true"; + app.UseWebApi(config); - string rootDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", "wwwroot"); - var options = new FileServerOptions() - { - EnableDefaultFiles = !directoryBrowsing, - EnableDirectoryBrowsing = directoryBrowsing, - RequestPath = PathString.Empty, - FileSystem = new PhysicalFileSystem(rootDir) - }; + var directoryBrowsing = ConfigurationManager.AppSettings["enableDirectoryBrowsing"] == "true"; - app.UseFileServer(options); + string rootDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", "wwwroot"); + var options = new FileServerOptions() + { + EnableDefaultFiles = !directoryBrowsing, + EnableDirectoryBrowsing = directoryBrowsing, + RequestPath = PathString.Empty, + FileSystem = new PhysicalFileSystem(rootDir) + }; + + app.UseFileServer(options); + } + + private void ConfigureOAuth(IAppBuilder app) + { + OAuthAuthorizationServerOptions OAuthOptions = new OAuthAuthorizationServerOptions + { + TokenEndpointPath = new PathString("/Token"), + Provider = new ApplicationOAuthProvider(), + AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), + AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), + //TODO: In modalità di produzione impostare AllowInsecureHttp = false + AllowInsecureHttp = true + }; + + app.UseOAuthAuthorizationServer(OAuthOptions); + app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); + } } - } } diff --git a/Step/Controllers/DataController.cs b/Step/Controllers/DataController.cs deleted file mode 100644 index a0849357..00000000 --- a/Step/Controllers/DataController.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Step.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Web.Http; -using System.Web.Http.Description; - -namespace Step.Controllers -{ - - [RoutePrefix("api/data")] - public class DataController : ApiController - { - [ResponseType(typeof(TestModel))] - [Route(""), HttpGet] - public IHttpActionResult Test() - { - return Ok(new TestModel() { Id = 42 }); - } - } -} diff --git a/Step/Controllers/LoginController.cs b/Step/Controllers/LoginController.cs index c0b037b2..8cbf20eb 100644 --- a/Step/Controllers/LoginController.cs +++ b/Step/Controllers/LoginController.cs @@ -5,21 +5,25 @@ using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; +using Step.Database.Controllers; +using System.Web.Http.Controllers; +using System.Security.Claims; namespace Step.Controllers { - [RoutePrefix("api/login")] - public class LoginController : ApiController - { - - [Route(), HttpPost] - public IHttpActionResult DoLogin(LoginViewModel model) + [RoutePrefix("api/login")] + public class LoginController : ApiController { - if (model.Username == "utente" && model.Password == "finto") return Ok(); - return Unauthorized(); - + [Route(), HttpPost] + public IHttpActionResult DoLogin(UserModel model) + { + UsersController usersController = new UsersController(); + + usersController.Create(model.Username, "passwor", "nome","cognome", 1); + if (model.Username == "utente" && model.Password == "finto") return Ok(); + return Unauthorized(); + } } - } } diff --git a/Step/Provider/ApplicationOAuthProvider.cs b/Step/Provider/ApplicationOAuthProvider.cs new file mode 100644 index 00000000..ecf2fb6a --- /dev/null +++ b/Step/Provider/ApplicationOAuthProvider.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Owin.Security.OAuth; +using Step.Database.Controllers; +using Step.Model; +using System.Security.Claims; + +namespace Step.Provider +{ + public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider + { + public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) + { + context.Validated(); + } + + public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) + { + + context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); + + using (UsersController usersController = new UsersController()) + { + UserModel user = usersController.Find(context.UserName, context.Password); + + if (user == null) + { + context.SetError("invalid_grant", "The user name or password is incorrect."); + return; + } + + var identity = new ClaimsIdentity(context.Options.AuthenticationType); + identity.AddClaim(new Claim("username", user.Username)); + identity.AddClaim(new Claim("role", user.Role.Level.ToString())); + + context.Validated(identity); + } + } + } +} diff --git a/Step/Step.csproj b/Step/Step.csproj index e0bd496a..e250044b 100644 --- a/Step/Step.csproj +++ b/Step/Step.csproj @@ -74,6 +74,9 @@ ..\packages\Microsoft.Owin.Security.3.1.0\lib\net45\Microsoft.Owin.Security.dll + + ..\packages\Microsoft.Owin.Security.OAuth.3.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll + ..\packages\Microsoft.Owin.StaticFiles.3.1.0\lib\net45\Microsoft.Owin.StaticFiles.dll @@ -142,11 +145,11 @@ - + @@ -192,9 +195,7 @@ - - - + @@ -274,6 +275,10 @@ + + {357d5ee1-ffc8-489b-9232-22cf474d9a6f} + Step.Database + {631375dd-06d3-49bb-8130-d9ddb34c429d} Step.Model diff --git a/Step/packages.config b/Step/packages.config index 0cc97219..c5c0791d 100644 --- a/Step/packages.config +++ b/Step/packages.config @@ -17,11 +17,13 @@ + + diff --git a/Step/wwwroot/src/@types/RoleModel.cs.d.ts b/Step/wwwroot/src/@types/RoleModel.cs.d.ts new file mode 100644 index 00000000..8082b3c7 --- /dev/null +++ b/Step/wwwroot/src/@types/RoleModel.cs.d.ts @@ -0,0 +1,8 @@ +declare module server { + interface roleModel { + roleId: number; + name: string; + level: number; + users: server.UserModel[]; + } +} diff --git a/Step/wwwroot/src/@types/RolesModel.cs.d.ts b/Step/wwwroot/src/@types/RolesModel.cs.d.ts new file mode 100644 index 00000000..80d16fa7 --- /dev/null +++ b/Step/wwwroot/src/@types/RolesModel.cs.d.ts @@ -0,0 +1,7 @@ +declare module server { + interface rolesModel { + roleId: number; + name: string; + users: server.UserModel[]; + } +} diff --git a/Step/wwwroot/src/@types/UserModel.cs.d.ts b/Step/wwwroot/src/@types/UserModel.cs.d.ts new file mode 100644 index 00000000..1a48fd35 --- /dev/null +++ b/Step/wwwroot/src/@types/UserModel.cs.d.ts @@ -0,0 +1,12 @@ +declare module server { + interface userModel { + userId: number; + username: string; + firstName: string; + lastName: string; + password: string; + securityStamp: string; + roleId: number; + role: server.RoleModel; + } +} From 9b6b3194e4708eea70b49576996e1acfd4e08e0d Mon Sep 17 00:00:00 2001 From: "CMS4390\\marantalu" Date: Thu, 23 Nov 2017 16:56:17 +0100 Subject: [PATCH 3/4] Project refactor and added comments --- Step.UI/ServerControlWindow.Designer.cs | 99 ++++++++--------- Step.UI/ServerControlWindow.cs | 123 +++++++++++----------- Step/App_Start/Startup.cs | 8 +- Step/App_Start/WebApiConfig.cs | 2 - Step/CmsAuthorizationAttribute.cs | 19 ++++ Step/Controllers/LoginController.cs | 14 +-- Step/Provider/ApplicationOAuthProvider.cs | 12 +-- Step/program.cs | 47 ++++----- 8 files changed, 172 insertions(+), 152 deletions(-) create mode 100644 Step/CmsAuthorizationAttribute.cs diff --git a/Step.UI/ServerControlWindow.Designer.cs b/Step.UI/ServerControlWindow.Designer.cs index 347d8fda..36164a60 100644 --- a/Step.UI/ServerControlWindow.Designer.cs +++ b/Step.UI/ServerControlWindow.Designer.cs @@ -28,59 +28,62 @@ /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ServerControlWindow)); - this.button1 = new System.Windows.Forms.Button(); - this.button2 = new System.Windows.Forms.Button(); - this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); - this.SuspendLayout(); - // - // button1 - // - this.button1.Location = new System.Drawing.Point(12, 12); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(177, 69); - this.button1.TabIndex = 0; - this.button1.Text = "Server Stop"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.button1_Click); - // - // button2 - // - this.button2.Location = new System.Drawing.Point(211, 12); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(177, 69); - this.button2.TabIndex = 1; - this.button2.Text = "Open UI"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.button2_Click); - // - // notifyIcon1 - // - this.notifyIcon1.BalloonTipText = "CMS"; - this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon"))); - this.notifyIcon1.Text = "CMS Server"; - this.notifyIcon1.Visible = true; - this.notifyIcon1.Click += new System.EventHandler(this.notifyIcon1_Click); - // - // ServerControlWindow - // - this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 24F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(400, 93); - this.Controls.Add(this.button2); - this.Controls.Add(this.button1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; - this.Name = "ServerControlWindow"; - this.Text = "Step"; - this.ResumeLayout(false); + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ServerControlWindow)); + this.stopServerButton = new System.Windows.Forms.Button(); + this.openUiButton = new System.Windows.Forms.Button(); + this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); + this.SuspendLayout(); + // + // stopServerButton + // + this.stopServerButton.Location = new System.Drawing.Point(7, 7); + this.stopServerButton.Margin = new System.Windows.Forms.Padding(2); + this.stopServerButton.Name = "stopServerButton"; + this.stopServerButton.Size = new System.Drawing.Size(97, 37); + this.stopServerButton.TabIndex = 0; + this.stopServerButton.Text = "Server Stop"; + this.stopServerButton.UseVisualStyleBackColor = true; + this.stopServerButton.Click += new System.EventHandler(this.StopServerButton_Click); + // + // openUiButton + // + this.openUiButton.Location = new System.Drawing.Point(115, 7); + this.openUiButton.Margin = new System.Windows.Forms.Padding(2); + this.openUiButton.Name = "openUiButton"; + this.openUiButton.Size = new System.Drawing.Size(97, 37); + this.openUiButton.TabIndex = 1; + this.openUiButton.Text = "Open UI"; + this.openUiButton.UseVisualStyleBackColor = true; + this.openUiButton.Click += new System.EventHandler(this.OpenUiButton_Click); + // + // notifyIcon1 + // + this.notifyIcon1.BalloonTipText = "CMS"; + this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon"))); + this.notifyIcon1.Text = "CMS Server"; + this.notifyIcon1.Visible = true; + this.notifyIcon1.Click += new System.EventHandler(this.notifyIcon1_Click); + // + // ServerControlWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(218, 50); + this.Controls.Add(this.openUiButton); + this.Controls.Add(this.stopServerButton); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "ServerControlWindow"; + this.Text = "Step"; + this.ResumeLayout(false); } #endregion - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button stopServerButton; + private System.Windows.Forms.Button openUiButton; private System.Windows.Forms.NotifyIcon notifyIcon1; } } \ No newline at end of file diff --git a/Step.UI/ServerControlWindow.cs b/Step.UI/ServerControlWindow.cs index b84ba46e..a499c720 100644 --- a/Step.UI/ServerControlWindow.cs +++ b/Step.UI/ServerControlWindow.cs @@ -14,68 +14,69 @@ using TeamDev.SDK.MVVM; namespace Step.UI { - public partial class ServerControlWindow : Form - { - public ServerControlWindow() + public partial class ServerControlWindow : Form { - InitializeComponent(); - } - - private static ServerControlWindow ctrlwindow = null; - - public static void Start() - { - Thread th = new Thread(() => - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - ctrlwindow = new ServerControlWindow(); - Application.Run(ctrlwindow); - }); - - th.SetApartmentState(ApartmentState.STA); - th.Start(); - } - - public static void Stop() - { - if (ctrlwindow != null) - { - ctrlwindow.Invoke((ThreadStart)delegate () + public ServerControlWindow() { - ctrlwindow._closing = true; - ctrlwindow.Close(); - ctrlwindow = null; - }); - } + InitializeComponent(); + } + + private static ServerControlWindow ctrlwindow = null; + + public static void Start() + { // Open WinForm + Thread th = new Thread(() => + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + ctrlwindow = new ServerControlWindow(); + Application.Run(ctrlwindow); + }); + + th.SetApartmentState(ApartmentState.STA); + th.Start(); + } + + public static void Stop() + { // Close WinForm + if (ctrlwindow != null) + { + ctrlwindow.Invoke((ThreadStart)delegate () + { + ctrlwindow._closing = true; + ctrlwindow.Close(); + ctrlwindow = null; + }); + } + } + + + private bool _closing = false; + + // Avoid closing the window + protected override void OnClosing(CancelEventArgs e) + { + if (!_closing) + { + e.Cancel = true; + this.Hide(); + } + } + + private void OpenUiButton_Click(object sender, EventArgs e) + { + Process.Start("http://localhost:9000/index.html"); + } + + private void StopServerButton_Click(object sender, EventArgs e) + { + // Send message to listeners and close server + MessageServices.Current.Publish("StopServer"); + } + + private void notifyIcon1_Click(object sender, EventArgs e) + { + this.Show(); + } } - - - private bool _closing = false; - - // Evito di chiudere la finestra - protected override void OnClosing(CancelEventArgs e) - { - if (!_closing) - { - e.Cancel = true; - this.Hide(); - } - } - - private void button2_Click(object sender, EventArgs e) - { - Process.Start("http://localhost:9000"); - } - - private void button1_Click(object sender, EventArgs e) - { - MessageServices.Current.Publish("StopServer"); - } - - private void notifyIcon1_Click(object sender, EventArgs e) - { - this.Show(); - } - } } diff --git a/Step/App_Start/Startup.cs b/Step/App_Start/Startup.cs index 209fe53b..be59a553 100644 --- a/Step/App_Start/Startup.cs +++ b/Step/App_Start/Startup.cs @@ -51,17 +51,19 @@ namespace Step.App_Start private void ConfigureOAuth(IAppBuilder app) { - OAuthAuthorizationServerOptions OAuthOptions = new OAuthAuthorizationServerOptions + OAuthAuthorizationServerOptions OAuthOptions = new OAuthAuthorizationServerOptions { + // Login and Token generation end point TokenEndpointPath = new PathString("/Token"), Provider = new ApplicationOAuthProvider(), - AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), + // Bearer token expiration time AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), //TODO: In modalità di produzione impostare AllowInsecureHttp = false AllowInsecureHttp = true }; - + // Set authorization options app.UseOAuthAuthorizationServer(OAuthOptions); + // Set bearer oAuth as authentication method app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); } } diff --git a/Step/App_Start/WebApiConfig.cs b/Step/App_Start/WebApiConfig.cs index 5024b3ef..d8b54148 100644 --- a/Step/App_Start/WebApiConfig.cs +++ b/Step/App_Start/WebApiConfig.cs @@ -11,8 +11,6 @@ namespace Step public static void Register(HttpConfiguration config) { // Web API configuration and services - - var form = config.Formatters.FormUrlEncodedFormatter; var xml = config.Formatters.XmlFormatter; var json = config.Formatters.JsonFormatter; diff --git a/Step/CmsAuthorizationAttribute.cs b/Step/CmsAuthorizationAttribute.cs new file mode 100644 index 00000000..353d1b6a --- /dev/null +++ b/Step/CmsAuthorizationAttribute.cs @@ -0,0 +1,19 @@ +using System.Linq; +using System.Security.Claims; +using System.Web.Http; +using System.Web.Http.Controllers; + +namespace Step +{ + class CmsAuthorizationAttribute : AuthorizeAttribute + { + public string Category; + public string Action; + protected override bool IsAuthorized(HttpActionContext actionContext) + { + ClaimsPrincipal principal = actionContext.RequestContext.Principal as ClaimsPrincipal; + var customClaimValue = principal.Claims.Where(c => c.Type == "role").Single().Value; + return base.IsAuthorized(actionContext); + } + } +} diff --git a/Step/Controllers/LoginController.cs b/Step/Controllers/LoginController.cs index 8cbf20eb..95cc9e6f 100644 --- a/Step/Controllers/LoginController.cs +++ b/Step/Controllers/LoginController.cs @@ -1,13 +1,6 @@ using Step.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; using System.Web.Http; using Step.Database.Controllers; -using System.Web.Http.Controllers; -using System.Security.Claims; namespace Step.Controllers { @@ -25,5 +18,12 @@ namespace Step.Controllers if (model.Username == "utente" && model.Password == "finto") return Ok(); return Unauthorized(); } + + [CmsAuthorization(Category = "test", Action = "Write")] + [Route("test"), HttpGet] + public IHttpActionResult Test() + { + return Ok(); + } } } diff --git a/Step/Provider/ApplicationOAuthProvider.cs b/Step/Provider/ApplicationOAuthProvider.cs index ecf2fb6a..5b5f8785 100644 --- a/Step/Provider/ApplicationOAuthProvider.cs +++ b/Step/Provider/ApplicationOAuthProvider.cs @@ -14,28 +14,28 @@ namespace Step.Provider { public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { + // Validate client context.Validated(); } public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { - - context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); - using (UsersController usersController = new UsersController()) { + // Check if credentials are correct UserModel user = usersController.Find(context.UserName, context.Password); - + // If not if (user == null) { + // Return 401 bad request context.SetError("invalid_grant", "The user name or password is incorrect."); return; } - + // Create a new Identity and insert custom claims var identity = new ClaimsIdentity(context.Options.AuthenticationType); identity.AddClaim(new Claim("username", user.Username)); identity.AddClaim(new Claim("role", user.Role.Level.ToString())); - + // Create Token with identity data context.Validated(identity); } } diff --git a/Step/program.cs b/Step/program.cs index 70d46d60..1301262e 100644 --- a/Step/program.cs +++ b/Step/program.cs @@ -11,37 +11,34 @@ using TeamDev.SDK.MVVM; namespace Step { - public class Application - { - - public static readonly ManualResetEvent StopRequest = new ManualResetEvent(false); - - public static int MessageService { get; private set; } - - public static void Main() + public class Application { - // Avvio dell'applicazione in selfhost - var configuredUri = ConfigurationManager.AppSettings["localHostServiceURI"]; - ServerControlWindow.Start(); + public static readonly ManualResetEvent StopRequest = new ManualResetEvent(false); - // Registro il messaggi di chiusura della applicazione. - MessageServices.Current.Subscribe("StopServer", (a, b) => - { - Application.StopRequest.Set(); - }); + public static int MessageService { get; private set; } + public static void Main() + { + // Start self host application + var configuredUri = ConfigurationManager.AppSettings["localHostServiceURI"]; - // Creo la finestra lato server che verrà visualizzata sulla SysTray + // Start WinForm + ServerControlWindow.Start(); + // Register listener to "close application" messages + MessageServices.Current.Subscribe("StopServer", (a, b) => + { + StopRequest.Set(); + }); - // Avvio il servizio del server. - using (WebApp.Start(url: configuredUri)) - { - StopRequest.WaitOne(); - } - - ServerControlWindow.Stop(); + // Start server services + using (WebApp.Start(url: configuredUri)) + { + StopRequest.WaitOne(); + } + // Close WinForm + ServerControlWindow.Stop(); + } } - } } From 46c34f46e88cd8cb033ae957af0c3fa9765d5c3e Mon Sep 17 00:00:00 2001 From: "CMS4390\\marantalu" Date: Tue, 28 Nov 2017 17:19:01 +0100 Subject: [PATCH 4/4] * Fixed webapi auth * WIP signalauth * Fist commit server config --- Step.Config/Constants.cs | 16 +++ Step.Config/Properties/AssemblyInfo.cs | 36 +++++++ Step.Config/StartupConfig.cs | 22 +++++ Step.Config/StartupConfigController.cs | 96 ++++++++++++++++++ Step.Config/Step.Config.csproj | 62 ++++++++++++ Step.Config/startupValidator.xsd | 98 +++++++++++++++++++ Step.Database/App.config | 16 ++- .../Controllers/AccessCategoriesController.cs | 38 +++++++ Step.Database/DatabaseContext.cs | 4 +- Step.Database/Step.Database.csproj | 7 ++ Step.Model/AccessCategoryModel.cs | 27 +++++ Step.Model/ConfigModels/AreasConfigModel.cs | 15 +++ Step.Model/ConfigModels/GenericConfigModel.cs | 17 ++++ Step.Model/Step.Model.csproj | 4 + Step.sln | 12 +++ Step/App.config | 2 +- Step/App_Start/Startup.cs | 8 +- Step/CmsAuthorizationAttribute.cs | 37 ++++++- Step/Controllers/LoginController.cs | 7 +- Step/Provider/ApplicationOAuthProvider.cs | 8 +- Step/Provider/SignalROAuthBearerProvider.cs | 2 +- Step/Step.csproj | 6 ++ 22 files changed, 518 insertions(+), 22 deletions(-) create mode 100644 Step.Config/Constants.cs create mode 100644 Step.Config/Properties/AssemblyInfo.cs create mode 100644 Step.Config/StartupConfig.cs create mode 100644 Step.Config/StartupConfigController.cs create mode 100644 Step.Config/Step.Config.csproj create mode 100644 Step.Config/startupValidator.xsd create mode 100644 Step.Database/Controllers/AccessCategoriesController.cs create mode 100644 Step.Model/AccessCategoryModel.cs create mode 100644 Step.Model/ConfigModels/AreasConfigModel.cs create mode 100644 Step.Model/ConfigModels/GenericConfigModel.cs diff --git a/Step.Config/Constants.cs b/Step.Config/Constants.cs new file mode 100644 index 00000000..aa9aaa0c --- /dev/null +++ b/Step.Config/Constants.cs @@ -0,0 +1,16 @@ + +namespace Step.Config +{ + public static class Constants + { + public enum ACTIONS + { + READ, + WRITE + } + + public static string ROLE_LEVEL_KEY = "roleLevel"; + public static string USERNAME_KEY = "username"; + public static string ID_KEY = "id"; + } +} diff --git a/Step.Config/Properties/AssemblyInfo.cs b/Step.Config/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..2c3e382c --- /dev/null +++ b/Step.Config/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Le informazioni generali relative a un assembly sono controllate dal seguente +// set di attributi. Modificare i valori di questi attributi per modificare le informazioni +// associate a un assembly. +[assembly: AssemblyTitle("Step.Config")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Step.Config")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili +// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da +// COM, impostare su true l'attributo ComVisible per tale tipo. +[assembly: ComVisible(false)] + +// Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi +[assembly: Guid("3f5c2483-fc87-43ef-92a8-66ff7d0e440f")] + +// Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: +// +// Versione principale +// Versione secondaria +// Numero di build +// Revisione +// +// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build +// usando l'asterisco '*' come illustrato di seguito: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Step.Config/StartupConfig.cs b/Step.Config/StartupConfig.cs new file mode 100644 index 00000000..f563e698 --- /dev/null +++ b/Step.Config/StartupConfig.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Step.Model.ConfigModels; + +namespace Step.Config +{ + public static class StartupConfig + { + public static GenericConfigModel genericConfig; + + public static AreasConfigModel productionConfig; + public static AreasConfigModel toolingConfig; + public static AreasConfigModel reportConfig; + public static AreasConfigModel alarmsConfig; + public static AreasConfigModel maintenanceConfig; + public static AreasConfigModel utilitiesConfig; + public static AreasConfigModel scadaConfig; + } +} diff --git a/Step.Config/StartupConfigController.cs b/Step.Config/StartupConfigController.cs new file mode 100644 index 00000000..eddb3c9b --- /dev/null +++ b/Step.Config/StartupConfigController.cs @@ -0,0 +1,96 @@ +using System.Xml; +using System.Collections.Generic; +using System; +using System.Xml.Schema; +using System.Xml.Linq; +using System.Linq; +using static Step.Config.StartupConfig; +using Step.Model.ConfigModels; + +namespace Step.Config +{ + public class StartupConfigController + { + public static void ReadStartUpConfig() + { + // Read validation file + XmlSchemaSet readerSettings = new XmlSchemaSet(); + // Add Schema + readerSettings.Add(null, "startupValidator.xsd"); + // Open file reader + XDocument xmlConfigFile = XDocument.Load("startupConfig.xml"); + // Validate file + xmlConfigFile.Validate(readerSettings, ValidationHandler); + + // Read generic config with LINQ + genericConfig = xmlConfigFile + .Descendants("generalConfig") + .Select(x => new GenericConfigModel() + { + Language = x.Element("language").Value, + ServerPort = Convert.ToInt32(x.Element("serverPort").Value), + NcVendor = Convert.ToInt32(x.Element("NcVendor").Value), + NcIpAddress = x.Element("NcIpAddress").Value, + NcPort = Convert.ToInt32(x.Element("NcPort").Value) + }).FirstOrDefault(); + + xmlConfigFile + .Descendants("areasConfig") + .Elements() + .ToList() + .ForEach(x => addKeyValue(x)); + } + + private static void addKeyValue(XElement element) + { + switch (element.Name.ToString()) + { + case "production": + SetAreasConfigValue(ref productionConfig, element); + break; + case "tooling": + SetAreasConfigValue(ref toolingConfig, element); + break; + case "report": + SetAreasConfigValue(ref reportConfig, element); + break; + case "alarms": + SetAreasConfigValue(ref alarmsConfig, element); + break; + case "maintenance": + SetAreasConfigValue(ref maintenanceConfig, element); + break; + case "utilities": + SetAreasConfigValue(ref utilitiesConfig, element); + break; + case "scada": + SetAreasConfigValue(ref scadaConfig, element); + break; + } + } + + private static void SetAreasConfigValue (ref AreasConfigModel areasConfig, XElement element) + { + areasConfig = new AreasConfigModel() + { + name = element.Name.ToString(), + enabled = Convert.ToBoolean(element.Element("enabled").Value), + allowExternalBrowser = Convert.ToBoolean(element.Element("allowExternalBrowser").Value) + }; + } + + private static void ValidationHandler(object sender, ValidationEventArgs e) + { + if (e.Severity == XmlSeverityType.Warning) + { + Console.Write("WARNING: "); + Console.WriteLine(e.Message); + } + else if (e.Severity == XmlSeverityType.Error) + { + Console.Write("ERROR: "); + Console.WriteLine(e.Message); + } + } + } +} diff --git a/Step.Config/Step.Config.csproj b/Step.Config/Step.Config.csproj new file mode 100644 index 00000000..9aa033b1 --- /dev/null +++ b/Step.Config/Step.Config.csproj @@ -0,0 +1,62 @@ + + + + + Debug + AnyCPU + {3F5C2483-FC87-43EF-92A8-66FF7D0E440F} + Library + Properties + Step.Config + Step.Config + v4.6.2 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + Always + Designer + + + + + {631375dd-06d3-49bb-8130-d9ddb34c429d} + Step.Model + + + + \ No newline at end of file diff --git a/Step.Config/startupValidator.xsd b/Step.Config/startupValidator.xsd new file mode 100644 index 00000000..a1ebd836 --- /dev/null +++ b/Step.Config/startupValidator.xsd @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Step.Database/App.config b/Step.Database/App.config index 300c297c..efb35769 100644 --- a/Step.Database/App.config +++ b/Step.Database/App.config @@ -1,9 +1,9 @@  -
- + + @@ -12,12 +12,18 @@ - + + - + + + + + + @@ -28,4 +34,4 @@ - + \ No newline at end of file diff --git a/Step.Database/Controllers/AccessCategoriesController.cs b/Step.Database/Controllers/AccessCategoriesController.cs new file mode 100644 index 00000000..1f39bc2b --- /dev/null +++ b/Step.Database/Controllers/AccessCategoriesController.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; +using Step.Model; +using static Step.Config.Constants; + +namespace Step.Database.Controllers +{ + public class AccessCategoriesController : IDisposable + { + private DatabaseContext dbCtx; + + public AccessCategoriesController() + { + // Initialize database context + dbCtx = new DatabaseContext(); + } + + public void Dispose() + { + // Clear database context + dbCtx.Dispose(); + } + + public int FindCategoryLevelByAction(string categoryName, ACTIONS action) + { + AccessCategoryModel accessCategories = dbCtx.AccessCategories.Where(ac => ac.Name == categoryName).FirstOrDefault(); + if (accessCategories != null) + { + if (ACTIONS.READ == action) + return accessCategories.ReadLevelMin; + else + return accessCategories.WriteLevelMin; + } + + return 0; + } + } +} diff --git a/Step.Database/DatabaseContext.cs b/Step.Database/DatabaseContext.cs index 58340e7c..d640ed2e 100644 --- a/Step.Database/DatabaseContext.cs +++ b/Step.Database/DatabaseContext.cs @@ -9,15 +9,15 @@ using MySql.Data.Entity; namespace Step.Database { - [DbConfigurationType(typeof(MySqlEFConfiguration))] public class DatabaseContext : DbContext { public DbSet Users { get; set; } public DbSet Roles { get; set; } + public DbSet AccessCategories { get; set; } public DatabaseContext() - : base("databaseConnection") + : base("mySQLDatabaseConnection") { } } diff --git a/Step.Database/Step.Database.csproj b/Step.Database/Step.Database.csproj index 83b7082b..4c0238d4 100644 --- a/Step.Database/Step.Database.csproj +++ b/Step.Database/Step.Database.csproj @@ -12,6 +12,8 @@ v4.6.2 512 + + true @@ -64,6 +66,7 @@ + @@ -73,6 +76,10 @@ + + {3f5c2483-fc87-43ef-92a8-66ff7d0e440f} + Step.Config + {631375dd-06d3-49bb-8130-d9ddb34c429d} Step.Model diff --git a/Step.Model/AccessCategoryModel.cs b/Step.Model/AccessCategoryModel.cs new file mode 100644 index 00000000..d0856012 --- /dev/null +++ b/Step.Model/AccessCategoryModel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Step.Model +{ + [Table("access_category")] + public class AccessCategoryModel + { + [Key] + [Column("id")] + public int RoleId { get; set; } + + [Column("name")] + public string Name { get; set; } + + [Column("write_level_min")] + public int WriteLevelMin { get; set; } + + [Column("read_level_min")] + public int ReadLevelMin { get; set; } + } +} diff --git a/Step.Model/ConfigModels/AreasConfigModel.cs b/Step.Model/ConfigModels/AreasConfigModel.cs new file mode 100644 index 00000000..791326c5 --- /dev/null +++ b/Step.Model/ConfigModels/AreasConfigModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Step.Model.ConfigModels +{ + public class AreasConfigModel + { + public string name { get; set; } + public bool enabled { get; set; } + public bool allowExternalBrowser { get; set; } + } +} diff --git a/Step.Model/ConfigModels/GenericConfigModel.cs b/Step.Model/ConfigModels/GenericConfigModel.cs new file mode 100644 index 00000000..04ea13af --- /dev/null +++ b/Step.Model/ConfigModels/GenericConfigModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Step.Model.ConfigModels +{ + public class GenericConfigModel + { + public string Language { get; set; } + public int ServerPort { get; set; } + public int NcVendor { get; set; } + public int NcPort { get; set; } + public string NcIpAddress { get; set; } + } +} diff --git a/Step.Model/Step.Model.csproj b/Step.Model/Step.Model.csproj index 2f3f59a4..609301dd 100644 --- a/Step.Model/Step.Model.csproj +++ b/Step.Model/Step.Model.csproj @@ -53,6 +53,9 @@ + + + DtsGenerator RoleModel.cs.d.ts @@ -79,6 +82,7 @@ + XCOPY $(ProjectDir)*.d.ts $(SolutionDir)Step\wwwroot\src\@types /C /Y /O diff --git a/Step.sln b/Step.sln index daa81b9e..0f7ae332 100644 --- a/Step.sln +++ b/Step.sln @@ -4,12 +4,20 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 15.0.27004.2009 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step", "Step\Step.csproj", "{AFED34E1-77DB-4D81-830A-A8D0A190573D}" + ProjectSection(ProjectDependencies) = postProject + {3F5C2483-FC87-43EF-92A8-66FF7D0E440F} = {3F5C2483-FC87-43EF-92A8-66FF7D0E440F} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step.Model", "Step.Model\Step.Model.csproj", "{631375DD-06D3-49BB-8130-D9DDB34C429D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step.UI", "Step.UI\Step.UI.csproj", "{20FC0937-E7CA-4693-95F9-7A948EFD173B}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step.Database", "Step.Database\Step.Database.csproj", "{357D5EE1-FFC8-489B-9232-22CF474D9A6F}" + ProjectSection(ProjectDependencies) = postProject + {3F5C2483-FC87-43EF-92A8-66FF7D0E440F} = {3F5C2483-FC87-43EF-92A8-66FF7D0E440F} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Step.Config", "Step.Config\Step.Config.csproj", "{3F5C2483-FC87-43EF-92A8-66FF7D0E440F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -33,6 +41,10 @@ Global {357D5EE1-FFC8-489B-9232-22CF474D9A6F}.Debug|Any CPU.Build.0 = Debug|Any CPU {357D5EE1-FFC8-489B-9232-22CF474D9A6F}.Release|Any CPU.ActiveCfg = Release|Any CPU {357D5EE1-FFC8-489B-9232-22CF474D9A6F}.Release|Any CPU.Build.0 = Release|Any CPU + {3F5C2483-FC87-43EF-92A8-66FF7D0E440F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F5C2483-FC87-43EF-92A8-66FF7D0E440F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F5C2483-FC87-43EF-92A8-66FF7D0E440F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F5C2483-FC87-43EF-92A8-66FF7D0E440F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Step/App.config b/Step/App.config index 37004edd..643e3ecc 100644 --- a/Step/App.config +++ b/Step/App.config @@ -57,7 +57,7 @@ - + diff --git a/Step/App_Start/Startup.cs b/Step/App_Start/Startup.cs index be59a553..3830af1c 100644 --- a/Step/App_Start/Startup.cs +++ b/Step/App_Start/Startup.cs @@ -9,6 +9,7 @@ using Microsoft.Owin.FileSystems; using System.Configuration; using Microsoft.Owin.Security.OAuth; using Step.Provider; +using Step.Config; [assembly: OwinStartup(typeof(Step.App_Start.Startup))] @@ -18,6 +19,8 @@ namespace Step.App_Start { public void Configuration(IAppBuilder app) { + StartupConfigController.ReadStartUpConfig(); + // Configure HTTP HttpConfiguration config = new HttpConfiguration(); @@ -30,11 +33,10 @@ namespace Step.App_Start // Configure authentication ConfigureOAuth(app); - // Register SignalR - app.MapSignalR(); - app.UseWebApi(config); + // Register SignalR + app.MapSignalR(); var directoryBrowsing = ConfigurationManager.AppSettings["enableDirectoryBrowsing"] == "true"; string rootDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", "wwwroot"); diff --git a/Step/CmsAuthorizationAttribute.cs b/Step/CmsAuthorizationAttribute.cs index 353d1b6a..0bbaa9c0 100644 --- a/Step/CmsAuthorizationAttribute.cs +++ b/Step/CmsAuthorizationAttribute.cs @@ -1,19 +1,50 @@ -using System.Linq; +using System; +using System.Linq; using System.Security.Claims; +using System.Security.Principal; using System.Web.Http; using System.Web.Http.Controllers; +using Step.Database.Controllers; +using static Step.Config.Constants; namespace Step { class CmsAuthorizationAttribute : AuthorizeAttribute { public string Category; - public string Action; + public ACTIONS Action; protected override bool IsAuthorized(HttpActionContext actionContext) { + if (!base.IsAuthorized(actionContext)) + return false; + + // Get user level stored in the bearer token ClaimsPrincipal principal = actionContext.RequestContext.Principal as ClaimsPrincipal; - var customClaimValue = principal.Claims.Where(c => c.Type == "role").Single().Value; + int userLevel = Convert.ToInt32(principal.Claims.Where(c => c.Type == ROLE_LEVEL_KEY).Single().Value); + + if (!CheckAuthorization(userLevel)) + { + return false; + } + return base.IsAuthorized(actionContext); } + + private bool CheckAuthorization(int userLevel) + { + using (AccessCategoriesController acController = new AccessCategoriesController()) + { + // Read from db category levels + int categoryLevel = acController.FindCategoryLevelByAction(Category, Action); + + if (categoryLevel > userLevel) + { + // Not authorized + return false; + } + // Authorized + return true; + } + } } } diff --git a/Step/Controllers/LoginController.cs b/Step/Controllers/LoginController.cs index 95cc9e6f..f99ed85c 100644 --- a/Step/Controllers/LoginController.cs +++ b/Step/Controllers/LoginController.cs @@ -1,6 +1,7 @@ using Step.Model; using System.Web.Http; using Step.Database.Controllers; +using static Step.Config.Constants; namespace Step.Controllers { @@ -11,15 +12,11 @@ namespace Step.Controllers [Route(), HttpPost] public IHttpActionResult DoLogin(UserModel model) { - UsersController usersController = new UsersController(); - - usersController.Create(model.Username, "passwor", "nome","cognome", 1); - if (model.Username == "utente" && model.Password == "finto") return Ok(); return Unauthorized(); } - [CmsAuthorization(Category = "test", Action = "Write")] + [CmsAuthorization(Category = "test", Action = ACTIONS.WRITE)] [Route("test"), HttpGet] public IHttpActionResult Test() { diff --git a/Step/Provider/ApplicationOAuthProvider.cs b/Step/Provider/ApplicationOAuthProvider.cs index 5b5f8785..76d325d3 100644 --- a/Step/Provider/ApplicationOAuthProvider.cs +++ b/Step/Provider/ApplicationOAuthProvider.cs @@ -7,6 +7,7 @@ using Microsoft.Owin.Security.OAuth; using Step.Database.Controllers; using Step.Model; using System.Security.Claims; +using static Step.Config.Constants; namespace Step.Provider { @@ -33,10 +34,13 @@ namespace Step.Provider } // Create a new Identity and insert custom claims var identity = new ClaimsIdentity(context.Options.AuthenticationType); - identity.AddClaim(new Claim("username", user.Username)); - identity.AddClaim(new Claim("role", user.Role.Level.ToString())); + identity.AddClaim(new Claim(USERNAME_KEY, user.Username)); + identity.AddClaim(new Claim(ROLE_LEVEL_KEY, user.Role.Level.ToString())); // Create Token with identity data context.Validated(identity); + + await base.GrantResourceOwnerCredentials(context); + return; } } } diff --git a/Step/Provider/SignalROAuthBearerProvider.cs b/Step/Provider/SignalROAuthBearerProvider.cs index eea2c448..f9b61f84 100644 --- a/Step/Provider/SignalROAuthBearerProvider.cs +++ b/Step/Provider/SignalROAuthBearerProvider.cs @@ -13,7 +13,7 @@ namespace Groupadoo.Web.Providers public override Task RequestToken(OAuthRequestTokenContext context) { - var token = context.OwinContext.Request.Query["bearer_token"]; + var token = context.OwinContext.Request.Query["connectionToken"]; if (!string.IsNullOrWhiteSpace(token)) { var result = JsonConvert.DeserializeObject(token); diff --git a/Step/Step.csproj b/Step/Step.csproj index e250044b..0947b73c 100644 --- a/Step/Step.csproj +++ b/Step/Step.csproj @@ -145,11 +145,13 @@ + + @@ -275,6 +277,10 @@ + + {3f5c2483-fc87-43ef-92a8-66ff7d0e440f} + Step.Config + {357d5ee1-ffc8-489b-9232-22cf474d9a6f} Step.Database