Linq over WCF
07.08.2010
|
IT |
Как говорится we are proud to announce the very first fully functional Linq provider over WCF. Первый в мире полноценный Linq провайдер работающий через WCF.
Качать как всегда здесь.
Критика, замечания, пожелания, особенно специалистов по WCF и защите, приветствуются.
Запустить пример в одном процессе можно примерно так:
Вкратце как это работает.
BLT Linq провайдер общается с контекстом данных через интерфейс IDataContext, которому передаётся распарсенный Linq запрос в виде структуры SqlQuery. SqlQuery фактически представляет собой SQL AST. ServiceModelDataContext сериализует эту структуру и передаёт LinqService, который в свою очередь формирует SQL, выполняет запрос и возвращает данные клиенту. Всё просто.
Самый больной вопрос в данном подходе, конечно же, безопасность, если она актуальна. LinqService содержит метод ValidateQuery, который можно использовать для валидации запроса. По умолчанию, LinqService всего лишь не позволяет использовать DML операции, но, в принципе, нет никаких проблем сделать более интеллектуальную проверку структуры запроса. Например, на использование несанкционированных таблиц или полей. Собственно говоря, на эту тему хотелось бы побольше поговорить и услышать мнения насчёт типовых сценариев защиты, которые можно было бы реализовать прямо в библиотеке, т.к. хотя SqlQuery и можно анализировать, но в языках не поддерживающих patten matching это занятие не из весёлых.
Качать как всегда здесь.
Критика, замечания, пожелания, особенно специалистов по WCF и защите, приветствуются.
Запустить пример в одном процессе можно примерно так:
using (var host = new ServiceHost(new LinqService(), new Uri("net.tcp://localhost:1234")))
{
host.Description.Behaviors.Add(new ServiceMetadataBehavior());
host.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
host.AddServiceEndpoint(
typeof(ILinqService),
new NetTcpBinding(SecurityMode.None)
{
MaxReceivedMessageSize = 10000000,
MaxBufferPoolSize = 10000000,
MaxBufferSize = 10000000,
CloseTimeout = new TimeSpan(00, 01, 00),
OpenTimeout = new TimeSpan(00, 01, 00),
ReceiveTimeout = new TimeSpan(00, 10, 00),
SendTimeout = new TimeSpan(00, 10, 00),
},
"LinqOverWCF");
host.Open();
var ctx = new ServiceModelDataContext(
new NetTcpBinding(SecurityMode.None)
{
MaxReceivedMessageSize = 10000000,
MaxBufferPoolSize = 10000000,
MaxBufferSize = 10000000,
CloseTimeout = new TimeSpan(00, 01, 00),
OpenTimeout = new TimeSpan(00, 01, 00),
ReceiveTimeout = new TimeSpan(00, 10, 00),
SendTimeout = new TimeSpan(00, 10, 00),
},
new EndpointAddress("net.tcp://localhost:1234/LinqOverWCF"));
var list = ctx.GetTable<Person>().ToList();
host.Close();
return list;
}
Вкратце как это работает.
BLT Linq провайдер общается с контекстом данных через интерфейс IDataContext, которому передаётся распарсенный Linq запрос в виде структуры SqlQuery. SqlQuery фактически представляет собой SQL AST. ServiceModelDataContext сериализует эту структуру и передаёт LinqService, который в свою очередь формирует SQL, выполняет запрос и возвращает данные клиенту. Всё просто.
Самый больной вопрос в данном подходе, конечно же, безопасность, если она актуальна. LinqService содержит метод ValidateQuery, который можно использовать для валидации запроса. По умолчанию, LinqService всего лишь не позволяет использовать DML операции, но, в принципе, нет никаких проблем сделать более интеллектуальную проверку структуры запроса. Например, на использование несанкционированных таблиц или полей. Собственно говоря, на эту тему хотелось бы побольше поговорить и услышать мнения насчёт типовых сценариев защиты, которые можно было бы реализовать прямо в библиотеке, т.к. хотя SqlQuery и можно анализировать, но в языках не поддерживающих patten matching это занятие не из весёлых.
07.08.2010 113 комментариев |
Круто! Вот только хотелось бы использовать Linq over WCF из Silverlight
IT>>Как говорится we are proud to announce the very first fully functional Linq provider over WCF. Первый в мире полноценный Linq провайдер работающий через WCF.
A>Круто! Вот только хотелось бы использовать Linq over WCF из Silverlight
Над этим работаем. К сожалению, API SL в плане совместимости с FW вещь далеко не идеальная, поэтому придётся много поменять в булките, например, заменить все Hashtable на Dictionary и т.п.
IT>Над этим работаем. К сожалению, API SL в плане совместимости с FW вещь далеко не идеальная, поэтому придётся много поменять в булките, например, заменить все Hashtable на Dictionary и т.п.
Такой способ не пойдёт?
K>Такой способ не пойдёт?
Ты действительно думаешь, что проблема в механическом рефакторинге?
AVK>Ты действительно думаешь, что проблема в механическом рефакторинге?
Я всего лишь предложил путь, которым я сам раньше воспользовался...
K>
K>Такой способ не пойдёт?
Нет. Hashtable отличается от Dictionary:
— способом добавления элемента в словать,
— способом проверки существования элемента в словаре,
— поддержкой многопоточности.
IT>Нет. Hashtable отличается от Dictionary:
IT>- способом добавления элемента в словать,
Hashtable.Add(object, object)
Dictionary<TKey.TValue>.Add(TKey key, TValue value) == Dictionary<object, object>.Add(object, object)
=> одинаково
IT>- способом проверки существования элемента в словаре,
Оба класса юзают метод ContainsKey
IT>- поддержкой многопоточности.
Тут есть небольшые различия, это да. Но проблема в принципе решаемая.
IT>>- способом проверки существования элемента в словаре,
K>Оба класса юзают метод ContainsKey
Знаешь почему у Hashtable нет метода TryGetValue?
IT>>- поддержкой многопоточности.
K>Тут есть небольшые различия, это да.
Различия весьма серьезные.
K> Но проблема в принципе решаемая.
Простым способом — нет. А сложным — проще отрефакторить.
AVK>Знаешь почему у Hashtable нет метода TryGetValue?
Потому что хэштаблица выросла из первого фреймворка и там этого метода не было? И дженериков там тоже не было для избежания боксинга?
Этот метод — комбинация метода ContainsKey и индексёра. Оба исполняются за константное время. Цитирую MSDN:
Так что проблемы тут нет.
AVK>Различия весьма серьезные.
multiread-singlewrite у хэштаблицы против multiread у словаря. При необходимости допиливается через перекрытие методов после наследования от словаря.
AVK>Простым способом — нет. А сложным — проще отрефакторить.
Мой поинт в том, что может оказаться проще сваять класс Hashtable с нужным поведением (да хоть тупо выдернув его код из "большого" фреймворка рефлектором и собрав под Silverlight), чем выкорчёвывать его из текущей либы, заменяя за словари и втыкая локи...
IT>>- способом добавления элемента в словать,
K>Hashtable.Add(object, object)
K>Dictionary<TKey.TValue>.Add(TKey key, TValue value) == Dictionary<object, object>.Add(object, object)
K>=> одинаково
hashTable[key] = value;
Если записи с key в таблице нет, то она будет добавлена. На этом можно строить логику.
IT>>- способом проверки существования элемента в словаре,
K>Оба класса юзают метод ContainsKey
var value = hashTable[key];
Если ключа нет в таблице, то вернётся null. Для Dictionary будет исключение.
IT>>- поддержкой многопоточности.
K>Тут есть небольшые различия, это да. Но проблема в принципе решаемая.
Все проблемы решаемые, но для этого нужно повозиться.
IT>hashTable[key] = value;
IT>Если записи с key в таблице нет, то она будет добавлена. На этом можно строить логику.
IT>var value = hashTable[key];
IT>Если ключа нет в таблице, то вернётся null. Для Dictionary будет исключение.
Обе проблемы элементарно решаются переопределением индексёра с добавлением желаемого поведения.
Короче, если вам "ехать", а не шашечки, то больших проблем я не наблюдаю...
IT>Как говорится we are proud to announce the very first fully functional Linq provider over WCF. Первый в мире полноценный Linq провайдер работающий через WCF.
уже есть другой, но платный
IT>>Как говорится we are proud to announce the very first fully functional Linq provider over WCF. Первый в мире полноценный Linq провайдер работающий через WCF.
C>уже есть другой, но платный
Это полноценный over WCF или поддержка WCF RIA Services?
IT>Как говорится we are proud to announce the very first fully functional Linq provider over WCF. Первый в мире полноценный Linq провайдер работающий через WCF.
Я только мельком глянул — но здесь вроде описывается похожий провайдер:
http://www.hanselman.com/blog/CreatingAnODataAPIForStackOverflowIncludingXMLAndJSONIn30Minutes.aspx
Там запросы описанны с помощью OData/Rest (параметры запроса).
Это аналог? Если да — то буду благодарен, если кто опубликует сравнительные характеристики. Если нет — то что я пропустил?
IT>>Как говорится we are proud to announce the very first fully functional Linq provider over WCF. Первый в мире полноценный Linq провайдер работающий через WCF.
Кэр>Я только мельком глянул — но здесь вроде описывается похожий провайдер:
Кэр>http://www.hanselman.com/blog/CreatingAnODataAPIForStackOverflowIncludingXMLAndJSONIn30Minutes.aspx
Кэр>Там запросы описанны с помощью OData/Rest (параметры запроса).
Кэр>Это аналог? Если да — то буду благодарен, если кто опубликует сравнительные характеристики. Если нет — то что я пропустил?
WCF Data Services хотя и содержат в своём названии WCF, но на самом деле, как ты совершенно справедливо заметил, это скорее Linq over OData со всеми вытекающими последствиями.
Принципиальное отличие BLT в том, что ты можешь конфигурировать Linq отдельно, WCF отдельно, а потом просто сказать этим парням — поехали.
ЗЫ. Ещё к родственным технологиям надо бы добавить RIA Services. Но они только для SL.
IT>WCF Data Services хотя и содержат в своём названии WCF, но на самом деле, как ты совершенно справедливо заметил, это скорее Linq over OData со всеми вытекающими последствиями.
IT>Принципиальное отличие BLT в том, что ты можешь конфигурировать Linq отдельно, WCF отдельно, а потом просто сказать этим парням — поехали.
Понял. Они там утверждают, что гибкость все равно осталась. Но она уже не такого уровня это точно.
Но с другой стороны в случае Linq over OData — я получаю удаленные Linq запросы и поддержку целый толпы клиентов — правильно? Сейчас в эпоху всех этих silverlight/objective-C/java это начинает таки иметь значение.
IT>Самый больной вопрос в данном подходе, конечно же, безопасность, если она актуальна.
Очень актуальна, особенно учитывая возможности BLToolkit over WCF! Насколько я понял, LinqService позволяет исполнить любой select запрос (ExecuteReader) к любой таблице в базе данных, даже если эта таблица не представлена в виде класса модели данных на клиенте. Конечно, такая задача потребует понимания механизма сериализации LinqServiceQuery, но для потенциального "злоумышленника" больших проблем не составит, так как код всегда под рукой.
>LinqService содержит метод ValidateQuery, который можно использовать для валидации запроса.
Такой подход, конечно, позволяет произвольно манипулировать клиентским запросом на сервере, но по моему стоит поддерживать минимальный набор проверок на уровне библиотеки.
>Например, на использование несанкционированных таблиц или полей. Собственно говоря, на эту тему хотелось бы побольше поговорить и услышать мнения насчёт типовых сценариев защиты, которые можно было бы реализовать прямо в библиотеке, т.к. хотя SqlQuery и можно анализировать, но в языках не поддерживающих patten matching это занятие не из весёлых.
На мой взгляд стоит реализовать basic securty на подобии WCF Data Services где можно задавать права доступа (Read, Write в вариациях — EntitySetRights Enumeration) на необходимые таблицы.
Так как модель данных в BLT over WCF реализации находится на клиенте, а сервер получает созданный на клиенте LinqServiceQuery, то также необходим контроль за списком полей, которыми клиент может манипулировать (не только запрашивать, но и использовать в Where). Наверное стоит реализовать возможность указывать список полей доступных для клиента для каждой из таблиц. По умолчанию можно отдавать все, но иметь возможность указать 'запрещенные' поля. Такого в WCF Data Services нет, так как там модель данных создается на сервере, соответственно клиент гарантировано получит только те поля, которые предоставляются сервисом.
Остается вопрос rowlevel security.
Задача примерно следующая:
— в зависимости от текущего service security context (user) необходимо вернуть набор записей, доступных этому пользователю.
В WCF Data Services решение такое:
— для каждой из таблиц можно задать optional QueryInterceptor который возвращает predicate, обязательный для этой таблицы.
Это дает возможность фильтровать возвращаемые данные на сервере в дополнение к запросу, созданному на клиенте.
В BLT можно было бы (наверное?) дополнять where необходимым фильтром на сервере.
Реализуя такие возможности out of the box, BLT позволит легко решать большинство задач связанных с security без дополнительного кода (код для объявления permissions — не в счет). В свою очередь это даст возможность грамотно и безопасно использовать BLT в WCF\Silverlight проектах большинству разработчиков.
Вообще реализация BLT over WCF — вещь шикарная — спору нет . Но именно из-за предоставляемой гибкости требует обязательной реализации ValidateQuery метода на сервере (на сегодняшний день).
Большое человеческое СПАСИБО за отличную реализацию. Однозначно будем продолжать использовать BLT в наших проектах.
Хорошо бы ещё прикинуть как это всё должно выглядеть.
IT>Здравствуйте, Alex Krasov, Вы писали:
IT>Хорошо бы ещё прикинуть как это всё должно выглядеть.
предлагаю декларативное описание Permissions примерно следующего вида:
LinqService дополняется чем-то вроде:
Вопрос:
— откуда вызывать DemandFieldPermission и DemandTablePermission?
Может непосредственно из QueryDeserializer.Parse() примерно в таком виде:
В этом случае удастся избежать повторного обхода десериализованного запроса, но я не уверен или можно вычислить demandingPermission из текущего контекста непосредственно в процессе десериализации.
Вопрос с удобным описанием RowLevel security пока остается открытым. Не имя модели данных на сервере можно пытаться манипулировать конструкциями вида SqlQuery.Predicate.ExprExpr(expr1, @operator, expr2), но это не удобно... Может у автора есть идеи как можно наиболее простым и интуитивно-понятным способом описать предикат не имея под рукой модели данных...?
Если предположить, что модель данных таки доступна для сервера и можно создать человеческий Expression<Func<T, bool>>, как его вставить в уже собранный BLT Query? Помнится после долгих танцев с бубном в EF 4 мне нечто подобное так и не удалось...
AK>Вопрос с удобным описанием RowLevel security пока остается открытым.
Вопрос с RLS вообще отдельный, к WCF отношения почти не имеющий. И решить этот вопрос универсально невозможно, не стоит даже пытаться. Универсальная схема в современных БД тормозит очень сильно, поэтому на практике обычно используют всякие эвристики.
AK>Может у автора есть идеи как можно наиболее простым и интуитивно-понятным способом описать предикат не имея под рукой модели данных...?
А почему не имея модели?
AK>Если предположить, что модель данных таки доступна для сервера
А как иначе?
AK> и можно создать человеческий Expression<Func<T, bool>>, как его вставить в уже собранный BLT Query?
Вот про это IT и спрашивает. Уже сейчас есть ряд механик, позволяющих в определенной мере доконструировать запрос, но для секурности они не очень удобны. Поэтому нужно придумать, как такое описать, чтобы в большинстве случаев это было красиво и удобно.
AVK>Вопрос с RLS вообще отдельный, к WCF отношения почти не имеющий. И решить этот вопрос универсально невозможно, не стоит даже пытаться. Универсальная схема в современных БД тормозит очень сильно, поэтому на практике обычно используют всякие эвристики.
Универсально не получится — согласен, но думалось сделать некий helper в дополнение к ValidateQuery который упростил бы создание предиката для фильтра записей по необходимому условию. Вообще, хотя данный вопрос и был поднят в контексте securiy, думается было бы полезно попытаться реализовать простой(упрощенный?) механизм для манипулирования LinqServiceQuery на сервере.
AVK>А почему не имея модели?
AK>>Если предположить, что модель данных таки доступна для сервера
AVK>А как иначе?
Так ведь для выполнения LinqServiceQuery не нужна она... Я, конечно, может чего и не досмотрел (просьба ткнуть носом в пропущенное), но для выполнения LinqServiceQuery на сервере модель не требуется. Кроме того, не вижу как можно было бы модифицировать полученный от клиента LinqServiceQuery используя серверную модель данных (предположив что мы ее таки создали).
AK>> и можно создать человеческий Expression<Func<T, bool>>, как его вставить в уже собранный BLT Query?
AVK>Вот про это IT и спрашивает. Уже сейчас есть ряд механик, позволяющих в определенной мере доконструировать запрос, но для секурности они не очень удобны.
А можно какой-нить пример такой деконструкции (я еще лучше — конструкции)? Кроме как использования классов из семейства SqlQuery.Predicate.* для описания нужного предиката на стороне сервера ничего на ум не приходит...
AVK>Поэтому нужно придумать, как такое описать, чтобы в большинстве случаев это было красиво и удобно.
Что до большинства случаев — так для них как раз и подошло бы описание вида Expression<Func<T, bool>> — это просто, но позволит описать security filter для небольших задач.
AK>Универсально не получится — согласен, но думалось сделать некий helper в дополнение к ValidateQuery который упростил бы создание предиката для фильтра записей по необходимому условию.
Для этого нужно понять, какие вообще бывают подобные предикаты. Именно в этом суть исходного вопроса и состояла.
AVK>>А как иначе?
AK>Так ведь для выполнения LinqServiceQuery не нужна она...
Не совсем так. Откидывание на клиента структуры БД не есть разумный вариант. В идеале на клиенте должна быть чистая модель, а модель с маппингом уже на сервере. Маппинг, как ты сам понимаешь, без модели быть не может. А маппинг на клиенте годится только для игрушечных приложений.
AK>А можно какой-нить пример такой деконструкции (я еще лучше — конструкции)?
Например то, как собственные sql-функции добавляются. Или как создаются кастомные подзапросы для методов.
AK>>Универсально не получится — согласен, но думалось сделать некий helper в дополнение к ValidateQuery который упростил бы создание предиката для фильтра записей по необходимому условию.
AVK>Для этого нужно понять, какие вообще бывают подобные предикаты. Именно в этом суть исходного вопроса и состояла.
Возможно, имеетс мысл создать два уровня фильтраци: на уровне БД, который должен съекономить чтение с диска и на уровне сервера приложений, который уже под чистую всё отфильтрует. Читать с БД в полтора-два раза больше чем надо и дофильтровывать уже потом не такое уж и плохое решение если учесть конечную скорость разработки.
AVK>Не совсем так. Откидывание на клиента структуры БД не есть разумный вариант. В идеале на клиенте должна быть чистая модель, а модель с маппингом уже на сервере. Маппинг, как ты сам понимаешь, без модели быть не может. А маппинг на клиенте годится только для игрушечных приложений.
Что-то я упускаю — даже после повторного прохода по коду не вижу где бы можно было вклинится с маппингом серверной модели данных. На сколько я разобрался, вся информация для запроса (включая весь mapping) подготавливается на стороне клиента, а на сервере производится построение описанного в SqlQuery (собирается из LinqServiceQuery) SQL выражения с помощью конкретного SqlQueryProvider. В каком слое происходит (может произойти?) маппинг с помощью сервеной модели? То, что можно руками допилить собранный SqlQuery на сервере — понятно. Для того нам ValidataQuery и был дан 'сверху' Я пытаюсь понять или есть возможность использовать на сервере стандартный model mapping подход, применяемый в BLT, к запросу построенному на клиенте. В качестве стандарта я подразумеваю описание POCO модели со всеми необходимыми mapping attributes.
ИМХО самый простой и эффективный метод. Только, конечно, надо будет не забыть применять их ко всем связям
P.S. правда в случае ошибки доступа будет not found, а не access denied, но в большинстве случаев это неважно
P>+ за аналог QueryInterceptor
P>ИМХО самый простой и эффективный метод. Только, конечно, надо будет не забыть применять их ко всем связям
QueryInterceptor — это хорошо. Вот только модель наша — на клиенте, а без модели Expression по человечески не построишь... Отсюда вывод — генерить модель и для сервиса На сервисе она нам, скорее всего, все равно пригодится, а для построения Expression — необходима.
Есть идеи как еще можно задать этот самый Interceptor?
А можно в двух словах в чём принципиальное отличие от двузвенки?
A>А можно в двух словах в чём принципиальное отличие от двузвенки?
Запрос контролируется сервером со всеми вытекающими последствиями. К тому же, бич двухзвенки — это рост количества соединений к серверу БД пропорционально количеству пользователей. При тысячах пользователей сервера БД просто дают дуба.
A>>А можно в двух словах в чём принципиальное отличие от двузвенки?
IT>Запрос контролируется сервером со всеми вытекающими последствиями.
Зависит от уровня контроля. Насколько легко организовать row level security по группе таблиц?
A>>>А можно в двух словах в чём принципиальное отличие от двузвенки?
IT>>Запрос контролируется сервером со всеми вытекающими последствиями.
A>Зависит от уровня контроля. Насколько легко организовать row level security по группе таблиц?
Этот вопрос как раз сейчас решается. При этом интересно прежде всего как это должно выглядеть. Как бы ты хотел, чтобы это выглядело?
A>>Зависит от уровня контроля. Насколько легко организовать row level security по группе таблиц?
IT>Этот вопрос как раз сейчас решается. При этом интересно прежде всего как это должно выглядеть. Как бы ты хотел, чтобы это выглядело?
Ну у меня вообще говоря задачи весьма специфические, но если это чем-то поможет расскажу.
Права доступа могу даваться как на класс объектов (можно/нельзя кушать булки вообще), так и на конкретные объекты (можно/нельзя кушать конкретную булку).
Задаются они весьма развесисто, но благодаря триггерам и такой-то матери всё это выливается в табличку Employee GUID, Target GUID, Permissions INT, где к качестве Target может выступать как GUID объекта, так и GUID класса. Соответсвенно любой запрос предваряется проверкой можно ли оперировать с объектами необходимых классов. Если можно, то обрабатываются все объекты (строки) для которых операция не запрещена (LEFT OUTER JOIN, ISNULL), иначе все те для которых разрешена. Выглядит примено так
IT>>Этот вопрос как раз сейчас решается. При этом интересно прежде всего как это должно выглядеть. Как бы ты хотел, чтобы это выглядело?
A>Ну у меня вообще говоря задачи весьма специфические, но если это чем-то поможет расскажу.
Это всё очень интересно, но хотелось бы прикинуть как должен выглядеть API управления настройками LinqService, который потом будет по этим правилам перетряхивать запросы.
IT>Это всё очень интересно, но хотелось бы прикинуть как должен выглядеть API управления настройками LinqService, который потом будет по этим правилам перетряхивать запросы.
Ну я так далеко заглядывать не буду, так как BLToolkit пользуюсь скорее случайно, чем специально.
Могу только резюмировать: row-level security надо реализовывать на уровне БД. Выкачивать зиллион строк в Application Server чтобы в конце выдать access denied идея далёкая от хорошей. Следовательно, надо уметь как-то сообщать SQL запросу в контексте какого пользователя приложения он выполняется. Видимо, надо внедрять служебный параметр. Но откуда его брать? Нужно как-то интегрироваться с аутентификацией. Для авторизации доступа мало ковырять WHERE, нужен JOIN. В моём примере всё симметрично, у всех таблиц есть идентификатор GUID и все права доступа в одной таблице. Вообще говоря это может быть не так. И всё это, видимо, должно хорошо работать для подзапросов.
IT>Это всё очень интересно, но хотелось бы прикинуть как должен выглядеть API управления настройками LinqService, который потом будет по этим правилам перетряхивать запросы.
Ещё я тут подумал. Что делать с правами доступа проверяемыми не на уровне БД? Например, logon hours. Что делать с кешированием, журналированием (я хочу журналировать не только запросы)? ИМХО очень нерасширяемое решение получилось. Катит только как QuickStart. И преимущество у QuickStart тогда должно быть только одно — с него должно быть можно быстро и безболезненно соскочить.
IT>Запустить пример в одном процессе можно примерно так:
IT>
Что делать в случае, если таблица Person большая ? А тем не менее хотелось бы выбрать всю таблицу ? Может ли помочь изменение " MaxStringContentLength property on the XmlDictionaryReaderQuotas " и как до него добраться ?
У меня вываливается исключение
Мож
WS>Что делать в случае, если таблица Person большая ? А тем не менее хотелось бы выбрать всю таблицу ? Может ли помочь изменение " MaxStringContentLength property on the XmlDictionaryReaderQuotas " и как до него добраться ?
Помочь может. Как поменять — подробно описано в MSDN. Вкратце — или в конфиге ендпоинта, или в соотв. элементах описания биндинга при программном конфигурировании. Поиск в MSDN по MaxStringContentLength должен помочь.
WS>Помогло.. только нужно устанавливать свойства бинидинга как на хосте, так и на клиенте
Разумеется. На сервере реальный контроль, на клиенте валидация, чтобы лишний раз сервер не нагружать.
Все запросы Linq Over WCF не работают, отваливаются по таймауту.
До этого использовалась версия 4.0, все работало.
Сейчас не работает даже этот пример, см. ниже.
В чем подвох и как лечить?