Перейти к содержимому

Как получить бд c forms

  • автор:

как сделать установщик windows form приложения на C# к которому подключена SSMS база данных?

Создана база данных в SSMS на локальном компьютере, также создано WindowsForm приложение на C#, которое выводит данные из таблиц БД. Сделал установочный файл приложения, на моем ПК устанавливается и работает как и задумано, а на ПК друга после установки запускаю приложение и не могу авторизоваться (в бд создана таблица с зарегистрированными пользователями). Понятно что приложение просто не может подключиться к базе данных, но как это решить? Подключение к базе данных прописано в отдельном классе. Код класса прилагается.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.SqlClient; namespace test_DataBase < internal class DataBase < SqlConnection sqlConnection = new SqlConnection(@"Data Source=DESKTOP-GE5UCRH\SQLEXPRESS; Initial Catalog=test; Integrated Security=True"); public void openConnection() < if (sqlConnection.State == System.Data.ConnectionState.Closed) < sqlConnection.Open(); >> public void closeConnection() < if (sqlConnection.State == System.Data.ConnectionState.Open) < sqlConnection.Close(); >> public SqlConnection getConnection() < return sqlConnection; >> > 

Отслеживать
48.4k 5 5 золотых знаков 22 22 серебряных знака 57 57 бронзовых знаков
задан 22 мар 2023 в 5:48
33 5 5 бронзовых знаков
Установщик создавался при помощи Microsoft Visual Studio Installer Projects 2022
22 мар 2023 в 5:50
Пк — друга подключен к вашей сети, так?
22 мар 2023 в 6:47
На одном Wi-Fi.
22 мар 2023 в 7:06
А пк на котором БД доступ для других пользователей разрешен?
22 мар 2023 в 7:10
Нет, доступа нету
22 мар 2023 в 7:17

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

«в бд создана таблица с зарегистрированными пользователями»

У вас авторизация в БД на базе учетки Windows. Как вы прописали пользователей? У вас домен или рабочая группа?

Просто есть подозрение, что у вас рабочая группа, а вы создали просто табличку с пользователями и в ручную проверяете авторизацию, уже после подключения. Определитесь и настроите доступ для подключения к БД сначала.

Далее вы столкнётесь с тем, что скорее всего не настроили прослушивание tcp/ip у sql server. И не открыли порт в фаерволе.

Создание простого приложения для работы с данными с помощью ADO.NET

Наборы данных и связанные классы являются устаревшими технологиями платформа .NET Framework с начала 2000-х годов, которые позволяют приложениям работать с данными в памяти во время отключения приложений от базы данных. Они особенно полезны для приложений, которые позволяют пользователям изменять данные и сохранять изменения обратно в базу данных. Хотя наборы данных оказались очень успешными, мы рекомендуем новым приложениям .NET использовать Entity Framework Core. Entity Framework предоставляет более естественный способ работы с табличными данными в виде объектных моделей, и он имеет более простой интерфейс программирования.

При создании приложения, которое работает с данными в базе данных, необходимо выполнить такие основные задачи, как определение строк подключения, вставка данных и выполнение хранимых процедур. Следуя этому разделу, вы можете узнать, как взаимодействовать с базой данных из простого приложения Windows Forms по данным с помощью Visual C# или Visual Basic и ADO.NET. Все технологии данных .NET, включая наборы данных, LINQ to SQL и Entity Framework, в конечном счете выполняют действия, которые очень похожи на приведенные в этой статье.

В этой статье демонстрируется простой способ быстрого получения данных из базы данных. Если приложению необходимо изменить данные в нетривиальных способах и обновить базу данных, следует рассмотреть возможность использования Entity Framework и использования привязки данных для автоматической синхронизации элементов управления пользовательским интерфейсом с изменениями в базовых данных.

С целью упрощения код не включает обработку исключений для выполнения в рабочей среде.

Полный код для этого руководства можно получить в репозитории GitHub в Visual Studio в C# и Visual Basic.

Необходимые компоненты

Чтобы создать приложение, вам потребуется:

  • Visual Studio с установленными рабочими нагрузками разработки классических приложений .NET и хранилища данных и обработки. Чтобы установить их, откройте Visual Studio Installer и нажмите кнопку «Изменить» (или «Изменить >«) рядом с версией Visual Studio, которую вы хотите изменить.
  • SQL Server Express LocalDB. Если у вас нет SQL Server Express LocalDB, его можно установить на странице загрузки SQL Server.

В этом разделе предполагается, что вы знакомы с основными функциями интегрированной среды разработки Visual Studio и можете создавать приложения Windows Forms, добавлять формы в проект, помещать кнопки и другие элементы управления в формы, задавать свойства элементов управления и кодировать простые события. Если вы не знакомы с этими задачами, мы рекомендуем завершить создание приложения Windows Forms в Visual Studio с помощью руководства по Visual Basic или создать приложение Windows Forms в Visual Studio с помощью руководства по C# , прежде чем начать это пошаговое руководство.

Настройка образца базы данных

Создайте образец базы данных, выполнив следующие действия.

  1. В Visual Studio откройте окно Обозреватель сервера.
  2. Щелкните правой кнопкой мыши Подключение данных и выберите «Создать базу данных SQL Server».
  3. В текстовом поле имени сервера введите (localdb)\mssqllocaldb.
  4. В текстовом поле «Новое имя базы данных» введите sales, а затем нажмите кнопку «ОК«. Пустая база данных sales создается и добавляется в узел data Подключение ions в сервере Обозреватель.
  5. Щелкните правой кнопкой мыши подключение к данным о продажах и выберите «Создать запрос«. Откроется окно редактора запросов.
  6. Скопируйте скрипт Sales Transact-SQL в буфер обмена.
  7. Вставьте скрипт T-SQL в редактор запросов и нажмите кнопку «Выполнить «. Через некоторое время запрос завершает выполнение и создаются объекты базы данных. База данных содержит две таблицы: Customer и Orders. Эти таблицы изначально не содержат данных, но при запуске создаваемого приложения можно добавить данные. База данных также содержит четыре простых хранимых процедуры.

Создание форм и добавление элементов управления

  1. Создайте проект C# или Visual Basic с помощью шаблона приложения Windows Forms (платформа .NET Framework), а затем назовите его SimpleDataApp. Visual Studio создает проект и несколько файлов, включая пустую форму Windows Forms с именем Form1.
  2. Добавьте две формы Windows Forms в проект, чтобы он включал три формы, и назначьте им следующие имена:
    • Переходы
    • NewCustomer
    • FillOrCancel
  3. Для каждой формы добавьте текстовые поля, кнопки и другие элементы управления, которые отображаются на рисунках ниже. Для каждого элемента управления задайте свойства, указанные в таблицах.

Примечание. Элементы управления «группа» и «надпись» обеспечивают большую ясность, но не используются в коде.

Navigation dialog box

Форма навигации

Элементы управления формы навигации Свойства
Кнопка Name = btnGoToAdd
Кнопка Name = btnGoToFillOrCancel
Кнопка Name = btnExit

Форма NewCustomer

