Интеграция 1С в приложение ASP.NET (C#)
Всем доброе время суток!
Столкнулся вот с такой задачей: есть сайт, написан на ASP.NET (C#), есть база данных (1С). Так вот, сейчас используется такая схема: в 1С есть уже написанные модули, которые формируют XML файл, а уже сайт считывает этот файл и, согласно его содержимому, формирует данные и отображает их на странице.
Вопрос: можно ли напрямую подключиться к базе данных 1С, как, например, к MS SQL SERVER? Чтобы изменения, внесенные в 1С, сразу попадали на сайт. Из сайта данные нужно только просматривать, т.е. вносить изменений в базу 1С через ASP не нужно.
Что-то слышал о COM-соединении, но что-то не нашел нормальных описаний или примеров...
Спасибо!
Столкнулся вот с такой задачей: есть сайт, написан на ASP.NET (C#), есть база данных (1С). Так вот, сейчас используется такая схема: в 1С есть уже написанные модули, которые формируют XML файл, а уже сайт считывает этот файл и, согласно его содержимому, формирует данные и отображает их на странице.
Вопрос: можно ли напрямую подключиться к базе данных 1С, как, например, к MS SQL SERVER? Чтобы изменения, внесенные в 1С, сразу попадали на сайт. Из сайта данные нужно только просматривать, т.е. вносить изменений в базу 1С через ASP не нужно.
Что-то слышал о COM-соединении, но что-то не нашел нормальных описаний или примеров...
Спасибо!
По теме из базы знаний
- 1С для .NET. Средства интеграции.
- Необычно-экономное использование 1С:Предприятие 8 на Asp.Net-хостинге для реализации Интернет-магазина
- Веб-сервер многопоточный с обработкой запросов в коде 1С (1C.Net:Предприятие)
- 10 шагов для создания стартапа на основе 1С: Предприятие и Asp.Net MVC
- 1Script.Web. Интернет-приложения на языке 1С
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Я бы не советовал напрямую "лезть" в базу 1С из скриптов ASP.NET. Гораздо лучше, если автоматизировать процесс выгрузки данных их 1С на сайт. Сделать в самой 1С-ке так, чтобы раз в определенный промежуток времени (5-10 мин.?) производилась выгрузка изменений (например в тот же XML), а затем уже отображать эти изменения на сайте. В одном нашем проекте именно так и реализовано. Работает вполне приемлемо.
Пример создания документа:
V81.COMConnectorClass v81connector = new V81.COMConnectorClass();
object v81base = v81connector.Connect("File=\"C:\\base\";Usr=\"test\";");
object v8_deb = v81base.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81base, new object[] { "СправочникМенеджер.Контрагенты" });
object v8_deb_select = v8_deb.GetType().InvokeMember("НайтиПоКоду", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v8_deb, new object[] { "V00000665" });
object v8_cre = v81base.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81base, new object[] { "СправочникМенеджер.Организации" });
object v8_cre_select = v8_deb.GetType().InvokeMember("НайтиПоКоду", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v8_cre, new object[] { "000000002" });
object v81docs = v81base.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81base, new object[] { "ДокументМенеджер.ЗаказПокупателя" });
object v81newDoc = v81docs.GetType().InvokeMember("CreateDocument", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81docs, null);
v81newDoc.GetType().InvokeMember("Дата", BindingFlags.PutDispProperty | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, v81newDoc, new object[] { DateTime.Now });
v81newDoc.GetType().InvokeMember("Организация", BindingFlags.PutDispProperty | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, v81newDoc, new object[] { v8_cre_select });
v81newDoc.GetType().InvokeMember("Контрагент", BindingFlags.PutDispProperty | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, v81newDoc, new object[] {v8_deb_select});
v81newDoc.GetType().InvokeMember("Write", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81newDoc, null);
V81.COMConnectorClass v81connector = new V81.COMConnectorClass();
object v81base = v81connector.Connect("File=\"C:\\base\";Usr=\"test\";");
object v8_deb = v81base.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81base, new object[] { "СправочникМенеджер.Контрагенты" });
object v8_deb_select = v8_deb.GetType().InvokeMember("НайтиПоКоду", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v8_deb, new object[] { "V00000665" });
object v8_cre = v81base.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81base, new object[] { "СправочникМенеджер.Организации" });
object v8_cre_select = v8_deb.GetType().InvokeMember("НайтиПоКоду", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v8_cre, new object[] { "000000002" });
object v81docs = v81base.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81base, new object[] { "ДокументМенеджер.ЗаказПокупателя" });
object v81newDoc = v81docs.GetType().InvokeMember("CreateDocument", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81docs, null);
v81newDoc.GetType().InvokeMember("Дата", BindingFlags.PutDispProperty | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, v81newDoc, new object[] { DateTime.Now });
v81newDoc.GetType().InvokeMember("Организация", BindingFlags.PutDispProperty | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, v81newDoc, new object[] { v8_cre_select });
v81newDoc.GetType().InvokeMember("Контрагент", BindingFlags.PutDispProperty | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, v81newDoc, new object[] {v8_deb_select});
v81newDoc.GetType().InvokeMember("Write", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81newDoc, null);
Код выбирает все документы типа "НашДокумент", в цикле обходит коллекцию, выбирая некие атрибуты каждого документа
var v81comConnector = Type.GetTypeFromProgID("V81.ComConnector");
var v81 = Activator.CreateInstance(v81comConnector);
Object[] arguments = { @"File=""ПУТЬ_К_ИНФОРМАЦИОННОЙ_БАЗЕ"";Usr=""ИМЯ_ПОЛЬЗОВАТЕЛЯ_ИБ"";" };
var x = v81comConnector.InvokeMember("Connect", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81, arguments);
var objDocs_ = GetObjectProperty(v81, x, "Документы");
var docEvent_ = GetObjectProperty(v81, objDocs_, "НашДокумент");
var docSelection_ = InvokeObjectMethod(v81, docEvent_, "Выбрать", new Object[] {});
while ((bool) InvokeObjectMethod(v81, docSelection_, "Следующий", new Object[] {}))
{
var eventID_ = GetObjectProperty(v81, docSelection_, "Номер");
var eventResponsibleObj_ = GetObjectProperty(v81, docSelection_, "Ответственный");
var eventResponsible_ = GetObjectProperty(v81, eventResponsibleObj_, "Description");
var eventBeginning_ = GetObjectProperty(v81, docSelection_, "НачалоСобытия");
var eventEnd_ = GetObjectProperty(v81, docSelection_, "ОкончаниеСобытия");
Console.WriteLine("Информация о событии:");
Console.WriteLine("ID: " + eventID_);
}
public object GetObjectProperty(object v81, object refObject, string propertyName)
{
return v81.GetType().InvokeMember(propertyName, BindingFlags.GetProperty, null, refObject, null);
}
public object InvokeObjectMethod(object v81, object refObject, string methodName, Object[] parameters)
{
return v81.GetType().InvokeMember(methodName, BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, refObject, parameters);
}
var v81comConnector = Type.GetTypeFromProgID("V81.ComConnector");
var v81 = Activator.CreateInstance(v81comConnector);
Object[] arguments = { @"File=""ПУТЬ_К_ИНФОРМАЦИОННОЙ_БАЗЕ"";Usr=""ИМЯ_ПОЛЬЗОВАТЕЛЯ_ИБ"";" };
var x = v81comConnector.InvokeMember("Connect", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, v81, arguments);
var objDocs_ = GetObjectProperty(v81, x, "Документы");
var docEvent_ = GetObjectProperty(v81, objDocs_, "НашДокумент");
var docSelection_ = InvokeObjectMethod(v81, docEvent_, "Выбрать", new Object[] {});
while ((bool) InvokeObjectMethod(v81, docSelection_, "Следующий", new Object[] {}))
{
var eventID_ = GetObjectProperty(v81, docSelection_, "Номер");
var eventResponsibleObj_ = GetObjectProperty(v81, docSelection_, "Ответственный");
var eventResponsible_ = GetObjectProperty(v81, eventResponsibleObj_, "Description");
var eventBeginning_ = GetObjectProperty(v81, docSelection_, "НачалоСобытия");
var eventEnd_ = GetObjectProperty(v81, docSelection_, "ОкончаниеСобытия");
Console.WriteLine("Информация о событии:");
Console.WriteLine("ID: " + eventID_);
}
public object GetObjectProperty(object v81, object refObject, string propertyName)
{
return v81.GetType().InvokeMember(propertyName, BindingFlags.GetProperty, null, refObject, null);
}
public object InvokeObjectMethod(object v81, object refObject, string methodName, Object[] parameters)
{
return v81.GetType().InvokeMember(methodName, BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, refObject, parameters);
}
Механизмов подключиться к 1С несколько- COM, OLE к примеру. Например,Вы используете comcntr.dll. Там есть два COM объекта
v81.Application и V81.COMConnectorClass... и соединение в таком случае происходит через т.н. "позднее связывание":object v8 = Activator.CreateInstance(Type.GetTypeFromProgID("V81.Application"));
object[] connectargs = new object[1];
connectargs[0] = @"File=D:\1CBases\DB1;Usr=Admin";
if ((bool)v8.GetType().InvokeMember("Connect", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod, null, v8, connectargs))
{
v8 = null;
}
Если создаете пользователя для подключения - не забудьте раздать ему права на запуск 1С через OLE Automation...
v81.Application и V81.COMConnectorClass... и соединение в таком случае происходит через т.н. "позднее связывание":object v8 = Activator.CreateInstance(Type.GetTypeFromProgID("V81.Application"));
object[] connectargs = new object[1];
connectargs[0] = @"File=D:\1CBases\DB1;Usr=Admin";
if ((bool)v8.GetType().InvokeMember("Connect", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod, null, v8, connectargs))
{
v8 = null;
}
Если создаете пользователя для подключения - не забудьте раздать ему права на запуск 1С через OLE Automation...
была у меня такая задача. Решение:
1) Создал еще одну базу на сервере sql где написал хранимые процедуры для выборки данных с базы 1с
2) Трасервкой нашел таблицы в базе 1 которые надо
3) добавил документ интернет заказ в 1с
4) С своей sql базы обновлял таблицу интернет заказа в 1с sql
5) на основании интренет заказа юзер делал заказ покупателя
все
1) Создал еще одну базу на сервере sql где написал хранимые процедуры для выборки данных с базы 1с
2) Трасервкой нашел таблицы в базе 1 которые надо
3) добавил документ интернет заказ в 1с
4) С своей sql базы обновлял таблицу интернет заказа в 1с sql
5) на основании интренет заказа юзер делал заказ покупателя
все
Работа непростая. Могу привести небольшой код для примера...
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.Security;
public partial class auth : System.Web.UI.Page
{
string strConnection = "user id=_ПОЛЬЗОВАТЕЛЬ_;data source=_ИМЯ_СЕРВЕРА_; persist security info=True; password=_ПАРОЛЬ_; initial catalog = _ИМЯ_ИНФО_БАЗЫ_НА_SQL_СЕРВЕРЕ_";
SqlConnection sqlConn;
protected void Page_Load(object sender, EventArgs e)
{
Page.Title = "ПРИМЕР ЧТЕНИЯ ДАННЫХ";
}
protected void Page_Unload(object sender, EventArgs e)
{
}
protected void btnВойти_Click(object sender, EventArgs e)
{
// ДО ЗВЁЗДОЧЕК НЕ ВНИКАТЬ - ТУТ ОБЪВЛЕНИЕ АВТОРИЗАЦИИ (form autorisation) для странички
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, "user", System.DateTime.Now, System.DateTime.Now.AddMinutes(60), false, String.Empty);
string encTicket = FormsAuthentication.Encrypt(authTicket);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
// ***** ТУТ ВНИКАТЬ
// подключаемся к SQL
sqlConn = new SqlConnection(strConnection);
try
{
sqlConn.Open();
}
catch(Exception error_e)
{
Console.WriteLine(error_e.ToString());
}
// создаём команду для чтения данных
// поищи в нете СтруктураБД.epf для того чтобы знать что именно в SQL таблицах нужно
// там соответствие имён 1с и SQL
SqlCommand myCommand = new SqlCommand("SELECT * FROM _Reference11 WHERE _Description = @Param1", sqlConn);
String SelectExhib = "Событие 2012 года";
SqlParameter Param1 = new SqlParameter("@Param1", SqlDbType.VarChar, 70);
Param1.Value = SelectExhib;
myCommand.Parameters.Add(Param1);
SqlDataReader myReader = null;
myReader = myCommand.ExecuteReader();
// в муридере будут данные из строки запроса.
while(myReader.Read())
{
Session["Выставка"] = myReader["_IDRRef"];
Session["Выставка.Наименование"] = myReader["_Description"].ToString();
}
//Page.RegisterStartupScript("alert", "<script>alert('"+NameExh+"');</script>");
//Обязательно закрой дата ридер. чтобы вызвалось dispos() и освободило память
myReader.Close():
// закрываем подключение. Оно останеться на сервере и унитожиться само по себе через некоторое время
try
{
sqlConn.Close();
}
catch(Exception error_e2)
{
Console.WriteLine(error_e2.ToString());
}
}
}
Тут только пример файла с кодом ASPX
Сама страничка ниже:
Шаблон:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="auth.aspx.cs" Inherits="auth" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>ПРИМЕР</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR" />
<meta content="C#" name="CODE_LANGUAGE" />
<meta content="JavaScript" name="vs_defaultClientScript" />
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema" />
<link rel="stylesheet" type="text/css" href="styles.css">
<link rel="stylesheet" type="text/css"
</head>
<body>
<!-- CONTENT -->
<form id="form1" runat="server">
<table align="center" border=0 width="100%">
<tr>
<td>
</td>
<td align="middle">
<asp:Panel ID="Panel1" runat="server" BackColor="White" BorderColor="White" BorderStyle="Outset"
BorderWidth="0px" Width="100%" align="middle">
</asp:Panel>
</td>
</tr>
</table>
</form>
<!-- CONTENT END -->
</body>
</html>
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.Security;
public partial class auth : System.Web.UI.Page
{
string strConnection = "user id=_ПОЛЬЗОВАТЕЛЬ_;data source=_ИМЯ_СЕРВЕРА_; persist security info=True; password=_ПАРОЛЬ_; initial catalog = _ИМЯ_ИНФО_БАЗЫ_НА_SQL_СЕРВЕРЕ_";
SqlConnection sqlConn;
protected void Page_Load(object sender, EventArgs e)
{
Page.Title = "ПРИМЕР ЧТЕНИЯ ДАННЫХ";
}
protected void Page_Unload(object sender, EventArgs e)
{
}
protected void btnВойти_Click(object sender, EventArgs e)
{
// ДО ЗВЁЗДОЧЕК НЕ ВНИКАТЬ - ТУТ ОБЪВЛЕНИЕ АВТОРИЗАЦИИ (form autorisation) для странички
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, "user", System.DateTime.Now, System.DateTime.Now.AddMinutes(60), false, String.Empty);
string encTicket = FormsAuthentication.Encrypt(authTicket);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
// ***** ТУТ ВНИКАТЬ
// подключаемся к SQL
sqlConn = new SqlConnection(strConnection);
try
{
sqlConn.Open();
}
catch(Exception error_e)
{
Console.WriteLine(error_e.ToString());
}
// создаём команду для чтения данных
// поищи в нете СтруктураБД.epf для того чтобы знать что именно в SQL таблицах нужно
// там соответствие имён 1с и SQL
SqlCommand myCommand = new SqlCommand("SELECT * FROM _Reference11 WHERE _Description = @Param1", sqlConn);
String SelectExhib = "Событие 2012 года";
SqlParameter Param1 = new SqlParameter("@Param1", SqlDbType.VarChar, 70);
Param1.Value = SelectExhib;
myCommand.Parameters.Add(Param1);
SqlDataReader myReader = null;
myReader = myCommand.ExecuteReader();
// в муридере будут данные из строки запроса.
while(myReader.Read())
{
Session["Выставка"] = myReader["_IDRRef"];
Session["Выставка.Наименование"] = myReader["_Description"].ToString();
}
//Page.RegisterStartupScript("alert", "<script>alert('"+NameExh+"');</script>");
//Обязательно закрой дата ридер. чтобы вызвалось dispos() и освободило память
myReader.Close():
// закрываем подключение. Оно останеться на сервере и унитожиться само по себе через некоторое время
try
{
sqlConn.Close();
}
catch(Exception error_e2)
{
Console.WriteLine(error_e2.ToString());
}
}
}
Тут только пример файла с кодом ASPX
Сама страничка ниже:
Шаблон:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="auth.aspx.cs" Inherits="auth" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>ПРИМЕР</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR" />
<meta content="C#" name="CODE_LANGUAGE" />
<meta content="JavaScript" name="vs_defaultClientScript" />
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema" />
<link rel="stylesheet" type="text/css" href="styles.css">
<link rel="stylesheet" type="text/css"
</head>
<body>
<!-- CONTENT -->
<form id="form1" runat="server">
<table align="center" border=0 width="100%">
<tr>
<td>
</td>
<td align="middle">
<asp:Panel ID="Panel1" runat="server" BackColor="White" BorderColor="White" BorderStyle="Outset"
BorderWidth="0px" Width="100%" align="middle">
</asp:Panel>
</td>
</tr>
</table>
</form>
<!-- CONTENT END -->
</body>
</html>
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот