Добрый день! Подскажите, пожалуйста, каким образом необходимо корректно формировать SelectRequest, для того что бы получить всю таблицу из бд?
Нашел информацию по этой ссылке:https://academy.terrasoft.ru/documents/technic-sdk/7-12/dataservice-cht…
Тут именно тот код:
//------------------------------------------------------------------------------
// Экземпляр класса запроса. var selectQuery = new SelectQuery() { // Название корневой схемы. RootSchemaName = "Contact", // Коллекция колонок запроса. Columns = new SelectQueryColumns() }; // Выражение, задающее тип колонки [[ФИО]. var columnExpressionName = new ColumnExpression() { // Тип выражения — колонка схемы. ExpressionType = EntitySchemaQueryExpressionType.SchemaColumn, // Путь к колонке. ColumnPath = "Name" }; // Конфигурирование колонки [Name]. var selectQueryColumnName = new SelectQueryColumn() { //Заголовок. Caption = "ФИО", // Направление сортировки — по возрастанию. OrderDirection = OrderDirection.Ascending, // Позиция порядка сортировки. OrderPosition = 0, // Выражение, задающее тип колонки. Expression = columnExpressionName }; // Выражение, задающее тип колонки [Количество активностей]. var columnExpressionActivitiesCount = new ColumnExpression() { // Тип выражения — вложенный запрос. ExpressionType = EntitySchemaQueryExpressionType.SubQuery, // Путь к колонке относительно корневой схемы. ColumnPath = "[Activity:Contact].Id", // Тип функции — агрегирующая. FunctionType = FunctionType.Aggregation, // Тип агрегации — количество. AggregationType = AggregationType.Count };
//------------------------------------------------------------------------------
В данном случае, у меня к примеру нет заголовка "ФИО", у меня есть просто столбец "Name"("ФИО" в данном случае это есть то как будут отображаться полученные данные или это именно часть таблицы к которой я обращаюсь?)
В данном случае, авторизация к серверу проходит успешно, но при попытке считать результат выполнения запроса, выпадает ошибка:
"Exception thrown: 'System.Net.WebException' in System.dll"
Нравится
engineer7 пишет:
и ошибок он не выдает...
Защиту от CSRF атак выключили? Просто добавление токена не наблюдаю. Попробуйте до вызова
using (var requestStream = selectRequest.GetRequestStream())
// Добавление CSRF-токена в заголовок запроса. CookieCollection cookieCollection = AuthCookie.GetCookies(new Uri(authServiceUri)); string csrfToken = cookieCollection["BPMCSRF"].Value; selectRequest.Headers.Add("BPMCSRF", csrfToken);
Указанный пример — это при работе с системой извне. Если просто в серверном коде получать данные из таблицы, см. тут.
Если Вам действительно нужно работать с удалённым сайтом по веб-сервисам, то причина может быть аналогичная этому обсуждению, где сервер возвращает 404.
Зверев Александр пишет:
Указанный пример — это при работе с системой извне. Если просто в серверном коде получать данные из таблицы, см. тут.
Если Вам действительн...
Александр, спасибо за ответ!
В данном случае, меня интересует второй случай, когда нужно работать с удаленным сайтом по веб-сервисам, но дело в том, что сервер возвращает не 404(нет ответа) ошибку, а 403(проблемы с доступом).
Возможно такое что я не правильно заполняю конфигурирование запроса?
// Экземпляр класса запроса.
var selectQuery = new SelectQuery()
{
// Название корневой схемы.
RootSchemaName = "Contact",
// Коллекция колонок запроса.
Columns = new SelectQueryColumns()
};
// Выражение, задающее тип колонки [[ФИО].
var columnExpressionName = new ColumnExpression()
{
// Тип выражения — колонка схемы.
ExpressionType = EntitySchemaQueryExpressionType.SchemaColumn,
// Путь к колонке.
ColumnPath = "Name"
};
// Конфигурирование колонки [Name].
var selectQueryColumnName = new SelectQueryColumn()
{
//Загловок.
Caption = "",
// Направление сортировки — по возрастанию.
OrderDirection = OrderDirection.Ascending,
// Позиция порядка сортировки.
OrderPosition = 0,
// Выражение, задающее тип колонки.
Expression = columnExpressionName
};
// Выражение, задающее тип колонки [Количество активностей].
var columnExpressionActivitiesCount = new ColumnExpression()
{
// Тип выражения — вложенный запрос.
ExpressionType = EntitySchemaQueryExpressionType.SubQuery,
// Путь к колонке относительно корневой схемы.
ColumnPath = "[Activity:Contact].Id",
// Тип функции — агрегирующая.
FunctionType = FunctionType.Aggregation,
// Тип агрегации — количество.
AggregationType = AggregationType.Count
};
// Конфигурирование колонки [Количество активностей].
var selectQueryColumnActivitiesCount = new SelectQueryColumn()
{
//Загловок.
Caption = "",
// Направление сортировки — по возрастанию.
OrderDirection = OrderDirection.Ascending,
// Позиция порядка сортировки.
OrderPosition = 1,
// Выражение, задающее тип колонки.
Expression = columnExpressionActivitiesCount
};
// Добавление колонок в запрос.
selectQuery.Columns.Items = new Dictionary<string, SelectQueryColumn>()
{
{
"Name",
selectQueryColumnName
},
{
"ActivitiesCount",
selectQueryColumnActivitiesCount
}
};
// Сериализация экземпляра класса запроса на добавление в JSON-строку.
var json = new JavaScriptSerializer().Serialize(selectQuery);
// Преобразование строки JSON-объекта в массив байтов.
byte[] jsonArray = Encoding.UTF8.GetBytes(json);
// Создание экземпляра HTTP-запроса.
var selectRequest = HttpWebRequest.Create(selectQueryUri) as HttpWebRequest;
// Определение метода запроса.
selectRequest.Method = "POST";
// Определение типа содержимого запроса.
selectRequest.ContentType = "application/json";
// Добавление полученных ранее аутентификационных cookie в запрос на получение данных.
selectRequest.CookieContainer = AuthCookie;
// Установить длину содержимого запроса.
selectRequest.ContentLength = jsonArray.Length;
using (var requestStream = selectRequest.GetRequestStream())
{
requestStream.Write(jsonArray, 0, jsonArray.Length);
}
ResponseStatus status = null;
// Получение ответа от сервера. Если аутентификация проходит успешно, в свойство AuthCookie будут
// помещены cookie, которые могут быть использованы для последующих запросов.
using (var response = (HttpWebResponse)selectRequest.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
// Десериализация HTTP-ответа во вспомогательный объект.
string responseText = reader.ReadToEnd();
status = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<ResponseStatus>(responseText);
}
}
В данном случае, конфигурирование колонки [name], каким образом нужно заполнять поле "Caption"?
Так как по умолчанию стояла запись "ФИО", я ее удалил, так как в таблице "Contact" у меня нет данного столбца.
Так же я не очень хорошо понимаю значение выражения, задающее тип колонки (количество активностей).
Пример, по которому пытаюсь получить доступ к БД: https://academy.terrasoft.ru/documents/technic-sdk/7-12/dataservice-cht…
Если с доступом, то, возможно, не передалась кука, полученная от AuthService. Если не уверены в доработках, сначала попробуйте со скопированными без изменений примерами.
Попробовал с исходным кодом:
// ----------------------------------------------
using System;
using System.Text;
using System.IO;
using System.Net;
using System.Collections.Generic;
using Terrasoft.Nui.ServiceModel.DataContract;
using Terrasoft.Core.Entities;
using System.Web.Script.Serialization;
using Terrasoft.Common;
namespace DataServiceSelectExample
{
class Program
{
// Основной URL приложения bpm'online. Необходимо заменить на пользовательский.
private const string baseUri = @"http://url";
// Строка запроса к методу Login сервиса AuthService.svc.
private const string authServiceUri = baseUri + @"/ServiceModel/AuthService.svc/Login";
// Строка пути запроса SelectQuery.
private const string selectQueryUri = baseUri + @"/0/DataService/json/SyncReply/SelectQuery";
// Cookie аутентификации bpm'online.
private static CookieContainer AuthCookie = new CookieContainer();
// Метод выполняет аутентификацию пользователя.
// Параметры:
// userName — имя пользователя bpm'online,
// userPassword — пароль пользователя bpm'online.
private static bool TryLogin(string userName, string userPassword)
{
// Создание экземпляра запроса к сервису аутентификации.
var authRequest = HttpWebRequest.Create(authServiceUri) as HttpWebRequest;
// Определение метода HTTP-запроса.
authRequest.Method = "POST";
// Определение типа контента запроса.
authRequest.ContentType = "application/json";
// Включение использования cookie в запросе.
authRequest.CookieContainer = AuthCookie;
// Помещение в тело запроса учетной информации пользователя.
using (var requesrStream = authRequest.GetRequestStream())
{
using (var writer = new StreamWriter(requesrStream))
{
writer.Write(@"{
""UserName"":""" + userName + @""",
""UserPassword"":""" + userPassword + @"""
}");
}
}
// Получение ответа от сервера. Если аутентификация проходит успешно, в свойство AuthCookie будут
// помещены cookie, которые могут быть использованы для последующих запросов.
using (var response = (HttpWebResponse)authRequest.GetResponse())
{
if (AuthCookie.Count > 0)
{
return true;
}
}
return false;
}
// Главный метод приложения.
static void Main(string[] args)
{
// Если выполнение аутентификации неудачно, приложение завершает работу.
if (!TryLogin("login", "password"))
{
Console.WriteLine("Ошибка аутентификации!");
return;
}
// Экземпляр класса запроса.
var selectQuery = new SelectQuery()
{
// Название корневой схемы.
RootSchemaName = "Contact",
// Коллекция колонок запроса.
Columns = new SelectQueryColumns()
};
// Выражение, задающее тип колонки [[ФИО].
var columnExpressionName = new ColumnExpression()
{
// Тип выражения — колонка схемы.
ExpressionType = EntitySchemaQueryExpressionType.SchemaColumn,
// Путь к колонке.
ColumnPath = "Name"
};
// Конфигурирование колонки [Name].
var selectQueryColumnName = new SelectQueryColumn()
{
//Загловок.
Caption = "ФИО",
// Направление сортировки — по возрастанию.
OrderDirection = OrderDirection.Ascending,
// Позиция порядка сортировки.
OrderPosition = 0,
// Выражение, задающее тип колонки.
Expression = columnExpressionName
};
// Выражение, задающее тип колонки [Количество активностей].
var columnExpressionActivitiesCount = new ColumnExpression()
{
// Тип выражения — вложенный запрос.
ExpressionType = EntitySchemaQueryExpressionType.SubQuery,
// Путь к колонке относительно корневой схемы.
ColumnPath = "[Activity:Contact].Id",
// Тип функции — агрегирующая.
FunctionType = FunctionType.Aggregation,
// Тип агрегации — количество.
AggregationType = AggregationType.Count
};
// Конфигурирование колонки [Количество активностей].
var selectQueryColumnActivitiesCount = new SelectQueryColumn()
{
//Загловок.
Caption = "Количество активностей",
// Направление сортировки — по возрастанию.
OrderDirection = OrderDirection.Ascending,
// Позиция порядка сортировки.
OrderPosition = 1,
// Выражение, задающее тип колонки.
Expression = columnExpressionActivitiesCount
};
// Добавление колонок в запрос.
selectQuery.Columns.Items = new Dictionary<string, SelectQueryColumn>()
{
{
"Name",
selectQueryColumnName
},
{
"ActivitiesCount",
selectQueryColumnActivitiesCount
}
};
// Сериализация экземпляра класса запроса на добавление в JSON-строку.
var json = new JavaScriptSerializer().Serialize(selectQuery);
// Преобразование строки JSON-объекта в массив байтов.
byte[] jsonArray = Encoding.UTF8.GetBytes(json);
// Создание экземпляра HTTP-запроса.
var selectRequest = HttpWebRequest.Create(selectQueryUri) as HttpWebRequest;
// Определение метода запроса.
selectRequest.Method = "POST";
// Определение типа содержимого запроса.
selectRequest.ContentType = "application/json";
// Добавление полученных ранее аутентификационных cookie в запрос на получение данных.
selectRequest.CookieContainer = AuthCookie;
// Установить длину содержимого запроса.
selectRequest.ContentLength = jsonArray.Length;
// Помещение JSON-объекта в содержимое запроса .
using (var requestStream = selectRequest.GetRequestStream())
{
requestStream.Write(jsonArray, 0, jsonArray.Length);
}
// Выполнение HTTP-запроса и получение ответа от сервера.
using (var response = (HttpWebResponse)selectRequest.GetResponse())
{
// Вывод ответа в консоль.
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
Console.WriteLine(reader.ReadToEnd());
}
}
// Задержка выполнения приложения.
Console.ReadKey();
}
}
}
// ----------------------------------------------
На вот этом месте возникает ошибка:
// ----------------------------------------------
// Выполнение HTTP-запроса и получение ответа от сервера.
using (var response = (HttpWebResponse)selectRequest.GetResponse())
Сложно сказать, не видя конкретных запросов и ответов на них в Fiddler.
Может, логин и пароль не подходит.
В той статье есть ссылки на скачивание готовых файлов примеров программы на C#. Возможно, с ними заработает.
Зверев Александр,
Это и есть код из той статьи(https://academy.terrasoft.ru/documents/technic-sdk/7-12/dataservice-cht…), единственное что я заменил, это логин и пароль. Они в свою очередь верны, так как вызывается метод tryLogin до вызова SelectRequest, и ошибок он не выдает...
engineer7 пишет:
и ошибок он не выдает...
Защиту от CSRF атак выключили? Просто добавление токена не наблюдаю. Попробуйте до вызова
using (var requestStream = selectRequest.GetRequestStream())
// Добавление CSRF-токена в заголовок запроса. CookieCollection cookieCollection = AuthCookie.GetCookies(new Uri(authServiceUri)); string csrfToken = cookieCollection["BPMCSRF"].Value; selectRequest.Headers.Add("BPMCSRF", csrfToken);
Видимо, пример из справки не актуализировали для поддержки CSRF в последних версиях.