Add a new customer and place an order

Элементы управления формы NewCustomer Свойства
TextBox Name = txtCustomerName
TextBox Name = txtCustomerID

Форма FillOrCancel

fill or cancel orders

Элементы управления формы FillOrCancel Свойства
TextBox Name = txtOrderID
Кнопка Name = btnFindByOrderID
DateTimePicker Format = Short

Сохранение строки подключения

Когда приложение пытается открыть подключение к базе данных, оно должно иметь доступ к строке подключения. Чтобы избежать ввода строки вручную в каждой форме, сохраните строку в файле App.config в проекте и создайте метод, возвращающий строку при вызове метода из любой формы в приложении.

Вы можете найти строка подключения, щелкнув правой кнопкой мыши подключение к данным о продажах в сервере Обозреватель и выбрав свойства. Найдите свойство Подключение ionString, а затем нажмите клавиши CTRL+A, CTRL+C, чтобы выбрать и скопировать строку в буфер обмена.

Screenshot of Connection String in Settings.settings

  1. Если вы используете C#, в Обозреватель решений разверните узел свойств в проекте и откройте файл Параметры.settings. Если вы используете Visual Basic, в Обозреватель решений щелкните «Показать все файлы«, разверните узел «Мой проект» и откройте файл Параметры.settings.
  2. В столбце «Имя» введите connString .
  3. В списке «Тип« выберите (Подключение ion String).
  4. В списке областей выберите «Приложение«.
  5. В столбце «Значение» введите строка подключения (без каких-либо внешних кавычек), а затем сохраните изменения.

В реальном приложении необходимо безопасно хранить строка подключения, как описано в строках Подключение ion и файлах конфигурации.

Написание кода для форм

В этом разделе содержатся краткие сведения о том, что делает каждая форма. Он также предоставляет код, определяющий базовую логику при нажатии кнопки в форме.

Форма навигации

Форма навигации открывается при запуске приложения. Кнопка Добавить учетную запись открывает форму NewCustomer. Кнопка Выполнение или отмена заказов открывает форму FillOrCancel. Кнопка Выход закрывает приложение.

Преобразование формы навигации в начальную форму

При использовании C# в обозревателе решений откройте файл Program.cs и измените строку Application.Run на следующую: Application.Run(new Navigation());

Если вы используете Visual Basic, в Обозреватель решений откройте окно «Свойства«, перейдите на вкладку «Приложение«, а затем выберите SimpleDataApp.Navigation в списке форм запуска.

Создание обработчиков событий автоматического создания

Дважды щелкните три кнопки в форме навигации, чтобы создать пустые методы обработчика событий. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажатию кнопки вызывать событие.

Если вы пропустите действие двойного щелчка в конструкторе и просто скопируйте код и вставьте его в файлы кода, не забудьте задать обработчик событий правильным методом. Это можно сделать в окне «Свойства «. Перейдите на вкладку «События» (используйте кнопку панели инструментов молнии) и найдите обработчик щелчка .

Добавление кода для логики формы навигации

На кодовой странице формы навигации заполните тела методов для трех обработчиков событий нажатия кнопки, как показано в следующем коде.

/// /// Opens the NewCustomer form as a dialog box, /// which returns focus to the calling form when it is closed. /// private void btnGoToAdd_Click(object sender, EventArgs e) < Form frm = new NewCustomer(); frm.Show(); >/// /// Opens the FillorCancel form as a dialog box. /// private void btnGoToFillOrCancel_Click(object sender, EventArgs e) < Form frm = new FillOrCancel(); frm.ShowDialog(); >/// /// Closes the application (not just the Navigation form). /// private void btnExit_Click(object sender, EventArgs e)
''' ''' Opens the NewCustomer form as a dialog box, which returns focus to the calling form when it closes. ''' Private Sub btnGoToAdd_Click(sender As Object, e As EventArgs) Handles btnGoToAdd.Click Dim frm As Form = New NewCustomer() frm.Show() End Sub ''' ''' Opens the FillOrCancel form as a dialog box. ''' Private Sub btnGoToFillOrCancel_Click(sender As Object, e As EventArgs) Handles btnGoToFillOrCancel.Click Dim frm As Form = New FillOrCancel() frm.ShowDialog() End Sub ''' ''' Closes the application (not just the navigation form). ''' Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click Me.Close() End Sub 

Код для этого руководства доступен в C# и Visual Basic. Чтобы переключить язык кода на этой странице между C# и Visual Basic, используйте переключатель языка кода в верхней части каждого примера кода.

Форма NewCustomer

При вводе имени клиента и нажатии кнопки «Создать учетную запись » форма NewCustomer создает учетную запись клиента, а SQL Server возвращает значение IDENTITY в качестве нового идентификатора клиента. Затем вы можете разместить заказ для новой учетной записи, указав сумму и дату заказа и нажав кнопку «Заказ места «.

Создание обработчиков событий автоматического создания

Создайте пустой обработчик событий Click для каждой кнопки в форме NewCustomer, дважды щелкнув каждую из четырех кнопок. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажатию кнопки вызывать событие.

Добавление кода для логики формы NewCustomer

Чтобы завершить логику формы NewCustomer, выполните следующие действия.

System.Data.SqlClient Доведите пространство имен в область, чтобы вам не нужно полностью квалифицировать имена его членов.

using System.Data.SqlClient; 
Imports System.Data.SqlClient 

Добавьте в класс некоторые переменные и вспомогательные методы, как показано в следующем коде.

// Storage for IDENTITY values returned from database. private int parsedCustomerID; private int orderID; /// /// Verifies that the customer name text box is not empty. /// private bool IsCustomerNameValid() < if (txtCustomerName.Text == "") < MessageBox.Show("Please enter a name."); return false; >else < return true; >> /// /// Verifies that a customer ID and order amount have been provided. /// private bool IsOrderDataValid() < // Verify that CustomerID is present. if (txtCustomerID.Text == "") < MessageBox.Show("Please create customer account before placing order."); return false; >// Verify that Amount isn't 0. else if ((numOrderAmount.Value < 1)) < MessageBox.Show("Please specify an order amount."); return false; >else < // Order can be submitted. return true; >> /// /// Clears the form data. /// private void ClearForm()
' Storage for ID values returned from the database. Private parsedCustomerID As Integer Private orderID As Integer ''' ''' Verifies that the customer name text box is not empty. ''' Private ReadOnly Property IsCustomerNameValid As Boolean Get If txtCustomerName.Text = "" Then MessageBox.Show("Please enter a name.") Return False Else Return True End If End Get End Property ''' ''' Verifies the order data is valid. ''' Private Function IsOrderDataValid() As Boolean ' Verify that CustomerID is present. If txtCustomerID.Text = "" Then MessageBox.Show("Please create a customer account before placing order.") Return False ' Verify that order amount isn't 0. ElseIf (numOrderAmount.Value < 1) Then MessageBox.Show("Please specify an order amount.") Return False Else ' Order can be submitted. Return True End If End Function ''' ''' Clears values from controls. ''' Private Sub ClearForm() txtCustomerName.Clear() txtCustomerID.Clear() dtpOrderDate.Value = DateTime.Now numOrderAmount.Value = 0 Me.parsedCustomerID = 0 End Sub 

Заполните тела метода для четырех обработчиков событий нажатия кнопки, как показано в следующем коде.

/// /// Creates a new customer by calling the Sales.uspNewCustomer stored procedure. /// private void btnCreateAccount_Click(object sender, EventArgs e) < if (IsCustomerNameValid()) < // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Create a SqlCommand, and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspNewCustomer", connection)) < sqlCommand.CommandType = CommandType.StoredProcedure; // Add input parameter for the stored procedure and specify what to use as its value. sqlCommand.Parameters.Add(new SqlParameter("@CustomerName", SqlDbType.NVarChar, 40)); sqlCommand.Parameters["@CustomerName"].Value = txtCustomerName.Text; // Add the output parameter. sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int)); sqlCommand.Parameters["@CustomerID"].Direction = ParameterDirection.Output; try < connection.Open(); // Run the stored procedure. sqlCommand.ExecuteNonQuery(); // Customer ID is an IDENTITY value from the database. this.parsedCustomerID = (int)sqlCommand.Parameters["@CustomerID"].Value; // Put the Customer ID value into the read-only text box. this.txtCustomerID.Text = Convert.ToString(parsedCustomerID); >catch < MessageBox.Show("Customer ID was not returned. Account could not be created."); >finally < connection.Close(); >> > > > /// /// Calls the Sales.uspPlaceNewOrder stored procedure to place an order. /// private void btnPlaceOrder_Click(object sender, EventArgs e) < // Ensure the required input is present. if (IsOrderDataValid()) < // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Create SqlCommand and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspPlaceNewOrder", connection)) < sqlCommand.CommandType = CommandType.StoredProcedure; // Add the @CustomerID input parameter, which was obtained from uspNewCustomer. sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int)); sqlCommand.Parameters["@CustomerID"].Value = this.parsedCustomerID; // Add the @OrderDate input parameter. sqlCommand.Parameters.Add(new SqlParameter("@OrderDate", SqlDbType.DateTime, 8)); sqlCommand.Parameters["@OrderDate"].Value = dtpOrderDate.Value; // Add the @Amount order amount input parameter. sqlCommand.Parameters.Add(new SqlParameter("@Amount", SqlDbType.Int)); sqlCommand.Parameters["@Amount"].Value = numOrderAmount.Value; // Add the @Status order status input parameter. // For a new order, the status is always O (open). sqlCommand.Parameters.Add(new SqlParameter("@Status", SqlDbType.Char, 1)); sqlCommand.Parameters["@Status"].Value = "O"; // Add the return value for the stored procedure, which is the order ID. sqlCommand.Parameters.Add(new SqlParameter("@RC", SqlDbType.Int)); sqlCommand.Parameters["@RC"].Direction = ParameterDirection.ReturnValue; try < //Open connection. connection.Open(); // Run the stored procedure. sqlCommand.ExecuteNonQuery(); // Display the order number. this.orderID = (int)sqlCommand.Parameters["@RC"].Value; MessageBox.Show("Order number " + this.orderID + " has been submitted."); >catch < MessageBox.Show("Order could not be placed."); >finally < connection.Close(); >> > > > /// /// Clears the form data so another new account can be created. /// private void btnAddAnotherAccount_Click(object sender, EventArgs e) < this.ClearForm(); >/// /// Closes the form/dialog box. /// private void btnAddFinish_Click(object sender, EventArgs e)
''' ''' Creates a new account by executing the Sales.uspNewCustomer ''' stored procedure on the database. ''' Private Sub btnCreateAccount_Click(sender As Object, e As EventArgs) Handles btnCreateAccount.Click ' Ensure a customer name has been entered. If IsCustomerNameValid Then ' Create the SqlConnection object. Using connection As New SqlConnection(My.Settings.connString) ' Create a SqlCommand, and identify the command type as a stored procedure. Using sqlCommand As New SqlCommand("Sales.uspNewCustomer", connection) sqlCommand.CommandType = CommandType.StoredProcedure ' Add the customer name input parameter for the stored procedure. sqlCommand.Parameters.Add(New SqlParameter("@CustomerName", SqlDbType.NVarChar, 40)) sqlCommand.Parameters("@CustomerName").Value = txtCustomerName.Text ' Add the customer ID output parameter. sqlCommand.Parameters.Add(New SqlParameter("@CustomerID", SqlDbType.Int)) sqlCommand.Parameters("@CustomerID").Direction = ParameterDirection.Output Try ' Open the connection. connection.Open() ' Run the stored procedure. sqlCommand.ExecuteNonQuery() ' Convert the Customer ID value to an Integer. Me.parsedCustomerID = CInt(sqlCommand.Parameters("@CustomerID").Value) ' Insert the customer ID into the corresponding text box. Me.txtCustomerID.Text = Convert.ToString(parsedCustomerID) Catch MessageBox.Show("Customer ID was not returned. Account could not be created.") Finally ' Close the connection. connection.Close() End Try End Using End Using End If End Sub ''' ''' Places the order by executing the Sales.uspPlaceNewOrder ''' stored procedure on the database. ''' Private Sub btnPlaceOrder_Click(sender As Object, e As EventArgs) Handles btnPlaceOrder.Click If IsOrderDataValid() Then ' Create the connection. Using connection As New SqlConnection(My.Settings.connString) ' Create SqlCommand and identify it as a stored procedure. Using sqlCommand As New SqlCommand("Sales.uspPlaceNewOrder", connection) sqlCommand.CommandType = CommandType.StoredProcedure ' Add the @CustomerID parameter, which was an output parameter from uspNewCustomer. sqlCommand.Parameters.Add(New SqlParameter("@CustomerID", SqlDbType.Int)) sqlCommand.Parameters("@CustomerID").Value = Me.parsedCustomerID ' Add the @OrderDate parameter. sqlCommand.Parameters.Add(New SqlParameter("@OrderDate", SqlDbType.DateTime, 8)) sqlCommand.Parameters("@OrderDate").Value = dtpOrderDate.Value ' Add the @Amount parameter. sqlCommand.Parameters.Add(New SqlParameter("@Amount", SqlDbType.Int)) sqlCommand.Parameters("@Amount").Value = numOrderAmount.Value ' Add the @Status parameter. For a new order, the status is always O (open). sqlCommand.Parameters.Add(New SqlParameter("@Status", SqlDbType.[Char], 1)) sqlCommand.Parameters("@Status").Value = "O" ' Add a return value parameter for the stored procedure, which is the orderID. sqlCommand.Parameters.Add(New SqlParameter("@RC", SqlDbType.Int)) sqlCommand.Parameters("@RC").Direction = ParameterDirection.ReturnValue Try ' Open connection. connection.Open() ' Run the stored procedure. sqlCommand.ExecuteNonQuery() ' Display the order number. Me.orderID = CInt(sqlCommand.Parameters("@RC").Value) MessageBox.Show("Order number " & (Me.orderID).ToString & " has been submitted.") Catch ' A simple catch. MessageBox.Show("Order could not be placed.") Finally ' Always close a connection after you finish using it, ' so that it can be released to the connection pool. connection.Close() End Try End Using End Using End If End Sub ''' ''' Resets the form for another new account. ''' Private Sub btnAddAnotherAccount_Click(sender As Object, e As EventArgs) Handles btnAddAnotherAccount.Click Me.ClearForm() End Sub ''' ''' Closes the NewCustomer form and returns focus to the Navigation form. ''' Private Sub btnAddFinish_Click(sender As Object, e As EventArgs) Handles btnAddFinish.Click Me.Close() End Sub 

Форма FillOrCancel

Форма FillOrCancel запускает запрос, чтобы вернуть заказ при вводе идентификатора заказа, а затем нажмите кнопку «Найти заказ «. Возвращенная строка отображается в сетке данных только для чтения. Вы можете пометить заказ как отмененный (X), если нажмите кнопку «Отмена заказа «, или вы можете пометить заказ как заполненный (F) при нажатии кнопки «Заказ заполнения «. Если снова выбрать кнопку «Найти заказ «, появится обновленная строка.

Создание обработчиков событий автоматического создания

Создайте пустые обработчики событий Click для четырех кнопок в форме FillOrCancel, дважды щелкнув кнопки. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажатию кнопки вызывать событие.

Добавление кода для логики формы FillOrCancel

Чтобы завершить логику формы FillOrCancel, выполните следующие действия.

Доведите следующие два пространства имен в область, чтобы вам не нужно полностью указать имена своих членов.

using System.Data.SqlClient; using System.Text.RegularExpressions; 
Imports System.Data.SqlClient Imports System.Text.RegularExpressions 

Добавьте в класс переменную и вспомогательный метод, как показано в следующем коде.

// Storage for the order ID value. private int parsedOrderID; /// /// Verifies that an order ID is present and contains valid characters. /// private bool IsOrderIDValid() < // Check for input in the Order ID text box. if (txtOrderID.Text == "") < MessageBox.Show("Please specify the Order ID."); return false; >// Check for characters other than integers. else if (Regex.IsMatch(txtOrderID.Text, @"^\D*$")) < // Show message and clear input. MessageBox.Show("Customer ID must contain only numbers."); txtOrderID.Clear(); return false; >else < // Convert the text in the text box to an integer to send to the database. parsedOrderID = Int32.Parse(txtOrderID.Text); return true; >> 
' Storage for OrderID. Private parsedOrderID As Integer ''' ''' Verifies that OrderID is valid. ''' Private Function IsOrderIDValid() As Boolean ' Check for input in the Order ID text box. If txtOrderID.Text = "" Then MessageBox.Show("Please specify the Order ID.") Return False ' Check for characters other than integers. ElseIf Regex.IsMatch(txtOrderID.Text, "^\D*$") Then ' Show message and clear input. MessageBox.Show("Please specify integers only.") txtOrderID.Clear() Return False Else ' Convert the text in the text box to an integer to send to the database. parsedOrderID = Int32.Parse(txtOrderID.Text) Return True End If End Function 

Заполните тела метода для четырех обработчиков событий нажатия кнопки, как показано в следующем коде.

/// /// Executes a t-SQL SELECT statement to obtain order data for a specified /// order ID, then displays it in the DataGridView on the form. /// private void btnFindByOrderID_Click(object sender, EventArgs e) < if (IsOrderIDValid()) < using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Define a t-SQL query string that has a parameter for orderID. const string sql = "SELECT * FROM Sales.Orders WHERE orderID = @orderID"; // Create a SqlCommand object. using (SqlCommand sqlCommand = new SqlCommand(sql, connection)) < // Define the @orderID parameter and set its value. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; try < connection.Open(); // Run the query by calling ExecuteReader(). using (SqlDataReader dataReader = sqlCommand.ExecuteReader()) < // Create a data table to hold the retrieved data. DataTable dataTable = new DataTable(); // Load the data from SqlDataReader into the data table. dataTable.Load(dataReader); // Display the data from the data table in the data grid view. this.dgvCustomerOrders.DataSource = dataTable; // Close the SqlDataReader. dataReader.Close(); >> catch < MessageBox.Show("The requested order could not be loaded into the form."); >finally < // Close the connection. connection.Close(); >> > > > /// /// Cancels an order by calling the Sales.uspCancelOrder /// stored procedure on the database. /// private void btnCancelOrder_Click(object sender, EventArgs e) < if (IsOrderIDValid()) < // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Create the SqlCommand object and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspCancelOrder", connection)) < sqlCommand.CommandType = CommandType.StoredProcedure; // Add the order ID input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; try < // Open the connection. connection.Open(); // Run the command to execute the stored procedure. sqlCommand.ExecuteNonQuery(); >catch < MessageBox.Show("The cancel operation was not completed."); >finally < // Close connection. connection.Close(); >> > > > /// /// Fills an order by calling the Sales.uspFillOrder stored /// procedure on the database. /// private void btnFillOrder_Click(object sender, EventArgs e) < if (IsOrderIDValid()) < // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) < // Create command and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspFillOrder", connection)) < sqlCommand.CommandType = CommandType.StoredProcedure; // Add the order ID input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; // Add the filled date input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@FilledDate", SqlDbType.DateTime, 8)); sqlCommand.Parameters["@FilledDate"].Value = dtpFillDate.Value; try < connection.Open(); // Execute the stored procedure. sqlCommand.ExecuteNonQuery(); >catch < MessageBox.Show("The fill operation was not completed."); >finally < // Close the connection. connection.Close(); >> > > > /// /// Closes the form. /// private void btnFinishUpdates_Click(object sender, EventArgs e)
''' ''' Executes a t-SQL SELECT query on the database to ''' obtain order data for a specified order ID. ''' Private Sub btnFindByOrderID_Click(sender As Object, e As EventArgs) Handles btnFindByOrderID.Click ' Prepare the connection and the command. If IsOrderIDValid() Then ' Create the connection. Using connection As New SqlConnection(My.Settings.connString) ' Define the query string that has a parameter for orderID. Const sql As String = "select * from Sales.Orders where orderID = @orderID" ' Create a SqlCommand object. Using sqlCommand As New SqlCommand(sql, connection) ' Define the @orderID parameter and its value. sqlCommand.Parameters.Add(New SqlParameter("@orderID", SqlDbType.Int)) sqlCommand.Parameters("@orderID").Value = parsedOrderID Try ' Open connection. connection.Open() ' Execute the query. Dim dataReader As SqlDataReader = sqlCommand.ExecuteReader() ' Create a data table to hold the retrieved data. Dim dataTable As New DataTable() ' Load the data from SqlDataReader into the data table. dataTable.Load(dataReader) ' Display the data from the data table in the data grid view. Me.dgvCustomerOrders.DataSource = dataTable ' Close the SqlDataReader. dataReader.Close() Catch MessageBox.Show("The requested order could not be loaded into the form.") Finally ' Close the connection. connection.Close() End Try End Using End Using End If End Sub ''' ''' Fills an order by running the Sales.uspFillOrder stored procedure on the database. ''' Private Sub btnFillOrder_Click(sender As Object, e As EventArgs) Handles btnFillOrder.Click ' Set up and run stored procedure only if OrderID is valid. If IsOrderIDValid() Then ' Create the connection. Using connection As New SqlConnection(My.Settings.connString) ' Create command and identify it as a stored procedure. Using sqlCommand As New SqlCommand("Sales.uspFillOrder", connection) sqlCommand.CommandType = CommandType.StoredProcedure ' Add input parameter for the stored procedure. sqlCommand.Parameters.Add(New SqlParameter("@orderID", SqlDbType.Int)) sqlCommand.Parameters("@orderID").Value = parsedOrderID ' Add second input parameter. sqlCommand.Parameters.Add(New SqlParameter("@FilledDate", SqlDbType.DateTime, 8)) sqlCommand.Parameters("@FilledDate").Value = dtpFillDate.Value Try ' Open the connection. connection.Open() ' Run the SqlCommand. sqlCommand.ExecuteNonQuery() Catch ' A simple catch. MessageBox.Show("The fill operation was not completed.") Finally ' Close the connection. connection.Close() End Try End Using End Using End If End Sub ''' ''' Cancels an order by running the Sales.uspCancelOrder stored procedure on the database. ''' Private Sub btnCancelOrder_Click(sender As Object, e As EventArgs) Handles btnCancelOrder.Click ' Set up and run the stored procedure only if OrderID is ready. If IsOrderIDValid() Then ' Create the connection. Using connection As New SqlConnection(My.Settings.connString) ' Create the command and identify it as a stored procedure. Using sqlCommand As New SqlCommand("Sales.uspCancelOrder", connection) sqlCommand.CommandType = CommandType.StoredProcedure ' Add input parameter for the stored procedure. sqlCommand.Parameters.Add(New SqlParameter("@orderID", SqlDbType.Int)) sqlCommand.Parameters("@orderID").Value = parsedOrderID Try ' Open the connection. connection.Open() ' Run the SqlCommand. sqlCommand.ExecuteNonQuery() Catch ' A simple catch. MessageBox.Show("The cancel operation was not completed.") Finally ' Close connection. connection.Close() End Try End Using End Using End If End Sub ''' ''' Closes the form and returns focus to the Navigation form. ''' Private Sub btnFinishUpdates_Click(sender As Object, e As EventArgs) Handles btnFinishUpdates.Click Me.Close() End Sub 

Тестирование приложения

Запустите приложение и попробуйте создать несколько клиентов и заказов, чтобы убедиться, что все работает должным образом. Чтобы убедиться, что база данных обновлена с изменениями, откройте узел таблиц на сервере Обозреватель, щелкните правой кнопкой мыши узлы «Клиенты и заказы» и выберите «Показать данные таблицы».

Связанный контент

Создание базы данных и добавление таблиц в приложениях платформа .NET Framework с помощью Visual Studio

Наборы данных и связанные классы являются устаревшими технологиями платформа .NET Framework с начала 2000-х годов, которые позволяют приложениям работать с данными в памяти во время отключения приложений от базы данных. Они особенно полезны для приложений, которые позволяют пользователям изменять данные и сохранять изменения обратно в базу данных. Хотя наборы данных оказались очень успешными, мы рекомендуем новым приложениям .NET использовать Entity Framework Core. Entity Framework предоставляет более естественный способ работы с табличными данными в виде объектных моделей, и он имеет более простой интерфейс программирования.

Visual Studio можно использовать для создания и обновления локального файла базы данных в SQL Server Express LocalDB. Вы также можете создать базу данных, выполнив инструкции Transact-SQL в окне инструментов SQL Server обозреватель объектов в Visual Studio. В этом разделе описано, как создать .mdf файл и добавить таблицы и ключи с помощью конструктора таблиц.

Необходимые компоненты

Чтобы выполнить это пошаговое руководство, вам потребуется разработка классических приложений .NET и хранение и обработка рабочих нагрузок, установленных в Visual Studio. Чтобы установить их, откройте Visual Studio Installer и нажмите кнопку «Изменить» (или «Изменить >«) рядом с версией Visual Studio, которую вы хотите изменить. См. раздел Изменение Visual Studio.

Процедуры, описанные в этой статье, применяются только к платформа .NET Framework проектам Windows Forms, а не к проектам Windows Forms .NET Core.

Создание проекта и файла локальной базы данных

  1. Создайте проект приложения Windows Forms (платформа .NET Framework) и назовите его SampleDatabaseWalkthrough.
  2. В строке меню выберите «Добавить новый элемент проекта>«. Если появится небольшое диалоговое окно с полем для имени файла, выберите «Показать все шаблоны«.
  3. В списке шаблонов элементов прокрутите вниз и выберите базу данных на основе служб.

Add New item ></p>
<p>Service-based database» /></p>
<p><img decoding=

Add new data source in Visual Studio

Просмотр свойств подключения к данным

Вы можете просмотреть строка подключения для файла SampleDatabase.mdf, открыв окно свойств подключения к данным:

  • Выберите «Просмотреть> SQL Server» обозреватель объектов, чтобы открыть окно обозреватель объектов SQL Server. Разверните (localdb)\MSSQLLocalDB>Database, а затем щелкните правой кнопкой мыши sampleDatabase.mdf (он может быть указан как полный путь) и выберите «Свойства».
  • Кроме того, можно выбрать Обозреватель представления>сервера, если это окно еще не открыто. Откройте окно свойств, разверните узел «Данные Подключение ions«, щелкните правой кнопкой мыши файл SampleDatabase.mdf и выберите «Свойства«.

Совет Если вы не можете развернуть узел «Данные Подключение ions», или подключение SampleDatabase.mdf не указано, нажмите кнопку Подключение в базу данных на панели инструментов сервера Обозреватель. В диалоговом окне «Добавить Подключение ion» убедитесь, что в источнике данных выбран файл базы данных Microsoft SQL Server, а затем перейдите к файлу SampleDatabase.mdf и выберите его. Завершите добавление подключения, нажав кнопку «ОК«.

Создание таблиц и ключей с помощью конструктора таблиц

В этом разделе вы создадите две таблицы, первичный ключ в каждой таблице и несколько строк примеров данных. Вы также создаете внешний ключ, чтобы указать, как записи в одной таблице соответствуют записям в другой таблице.

Создание таблицы Customers

  1. В обозревателе объектов Сервера Обозреватель или SQL Server разверните узел «Данные Подключение ions«, а затем развернитеузел SampleDatabase.mdf.
  2. Щелкните правой кнопкой мыши таблицы и выберите «Добавить новую таблицу«. Будет открыт Конструктор таблиц, отобразится сетка с одной строкой по умолчанию, которая представляет один столбец в создаваемой таблице. Добавляя строки в сетку, вы добавляете столбцы в таблицу.
  3. В сетке добавьте строку для каждой из следующих записей.
Имя столбца Тип данных Разрешить значения null
CustomerID nchar(5) False (не установлен)
CompanyName nvarchar(50) False (не установлен)
ContactName nvarchar (50) True (установлен)
Phone nvarchar (24) True (установлен)
CREATE TABLE [dbo].[Customers] 
CONSTRAINT [PK_Customers] PRIMARY KEY ([CustomerID]) 

Отобразятся примерно следующие сведения:

Table Designer with Customers table

Table Designer with Customers table

Создание таблицы «Заказы»

  1. Создайте еще одну таблицу, а затем добавьте строку для каждой записи следующей таблицы.
Имя столбца Тип данных Разрешить значения null
OrderID int False (не установлен)
CustomerID nchar(5) False (не установлен)
OrderDate datetime True (установлен)
OrderQuantity int True (установлен)
CREATE TABLE [dbo].[Orders] 
CONSTRAINT [PK_Orders] PRIMARY KEY ([OrderId]) 

Tables node expanded in Server Explorer

Tables node expanded in Server Explorer

Создание внешнего ключа

  1. В области контекста справа от сетки конструктора таблиц для таблицы «Заказы» щелкните правой кнопкой мыши внешние ключи и выберите «Добавить новый внешний ключ«.

Add a foreign key in Table Designer in Visual Studio

Add a foreign key in Table Designer in Visual Studio

CONSTRAINT [FK_Orders_Customers] FOREIGN KEY ([CustomerID]) REFERENCES [Customers]([CustomerID]) 

Заполнение таблиц данными

  1. В обозреватель объектов Server Обозреватель или SQL Server разверните узел для примера базы данных.
  2. Откройте контекстное меню узла «Таблицы», выберите «Обновить» и разверните узел «Таблицы«.
  3. Откройте контекстное меню таблицы «Клиенты», а затем выберите «Показать данные таблицы» или «Просмотреть данные«.
  4. Добавьте все нужные данные для некоторых клиентов. Можно указать любые пять символов как ИД клиентов, но хотя бы один нужно выбрать и запомнить для дальнейшего использования в этой процедуре.
  5. Откройте контекстное меню таблицы «Заказы», а затем выберите «Показать данные таблицы» или «Просмотреть данные«.
  6. Добавьте данные для некоторых заказов. При вводе каждой строки она сохраняется в базе данных.

Важно! Убедитесь, что все идентификаторы заказов и количества заказов — целые числа, и каждый идентификатор клиента соответствует значению, указанному в столбце CustomerID таблицы клиентов.

Поздравляем! Теперь вы знаете, как создавать таблицы, связывать их с внешним ключом и добавлять данные.

Связанный контент

Отправка данных формы

В этой статье рассматривается, что происходит, когда пользователь отправляет форму — куда передаются данные и как мы их обрабатываем, когда они туда попадают? Мы также рассмотрим некоторые проблемы безопасности, связанные с отправкой данных формы.

Предварительные знания: Базовая компьютерная грамотность, понимание HTML и базовые знания по HTTP и программированию на стороне сервера.
Задача: Понять, что происходит при отправке данных формы, в том числе получить представление о том, как данные обрабатываются на стороне сервера.

Куда отправляются данные?

Здесь мы обсудим, что происходит с данными при отправке формы.

О клиентской/серверной архитектуре

A basic schema of the Web client/server architecture

WEB основан на очень простой клиент-серверной архитектуре, которую можно обобщить следующим образом: клиент (обычно веб-браузер) отправляет запрос на сервер (в основном веб-сервер, такой как Apache, Nginx, IIS, Tomcat, и т. д.), используя протокол HTTP. Сервер отвечает на запрос, используя тот же протокол.

На стороне клиента HTML-форма — это не более чем удобный способ настройки HTTP-запроса для отправки данных на сервер. Это позволяет пользователю предоставлять информацию для доставки в HTTP-запросе .

Примечание: Для получения более полного представления о том, как работают клиент-серверные архитектуры, ознакомьтесь с модулем «Первые шаги в программировании на стороне сервера».

На стороне клиента: определение способа отправки данных

Атрибут action

Этот атрибут определяет, куда отправляются данные. Его значение должно быть действительным URL. Если этот атрибут не указан, данные будут отправлены на URL-адрес страницы, содержащей форму.

В этом примере данные отправляются на абсолютный URL — http://foo.com :

form action="http://foo.com">form> 

Здесь мы используем относительный URL — данные отправляются на другой URL на сервере:

form action="/somewhere_else">form> 
form>form> 

Многие старые страницы используют следующий синтаксис, чтобы указать, что данные должны быть отправлены на ту же страницу, которая содержит форму; это было необходимо, потому что до появления HTML5 атрибут action был обязательным. Это больше не нужно.

form action="#">form> 

Примечание: Можно указать URL, который использует протокол HTTPS (безопасный HTTP). Когда вы делаете это, данные шифруются вместе с остальной частью запроса, даже если сама форма размещается на небезопасной странице, доступ к которой осуществляется через HTTP. С другой стороны, если форма размещается на защищённой странице, но вы указываете небезопасный URL-адрес HTTP с атрибутом action , все браузеры выдают пользователю предупреждение о безопасности при каждой попытке отправки данных, поскольку данные не шифруются.

Атрибут method

Этот атрибут определяет способ отправки данных. Протокол HTTP предоставляет несколько способов выполнить запрос; Данные HTML-формы могут передаваться несколькими различными способами, наиболее распространёнными из которых являются метод GET и метод POST .

Чтобы понять разницу между этими двумя методами, давайте вернёмся назад и рассмотрим, как работает HTTP. Каждый раз, когда вы хотите получить доступ к ресурсу в Интернете, браузер отправляет запрос на URL-адрес. HTTP-запрос состоит из двух частей: заголовка, который содержит набор глобальных метаданных о возможностях браузера, и тела, которое может содержать информацию, необходимую серверу для обработки конкретного запроса.

Метод GET

Метод GET — это метод, используемый браузером, который говорит серверу, что нужно отправить назад данный ресурс: «Эй, сервер, я хочу получить этот ресурс». В этом случае браузер отправляет пустое тело. Поскольку тело пустое, если форма отправляется с использованием данного метода, данные, отправляемые на сервер, добавляются к URL-адресу.

Рассмотрим следующую форму:

form action="http://foo.com" method="get"> div> label for="say">What greeting do you want to say?label> input name="say" id="say" value="Hi" /> div> div> label for="to">Who do you want to say it to?label> input name="to" id="to" value="Mom" /> div> div> button>Send my greetingsbutton> div> form> 

Поскольку используется метод GET , вы увидите URL www.foo.com/?say=Hi&to=Mom , который появится в адресной строке браузера при отправке формы.

Данные добавляются в URL как последовательность пар имя / значение. После того, как URL веб-адрес закончился, мы добавляем знак вопроса ( ? ), за которым следуют пары имя / значение, каждая из которых разделена амперсандом ( & ). В этом случае мы передаём две части данных на сервер:

  • say , со значением Hi
  • to , со значением Mom

HTTP-запрос имеет следующий вид:

GET /?say=Hi&to=Mom HTTP/2.0 Host: foo.com

Примечание: вы можете найти этот пример на GitHub — смотрите get-method.html (see it live also).

Метод POST

Метод POST немного отличается. Браузер использует этот метод для связи с сервером при запросе ответа с учётом данных, представленные в теле HTTP-запроса: «Эй, сервер, взгляни на эти данные и отправь мне соответствующий результат». Если форма отправляется с использованием этого метода, данные добавляются в тело HTTP-запроса.

Давайте рассмотрим пример — это та же самая форма, которую мы рассматривали в разделе GET выше, но с атрибутом method , установленным в post .

form action="http://foo.com" method="post"> div> label for="say">What greeting do you want to say?label> input name="say" id="say" value="Hi" /> div> div> label for="to">Who do you want to say it to?label> input name="to" id="to" value="Mom" /> div> div> button>Send my greetingsbutton> div> form> 

Когда форма отправляется с использованием метода POST , данные добавляются не к URL-адресу, а включаются в тело запроса. HTTP-запрос имеет следующий вид:

POST / HTTP/2.0 Host: foo.com Content-Type: application/x-www-form-urlencoded Content-Length: 13 say=Hi&to=Mom

Заголовок Content-Length указывает размер тела, а заголовок Content-Type указывает тип данных, отправляемых на сервер. Мы обсудим эти заголовки позже.

Примечание: вы можете найти этот пример на GitHub — смотрите post-method.html (see it live also).

Просмотр HTTP-запросов

HTTP-запросы никогда не отображаются пользователю (если вы хотите их видеть, вам нужно использовать такие инструменты, как Firefox Network Monitor или Chrome Developer Tools). Например, данные формы можно увидеть на вкладке Сеть (Network) в Chrome следующим образом (после отправки формы):

  1. Нажмите F12
  2. Выберите Network
  3. Выберите «All»
  4. Выберите «foo.com» во вкладке «Name»
  5. Выберите «Headers»

Затем вы можете получить данные формы, как показано на рисунке ниже.

Единственное, что отображается пользователю — вызываемый URL. Как упоминалось раннее, запрос с методом GET позволит пользователю увидеть информацию из запроса в URL, а запрос с методом POST не позволит. Две причины, почему это может быть важно:

  1. Если необходимо отправить пароль (или любую другую важную информацию), никогда не используйте метод GET , иначе рискуете отобразить эту информацию в URL-строке, что небезопасно.
  2. Если необходимо отправить большой объем информации, POST -метод является предпочтительным, так как некоторые браузеры ограничивают длину URL. К тому же, многие сервера так же ограничивают длину обрабатываемых URL.

На стороне сервера: получение данных

Какой бы HTTP вы не выбрали, сервер возвращает строку, которая будет последовательно проанализирована для получения данных в формате листа с парами ключ/значение. Способ получения доступа к этому листу зависит от платформы разработки или особенностей фреймворка, который вы можете использовать. Технологии, которые вы используете, определяют, как обрабатываются скопированные ключи. Часто, приоритетным является последнее полученное значение для данного ключа.

Пример: Чистый PHP

PHP предлагает несколько глобальных объектов для доступа к данным. Например, вы используете POST -метод, в приведённом ниже примере данные просто получаются и показываются пользователю. Разумеется, как использовать данные — решать только вам. Вы можете отобразить эти данные, поместить в базу данных, отправить по почте или передать эти данные куда-либо ещё.

 // The global $_POST variable allows you to access the data sent with the POST method by name // To access the data sent with the GET method, you can use $_GET $say = htmlspecialchars($_POST['say']); $to = htmlspecialchars($_POST['to']); echo $say, ' ', $to; ?> 

Пример показывает страницу с данными, которые мы отправили. Вы можете посмотреть это в действии в нашем файле с примером: php-example.html — который содержит те же данные, которые вы видели раньше: method : post и action из php-example.php . Когда данные переданы на отправку (submit), они переданы в форму php-example.php, которая содержит PHP код из примера выше. Когда код будет выполнен, браузер выведет (output) обработанное сообщение: Hi Mom .

Примечание: Этот пример не будет работать, когда вы загружаете его в браузер локально — браузер не может интерпретировать PHP код, после отправки данных из формы, браузер просто предложит загрузить PHP файл. Чтобы пример заработал, необходимо отправить его на PHP сервер. Для тестирования PHP на локальных серверах можете пробовать MAMP (Mac and Windows) и/или AMPPS (Mac, Windows, Linux).

Пример: Python

Этот пример показывает, как вы можете использовать Python для решения той же задачи — отобразить отправленные данные на странице. В этом примере используется Flask framework для визуализации шаблонов, поддерживающих форму отправки данных (смотри python-example.py).

from flask import Flask, render_template, request app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def form(): return render_template('form.html') @app.route('/hello', methods=['GET', 'POST']) def hello(): return render_template('greeting.html', say=request.form['say'], to=request.form['to']) if __name__ == "__main__": app.run() 

Два шаблона из коде выше взаимодействуют так:

  • form.html: Та же форма, что и выше The POST method , только с использованием action к > . (Это Jinja2 шаблон, который изначально HTML, но может содержать вызовы Python кода в фигурных скобках, которые запустятся веб-сервером. url_for(‘hello’) буквально говорит: после отправки данных переадресуй их в /hello .)
  • greeting.html: Этот шаблон просто содержит строку, которая отображает два бита данных, переданных ему при отображении. Это сделано с помощью функции hello() , указанной выше, которая выполняется, когда запрос направляется в /hello URL.

Примечание: Опять же, этот код не будет работать, если вы просто попробуете загрузить его прямо в браузер. Python работает немного иначе, чем PHP — чтобы запустить этот код, нужно установить Python/PIP, потом установить Flask используя команду: pip3 install flask . После этого, вы сможете запустить файл из примера, используя команду: python3 python-example.py , потом открыть localhost:5000 в своём браузере.

Другие языки и фреймворки

Существует множество других серверных технологий, которые вы можете использовать для работы с формами, включая языки Perl, Java, .Net, Ruby, и прочее. Выбирайте тот, который нравится больше. К тому же, использовать вышеупомянутые технологии непосредственно, без использования фреймворков, может быть сложно. Лучше использовать один из множества высококачественных фреймворков, таких как:

  • Django для Python (немного тяжеловеснее, чем Flask, но больше инструментов и опций)
  • Express для Node.js
  • Laravel для PHP
  • Ruby On Rails для Ruby
  • Phoenix для Elixir

Стоит отметить, что использование фреймворков и работа с формами — это не всегда легко. Но это намного легче, чем пытаться написать аналогичную функциональность с нуля, и это определённо сэкономит время.

Примечание: Обучению фреймворкам и работе с серверами не входит в рамки этой статьи. Если хотите узнать больше, ссылки ниже помогут в этом.

Особый случай: отправка файлов

Отправка файлов с помощью форм HTML — это особый случай. Файлы — это бинарные данные или рассматриваются как таковые, в то время как все остальные — это текстовые данные. Поскольку HTTP — это текстовый протокол, есть особые требования для работы с бинарными данными.

Атрибут enctype

Этот атрибут позволяет конкретизировать значение в Content-Type HTTP заголовок, включённый в запрос, при генерировании отправки формы. Этот заголовок очень важен, потому что указывает серверу, какой тип данных отправляется. По умолчанию это: application/x-www-form-urlencoded . На человеческом это значит: «Это форма с данными, которые были закодированы в URL параметры.»

Если хотите отправить файл, нужно сделать следующие три шага:

  • Указать method атрибут POST , поскольку содержимое файла, как и сам файл, не могут быть отображены в URL параметрах.
  • Установить в enctype значение multipart/form-data , потому что данные будут разбиты на несколько частей: одна часть на файл (две части на два файла), и одна часть на текстовые данные (при условии, если форма содержит поле для получения тестовых данных).
  • Подключите один или более File picker (en-US) виджетов, чтобы позволить своим пользователям выбрать, какие и сколько файлов будут загружены.
form method="post" enctype="multipart/form-data"> div> label for="file">Choose a filelabel> input type="file" id="file" name="myFile" /> div> div> button>Send the filebutton> div> form> 

Предупреждение: Многие сервера имеют заданные ограничения на размер загружаемых файлов и запросы от пользователей, чтобы защититься от возможных злоупотреблений. Важно проверять эти ограничения у администратора сервера, прежде чем загружать файлы.

Проблемы безопасности

Каждый раз, когда вы отправляете данные на сервер, вы должны учитывать безопасность. HTML-формы являются наиболее распространёнными векторами атак на серверы(места, где могут происходить атаки). Проблемы вытекают не из самих форм HTML, а из-за того, как сервер обрабатывает данные из этих форм.

В зависимости от того, что вы делаете, вы можете столкнуться с некоторыми очень известными проблемами безопасности:

XSS «Межсайтовый скриптинг» и CSRF «Подделка межсайтовых запросов»

Межсайтовый скриптинг (XSS «Cross Site Request Forgery») и подделка межсайтовых запросов (CSRF «Cross-Site Scripting») — это распространённые типы атак, которые происходят при отображении данных после ответа сервера или другого пользователя.

Межсайтовый скриптинг (XSS «Cross Site Request Forgery») позволяет злоумышленникам внедрить клиентский скрипт в веб-страницы, просматриваемые другими пользователями. Подделка межсайтовых запросов (CSRF «Cross-Site Scripting») может использоваться злоумышленниками для обхода средств контроля доступа, таких как одна и та же политика происхождения. Последствие от этих атак может варьироваться от мелких неудобств до значительного риска безопасности.

CSRF-атаки аналогичны XSS-атакам в том, что они начинаются одинаково — с внедрения клиентского скрипта в веб-страницы — но их конечные цели разные. Злоумышленники CSRF пытаются назначить права пользователям с более высоким уровнем прав доступа(например, администратору сайта), чтобы выполнить действие, которое они не должны выполнять (например, отправка данных ненадёжному пользователю). Атаки XSS используют доверие пользователя к веб-сайту, в то время как атаки CSRF используют доверие веб-сайта к пользователю.

Чтобы предотвратить эти атаки, вы всегда должны проверять данные, которые пользователь отправляет на ваш сервер, и (если вам нужно отобразить их) стараться не отображать HTML-контент, предоставленный пользователем. Вместо этого вы должны обработать предоставленные пользователем данные, чтобы не отображать их слово в слово. Сегодня почти все платформы на рынке реализуют минимальный «фильтр», который удаляет элементы HTML , (en-US) и (en-US) полученных от любого пользователя. Это помогает снизить риск, но не исключает его полностью.

SQL — вброс

SQL -вброс представляет собой тип атак, при которых осуществляется попытка выполнения действия с базой данных, используемой целевым веб-сайтом. В этих случаях обычно осуществляется отправка SQL-запроса в надежде, что сервер выполнит этот запрос (обычно при попытке сервера приложения сохранить данные, отправляемые пользователем). Данный вид атак является одним из самых направленных атак на веб-сайты.

Последствия могут быть ужасающими, начиная от потери данных и заканчивая утратой контроля над всей инфраструктурой веб-сайта за счёт повышения привилегий. Это очень серьёзная угроза, поэтому никогда не сохраняйте данные, отправляемые пользователем, без выполнения фильтрации данных (например, с помощью mysqli_real_escape_string() .

Вброс HTTP-заголовка и email

Эти виды атак могут проявляться, когда ваше приложение создаёт заголовки HTTP или электронные почтовые адреса на основании данных, введённых пользователем в форму. Такие атаки напрямую не повреждают сервер или пользователей, однако создают уязвимость для таких угроз, как перехват сессии, или для фишинговых атак.

Такие атаки являются самыми незаметными, но при этом могут превратить ваш сервер в зомби.

Будьте параноиком: никогда не доверяйте вашим пользователям

Как вы боретесь с такими угрозами? Этот вопрос выходит далеко за рамки данной статьи, но есть несколько общих правил, которые следует всегда соблюдать. Самое важное из них — никогда не доверяйте вашим пользователям, в том числе себе; даже проверенный пользователь может быть атакован.

Все данные, поступающие на ваш сервер, необходимо проверять и санитизировать. Все и всегда. Без исключений.

  • Избегайте потенциально опасных символов. Конкретные символы, с которыми следует соблюдать осторожность, зависят от контекста, в котором используются данные, а также от используемой платформы. Однако, все языки на стороне сервера имеют соответствующие функции для обеспечения такой защиты.
  • Ограничьте входящий объем данных для поступления только реально необходимых данных.
  • Помещайте загруженные файлы в песочницу (храните их на другом сервере и предоставляйте доступ к файлам только через отдельный поддомен или даже через совершенно другое доменное имя).

Соблюдая эти три правила, вы сможете избежать многих/большинства проблем. При этом следует помнить, что периодически необходимо проводить анализ защищённости, желательно квалифицированной сторонней организацией. Не считайте, что вы уже сталкивались со всеми возможными угрозами.

Примечание: В статье Безопасность веб-сайта нашего раздела серверного обучения приведено подробное обсуждение упомянутых угроз и возможных способов их устранения.

Заключение

Как мы увидели, отправлять формы просто, однако защитить приложение может быть довольно трудно. Просто помните, что фронтенд разработчики не должны задавать модель безопасности для приложения. Да, как мы увидим далее, мы можем проверить данные на стороне клиента, однако сервер не может доверять этой проверке, потому что он никогда не может по-настоящему узнать что происходит на стороне клиента.

Смотрите также

Если вы хотите узнать больше об обеспечении безопасности веб-приложений, вы можете использовать следующие источники информации:

  • Первые шаги в программирование веб-сайтов на стороне сервера
  • Открытый проект обеспечения веб-безопасности приложений (OWASP)
  • Веб-безопасность от Mozilla
  • Назад (en-US)
  • Обзор: Forms
  • Далее (en-US)

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 2 дек. 2023 г. by MDN contributors.

Your blueprint for a better internet.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *