Об авторе Алекс Макки (Alex Mackey) всегда испытывал интерес к компьютерам и начинал программировать на любительском языке под названием Amos на Amiga. Изначально он хотел стать разработчиком игр, но вместо этого оказался разработчиком приложений для Интернета. На него сильно повлияла книга Neuromancer (“Нейромант”) Уильяма Гибсона (William Gibson). В ней есть фантастическая цитата: The Matrix unfolds like neon origami beneath clusters and constellation of data. Матрица раскрывается подобно неоновому оригами под кластерами и созвездиями данных. Замечательно сказано, хотя мир Гибсона не включал в себя такого чуда, каким является IE 6. Свой первый опыт коммерческой разработки я получил в университете (бизнесвычисления с психологией, первый курс), где работал на маленькую консалтинговую фирму, создающую приложения на основе ASP и VB6. Вскоре после этого появился .NET, и я перешел к серверной разработке ASP.NET/SQL, чем и занимаюсь последние восемь лет. Мне пришлось заниматься разработкой и консультированием в области медицины, государственных учреждений, CRM, финансов и автомобильной промышленности, причем повезло поработать по всему миру — в Великобритании, Ирландии, на Ближнем Востоке, в Америке и Австралии. В настоящее время я живу в Мельбурне, Австралия, где работаю главным разработчиком. Здесь я открыл для себя изощренный австралийский помми-юмор (pommy — неодобрительное название англичан в Австралии), который неизменно сопровождается лондонским просторечием (кокни) 1820-х гг. Тем не менее, австралийцы — одни из самых приветливых, доброжелательных и веселых людей, которых мне приходилось встречать, и я благодарен друзьям, которых нашел здесь, и которые облегчили мой процесс адаптации в новой стране. Я активно участвую в сообществе программистов, выступаю на многочисленных конференциях и мероприятиях групп пользователей. В Британии я основал находящуюся в Саррее группу пользователей .NET под названием DevEvening.co.uk. В октябре 2008 г. я получил звание MVP C#. В настоящее время работаю над организацией формата конференции “DeveloperDeveloperDeveloper day” в Мельбурне (dddmelbourne.com) и настройкой DevEvening.com.ua. В нерабочее время люблю заниматься бегом и физкультурой, а также интересуюсь проблемами искусственного интеллекта. Со мной можно связаться через сайт simpleisbest.co.uk, а также в twitter — twitter.com/alexjmackey. Содержание Об авторе Благодарности Введение 20 Цель написания книги Примеры кода Внимание: работы продолжаются! Исходный код примеров От издательства 23 23 24 24 24 22 23 Глава 1. Введение 25 Версии Что собой представляют .NET 4.0 и VS2010 Эффективность Улучшение существующих технологий Расширяемость Влияние текущих тенденций Мнение разработчиков о .NET 4.0 Майк Ормонд (Mike Ormond), евангелист Microsoft Эрик Нельсон (Eric Nelson), евангелист Microsoft Крэйг Мерфи (Craig Murphy), MVP и организатор сообщества разработчиков Фил Винстенли (Phil Whinstanley), ASP.NET.MVP и автор Дэйв Суссман (Dave Sussman), MVP и автор Мэтт Лэйси (Matt Lacey), организатор сайта Devevening.co.uk Алекс Макки (Alex Mackey), MVP и автор этой книги Будущие тенденции Субъективное мнение автора Резюме 25 26 26 26 27 27 27 27 28 28 29 29 30 30 30 31 31 Глава 2. Интегрированная среда разработки Visual Studio и MEF 32 Общие усовершенствования Улучшенная поддержка различных версий .NET Средство IntelliSense Добавление ссылок Профиль Web Development (code-optimized profile) Масштабирование (Zoom) Выделение ссылок (Highlight References) Перейти к (Navigate To) Выделение прямоугольных областей текста (Box Selection) Иерархия вызовов (Call Hierarchy) Генерация кода Режим сonsume-first Точки останова Панель инструментов Сниппеты кода Создание специальных стартовых страниц Файлы T4 Версии Premium и Ultimate среды VS2010 33 33 34 34 35 36 36 36 37 38 38 39 40 40 40 43 43 44 Содержание 7 Генерация диаграмм последовательностей Хронологическая отладка (только в версии Team System Edition) Статический анализ контрактов кода Настройка IDE-среды Каркас MEF Для чего использовать MEF? Пример “Hello MEF” Как работает этот пример? Справочники MEF Метаданные MEF и расширяемость Visual Studio Расширяемость Visual Studio Проект Editor Margin Распространение расширений Галерея расширений Оболочка Visual Studio Shell Изменения в Dotfuscator Резюме 44 44 44 45 45 46 46 48 48 50 51 51 52 53 53 53 54 54 Глава 3. Языковые и динамические изменения 55 Будущая совместная эволюция VB и C# Усовершенствования в C# Именованные и необязательные параметры Обязательные правила Изменения в VB.NET Продолжение строки Правила продолжения строк Поддержка анонимных методов Автоматически реализуемые свойства Упрощенное взаимодействие с COM Избавление от файлов PIA Вариантность Более подробно о вариантности Дополнительные источники Динамические усовершенствования Разве нельзя было делать подобные вещи в предшествующих версиях .NET? Статически типизированные языки Динамически типизированные языки Опасности, связанные с динамичностью Тип dynamic Класс System.Dynamic.ExpandoObject Класс System.Dynamic.DynamicObject Интерфейс IDynamicMetaObjectProvider Ограничения, связанные с динамическими объектами Динамический промежуточный язык Исполняющая среда динамического языка (DLR) Язык IronPython Майкл Фурд Язык F# Интервью с Джоном Скитом Будущее языка C# 55 56 56 57 57 57 57 58 58 59 60 60 61 65 65 66 66 66 67 67 68 68 69 69 70 72 73 74 77 78 79 8 Содержание Глава 4. Изменения в CLR и BCL 80 Новая среда CLR ASP.NET Какую версию CLR использует приложение? Указание используемой платформы Компилятор командной строки VB.NET Усовершенствованный клиентский профиль Внутрипроцессное выполнение бок о бок Сборка мусора Сборка мусора в версиях, предшествующих .NET 4.0 Сборка мусора в версии .NET 4.0 Метод GC.RegisterForFullGCNotification() Многопоточность Глобализация Изменения, связанные с глобализацией, в .NET 4.0 Глобализованное форматирование и анализ с помощью класса TimeSpan Безопасность Модель прозрачности Прозрачный код Безопасный критичный код Критичный код Безопасный критичный страж Почему это имеет значение? Изменения в безопасности Средство SecAnnotate APTCA и Evidence Мониторинг и профилирование Средство Native Image Generator (NGen) Расширения “родного” кода Обработка исключений 80 81 81 81 82 82 83 84 84 84 85 85 85 86 86 87 87 87 87 87 87 87 88 88 89 89 89 89 90 90 90 91 91 92 93 93 93 93 94 94 94 94 94 94 95 95 95 95 96 CorruptedStateExceptions Новые типы BigInteger Тип Lazy<T> Файлы, отображаемые в память Тип SortedSet<T> Интерфейс ISet<T> Тип Tuple Тип System.Numerics.Complex Типы System.IntPtr и System.UIntPtr Хвостовая рекурсия Изменения в существующей функциональности Делегаты Action и Func Усовершенствования сжатия Файловый ввод-вывод Метод Path.Combine() Изолированное хранилище Изменения в доступе к реестру Метод Stream.CopyTo() Методы Guid.TryParse(), Version.TryParse() и Enum.TryParse<T>() Содержание Метод Enum.HasFlag() Методы String.Concat() и String.Join() поддерживают IEnumerable<T> Метод String.IsNullOrWhiteSpace() Метод StringBuilder.Clear() Дополнения в перечислении Environment.SpecialFolder Методы Environment.Is64BitProcess и Environment.Is64BitOperatingSystem Метод Stopwatch.Restart() Средство ServiceProcessInstaller.DelayedAutoStart Рефакторинг наблюдаемых коллекций IObservable<T> Библиотеки сетевых классов (NCL) Конечная точка DNS Новые средства, предназначенные только для Windows 7 Устаревшие API-интерфейсы System.Data.OracleClient Глобальные статические функции хостинга Контракты кода Введение в контракты кода Установка контрактов кода Пример контракта кода Включение статической верификации контрактов кода (только в версиях Premium/Ultimate) Наследование контракта Архитектура Условия Значения контракта кода Атрибут Pure Контракты интерфейса Проект PEX Резюме Материалы для дополнительного чтения 9 96 96 96 96 97 97 97 97 97 97 97 98 99 99 100 100 100 100 101 101 103 103 103 103 105 105 105 106 106 106 Глава 5. Распараллеливание и многопоточность 107 Обзор распараллеливания Важнейшие концепции Зачем могут понадобиться эти усовершенствования? Одновременно не означает параллельно Предупреждение: многопоточность и параллелизм увеличивают сложность приложения Неэффективный код, выполняющийся параллельно — это просто распараллеленный неэффективный код Что выигрывают приложения от распараллеливания? Можно ли запустить эти примеры на машине с одноядерным процессором? Могут ли средства распараллеливания замедлить работу? Производительность Параллельные циклы 107 108 108 108 109 110 110 110 110 110 111 Parallel.For() 111 Нереалистичный пример? 111 ParallelOptions 114 Parallel.ForEach() 114 Предупреждение: распараллеливание может нанести ущерб производительности 115 10 Содержание Параллельные коллекции Примитивы синхронизации Отменяющие лексемы Дополнительные соображения Интервью c Дэнни Ши Интервью с Филом Винстенли Резюме Материалы для дополнительного чтения 115 115 115 116 117 117 117 118 118 118 118 118 119 119 119 119 120 121 123 123 123 124 124 124 124 125 125 125 125 126 126 126 126 128 129 131 132 133 133 133 Глава 6. Windows Workflow Foundation 4 134 Зачем использовать WF? Чем поможет Windows Workflow? Что такое Windows Workflow Foundation? Экземпляр/исполняющая среда рабочего потока Действия Визуальный конструктор рабочих потоков Существующие пользователи WF 3 Рабочий поток конечного автомата не поддерживается Документация по обновлению 134 137 137 138 138 138 139 139 139 Parallel.Invoke() Задачи Планировщик задач Создание новой задачи Task.Wait() и Task.WaitAll() Task.WaitAny() IsCompleted ContinueWith() Создают ли параллельные циклы потоки для каждой итерации? Возврат значений из задач Что если задача еще не имеет результата? Варианты создания задач Состояние задачи Переопределение TaskScheduler Планирование в потоке пользовательского интерфейса Усовершенствования параллельной отладки Окно Parallel Task Окно Parallel Stacks PLINK (параллельный LINQ) Почему бы не распараллелить все запросы LINQ автоматически? Введение в PLINQ Упорядочивание результатов Операция ForAll() AsSequential() WithMergeOptions Производительность PLINQ Отмена запроса PLINQ Исключения и параллельный LINQ Структуры данных для координации и усовершенствования многопоточности Усовершенствования пула потоков Thread.Yield() Minitor.Enter() Содержание 11 Исполняющая среда WF 3 Действие Interop Стоит ли выполнять обновление? Все меняется Введение в WF 4 Введение в WF Аргументы и переменные Создание собственных действий Создание действия, состоящего из других действий Создание действий непосредственно в коде Разметка XAML для рабочих потоков Вызов рабочих потоков Блок-схема Усовершенствования WCF и обмена сообщениями Корреляция Приложения WCF Workflow Service Действия Прочие усовершенствования Интервью с Джоном Маклоклином Резюме 139 139 140 140 140 140 140 147 147 148 149 150 151 153 153 153 155 159 160 160 Глава 7. Windows Communication Foundation 161 Отсутствие конфигурационного файла Привязки, поведение и конечные точки по умолчанию Привязки и поведение по умолчанию Стандартные конечные точки Отсутствие расширения svc Служба маршрутизатора Пример маршрутизации Фильтры маршрутизации Поддержка многоадресной рассылки Связь протоколов Избыточность WS-Discovery Управляемый режим Специальный режим События анонсирования службы Интеграция стартового набора WCF REST Справочные страницы Кэширование HTTP Прочие изменения Усовершенствованная интеграция с WF Изменены настройки по умолчанию, связанные с производительностью Минимум памяти Другие изменения Dublin/сервер приложений Windows Материалы для дополнительного чтения 161 163 163 164 164 165 165 167 167 167 167 168 168 168 170 171 171 173 173 173 173 173 173 174 174 Глава 8. Entity Framework 175 EF и LINQ to SQL LINQ to SQL больше не развивается? 175 175 12 Содержание Изменения в LINQ to SQL Зачем использовать EF? Абстракция Генерация кода Поддержка различных баз данных Поддержка времени проектирования Использование LINQ Разработка n-уровневых приложений Где используется EF? Основы EF Сущностная модель данных Создание EDM Навигация по модели EF Опрос данных Операции CRUD в EF Создание Обновление Удаление Критика первого выпуска EF Entity Framework 4 Изменения в визуальном конструкторе EDM Установка множественной формы Отложенная/“ленивая” загрузка Немедленная загрузка Поддержка сложных типов визуальным конструктором Получение сложных типов из хранимых процедур Функции, определенные моделью Первоначальная генерация модели Внешние ключи Только код/POCO POCO в EF 4 Шаблоны генерации кода Интервью с Джулией Лерман (Julia Lerman), MVP и автором книги Programming Entity Framework Интервью с Дэйном Моргриджем (Dane Morgridge) Резюме Материалы для дополнительного чтения 176 176 176 176 177 177 177 177 177 178 178 178 182 183 185 185 186 186 186 187 187 188 188 188 188 190 191 192 197 197 198 199 Глава 9. Службы WCF Data Services 203 Введение в WCF Data Services Entity Framework Создание службы данных Настройка содержимого в Internet Explorer Введение в WDS Запрос служб WCF Data Services Безопасность служб WCF Data Services Перехватчики запросов Возврат результатов в других форматах Использование JSON в JavaScript Использование JSON в C# Прокси-классы WDS 203 204 206 207 207 207 209 210 210 210 211 211 200 200 201 202 Содержание 13 Извлечение элементов с помощью прокси-классов Добавление нового элемента с помощью прокси-классов Обновление элемента Удаление элемента WDS 1.5 Подсчет строк и управляемое сервером разбиение на страницы Ограничение количества возвращаемых результатов Проекции Дружественные каналы Прочие усовершенствования Какая связь между службами WDS и WCF RIA Services? Резюме Материалы для дополнительного чтения 211 213 213 213 213 214 214 215 215 215 215 216 216 Глава 10. ASP.NET 217 Шаблоны проектов Файл Web.config Изменения в IDE-среде Сниппеты кода Сниппеты кода ASP.NET Использование сниппетов Развертывание Трансформация Web.config Создание новой конфигурации развертывания Трансформация Web.config из командной строки Варианты трансформации Web.config Веб-пакеты Публикация одним щелчком ViewState 217 217 218 219 219 220 221 222 222 224 224 224 226 227 228 229 229 229 230 230 231 231 231 231 231 231 232 232 232 232 233 233 233 233 233 233 ClientIDMode Response.RedirectPermanent() Мета-дескрипторы Маршрутизация URL HTML-кодирование HtmlString Специальная проверка запросов Специальные кодировщики Длина URL и строки запроса Допустимые символы URL Доступность и стандарты controlRenderingCompatibilityVersion RenderOuterTable CheckBoxList и RadioButtonList Элемент управления Menu Файлы возможностей браузера Прочие усовершенствования элементов управления Элемент управления Wizard Элемент управления ListView Элемент управления GridView Элемент управления CompareValidator Расширитель запросов 14 Содержание Автозапуск веб-приложений Сжатие состояния сеанса Кэширование Microsoft Velocity Мониторинг ресурсов Измененные элементы управления Dynamic Data Framework Резюме Материалы для дополнительного чтения 234 234 235 235 235 235 236 237 237 237 Глава 11. Библиотека Microsoft AJAX 238 Изменения в архитектуре Совместимость Устранена проблема, связанная с методом pageLoad Установка Добавление библиотеки Microsoft AJAX к проекту Загрузчик клиентского сценария Библиотеки AJAX теперь находятся у Microsoft Свойство EnableCdn элемента ScriptManager Интеграция инструментария AJAX Элементы управления теперь представлены как подключаемые модули jQuery Контекст данных службы WCF Data Services Резюме Материалы для дополнительного чтения 238 238 239 239 239 240 242 242 242 242 243 243 243 243 244 244 245 246 247 248 248 249 250 250 250 251 251 253 253 255 255 Глава 12. jQuery 256 jQuery или библиотеки Microsoft AJAX? Обзор jQuery Загрузка jQuery Поддержка IntelliSense Хостинг сценариев Введение в jQuery 256 257 257 258 258 258 System.Runtime.Caching DataView Совместимость с XHTML Введение в Microsoft AJAX CSS-правило sys-template Привязка DataView Декларативная привязка Программная привязка Более ясная программная привязка Привязка “главная–детали” Привязка к внешним службам Привязка к веб-службе ASMX Привязка WCF JSONP Расширенная привязка Условная визуализация Конвертеры привязки Двунаправленная привязка Sys.Observer Содержание 15 Как это работает? Выбор элементов Селекторы CSS Селекторы jQuery Работа с наборами Метод .each() Работа со значениями атрибутов и CSS Динамическая генерация элементов Запуск сценария по загрузке страницы Добавление функций Анимация/эффекты Перегрузки эффектов Базовые эффекты библиотеки Дополнительные эффекты Glimmer Инструменты jQuery Цепочки событий Настройка jQuery Методы AJAX Загрузка и запуск файла JavaScript Отправка данных Получение последней версии страницы Извлечение объекта JSON Лучший способ Служебные методы Дополнения jQuery Резюме Материалы для дополнительного чтения 259 260 261 261 262 262 262 263 263 263 264 264 265 265 265 265 266 266 267 267 267 268 268 268 269 269 270 270 Глава 13. ASP.NET MVC 271 История MVC Зачем необходима архитектура MVC? Существующее приложение MVC Поддержка состояния Инициализация типа Установка MVC Создание приложения MVC Структура проекта Изменение компоновки страниц ASP.NET MVC Создание модели Создание контроллера Добавление представления Запуск приложения Более пристальный взгляд на маршрутизацию Возврат представлений ViewData и TempData Отображения списка данных Не возвращаемся ли мы обратно в 1998 год? Создание детальной страницы Методы HtmlHelper Строго типизированные представления 271 272 272 274 274 275 275 275 276 276 280 280 281 282 283 283 283 285 285 286 287 16 Содержание Создание строго типизированного представления Создание функциональности добавления нового фильма и удаления существующего Прием данных от пользователей Атрибуты ASP.NET MVC и JavaScript Специальная маршрутизация ASP.NET MVC и безопасность Расширение MVC Расширяющие методы Фильтры Тестирование Создание фиктивного репозитория фильмов Создание теста Модификация контроллера Film Запуск тестов ASP.NET MVC V2 ASP.NET MVC в реальном мире Что дальше? Преимущества ASP.NET MVC Соображения Резюме Материалы для дополнительного чтения 289 290 291 292 294 295 296 296 296 297 297 298 299 299 300 300 301 301 302 302 303 Глава 14. Введение в Silverlight 304 Сравнение Silverlight и Flash Silverlight в реальном мире WPF XAML Требования Silverlight и установка Expression Blend Создание нового проекта Silverlight Структура проекта Введение в Silverlight Добавление содержимого Добавление Silverlight к приложению Дескриптор object Страницы в Silverlight Создание пользовательского элемента управления Silverlight 305 305 307 307 307 307 308 308 309 310 311 311 311 312 313 314 314 315 316 316 316 318 320 320 321 322 App.xaml Стили Позиционирование элементов Присоединенные свойства и свойства зависимости Элементы управления компоновкой Canvas StackPanel Grid Простая анимация Программное создание анимации Реакция на пользовательские события Декларативное создание анимации 287 Содержание Интеграция с HTML Вызов функций JavaScript из Silverlight Изменение значений элементов DOM из Silverlight Вызов функции Silverlight из JavaScript Передача параметров Silverlight 17 Сетевые коммуникации Резюме Материалы для дополнительного чтения 323 323 324 324 325 325 326 326 327 327 329 329 332 332 333 334 334 334 336 336 337 Глава 15. WPF 4.0 и Silverlight 3.0 338 Усовершенствования в IDE-среде Визуальный конструктор WPF/Silverlight в VS2010 Сортировка свойств по источнику Пиктограммы свойств Стиль Кисти Окно Binding Привязка данных времени проектирования Новое диалоговое окно выбора изображений Усовершенствованный визуальный конструктор сеток Статические ресурсы и исправления в визуальном конструкторе Привязка данных с помощью перетаскивания Улучшенное средство XAML IntelliSense Новые элементы управления Элемент управления Ribbon и коллекция элементов “Bag O’Tricks” Интеграция с Windows 7 Списки переходов Панель задач Поддержка технологии мультитач Изменения привязки 338 338 339 339 339 340 342 342 342 343 343 343 347 348 348 349 349 350 351 352 352 352 352 352 352 353 354 354 InitParams Строка запроса Встроенное содержимое в приложении Silverlight Динамическая загрузка XAML Медиа-содержимое Дополнительные элементы управления Привязка данных Режимы привязки Привязка данных и свойства зависимости Двунаправленная привязка Привязка ListBox Шаблоны данных DataGrid Run.text Поддержка динамической привязки Класс InputBinding теперь поддерживает привязку Усовершенствования в визуализации текста TextOptions.TextFormattingMode TextOptions.TextRenderingMode RenderOptions.ClearTypeHint Поддержка восточноазиатских шрифтов в виде битовых карт 18 Содержание Округление при компоновке Кэшированная композиция Облегчение анимации Поддержка Pixel Shader 3.0 Интеграция с Visual State Manager Взаимодействие сценариев HTML-XBAP Развертывание XBAP с полным доверием Клиентский профиль Прочие изменения Silverlight 3.0 Модернизация от Silverlight 2 Автономные приложения Создание автономного приложения Удаление приложений Silverlight Отсоединение вручную Получение режима работы Обнаружение состояния соединения Автоматическое обновление Внешние гиперссылки и хронология браузера Navigation Application Локальные соединения Стили Динамическое применение стилей Наследование стиля Поддержка слияния словаря Диалоговое окно сохранения файла Фильтрация файлов в SaveDialog Привязка элемента к другому элементу Эффекты и трансформации Плоская проекция Облегченные эффекты Технология Pixel Shader Создание собственных затенителей пикселей Медиа-средства Новые форматы Silverlight DRM Производительность Поддержка Binary XML Улучшенная производительность Deep Zoom Улучшенное сжатие XAP Файл Silverlight.js Кэширование сборок Ускорение графического процессора Прочие усовершенствования Элементы управления Listbox Стили курсора в TextBox Специальные возможности Поддержка функции масштабирования в браузере Slsvcutil.exe Шаблон проектирования WCF RIA Services 354 355 355 356 356 356 356 356 356 357 357 357 357 360 360 360 360 360 360 361 361 363 363 364 364 364 364 365 365 365 366 367 369 369 369 369 369 369 369 369 370 370 371 371 371 371 371 371 372 372 372 Содержание 19 Blend 3/SketchFlow Silverlight 4.0 Silverlight в реальном мире Резюме Материалы для дополнительного чтения 372 373 373 375 375 Глава 16. Windows Azure 376 Обзор Azure Архитектура Возможность установки собственной версии Windows Azure Прежде чем начать Установка Веб-роли Приложение “Hello Azure” Azure и конфигурационные установки Протоколирование и отладка Тестирование приложений Azure Создание хранилища разработки Просмотр журналов Azure Развертывание Развертывание приложения “Hello Azure” Установка Рабочие URL Аналитические данные Локальное хранилище Рабочие роли Хранилище в Azure Azure Storage Работа с Azure Storage API-интерфейс Azure или запросы REST? Немного о REST Имена в Azure Storage Большие двоичные объекты Пример большого двоичного объекта Прямое обращение к API-интерфейсу REST Как работать с API-интерфейсом REST? Работа с Azure Storage посредством низкоуровневых HTTP-запросов Очереди Табличное хранилище Другие службы Azure Microsoft.NET Services Windows Live Services Ценообразование и соглашение об уровне обслуживания Azure в реальном мире Рэй Буйсен (Ray Booysen) Расти Джонсон (Rusty Johnson) и Энди Бритклиф (Andy Britcliffe), SharpCloud Преимущества Недостатки Резюме Материалы для дополнительного чтения 376 377 377 378 378 378 378 380 382 382 382 384 385 385 389 389 389 390 390 391 392 393 393 393 394 394 394 396 397 397 399 400 403 403 403 404 405 405 406 406 407 407 408 Предметный указатель 409 Введение М ногие разработчики чересчур заняты (или ленивы), чтобы изучать новые технологии и повышать свою квалификацию. Это недопустимо, поскольку упускаются следующие возможности. • Создание лучшего программного обеспечения. • Облегчение себе жизни за счет создания лучшего и проще сопровождаемого кода. • Получение новых возможностей карьерного роста и хорошей работы. • Произведение впечатления на других людей. Прежде всего, давайте определимся с тем, чем данная книга не является. Во-первых, эта книга нацелена вширь, а не вглубь, поэтому, возможно, не охватывает некоторые области в такой степени детализации, как вы бы хотели. Во-вторых, эта книга написана с прицелом на версию Visual Studio 2010 Professional Edition, поэтому здесь не описаны замечательные новые средства, доступные в версиях Premium и Ultimate. Причина не в том, что эти средства не важны, но просто я уверен, что большинство разработчиков используют версию Professional, и того, что о ней рассказано в книге, будет более чем достаточно. Цель написания книги Эта книга позволит быстро ознакомиться со всеми новшествами .NET 4.0 и VS2010 с достаточной степенью глубины, чтобы можно было получить необходимое представление, не слишком углубляясь в детали. Когда появляется нечто настолько масштабное, как Visual Studio 2010, я полагаю, что разработчикам нужно именно обзорное руководство. Большинство из нас достаточно долго занимается разработкой программного обеспечения, и нам нужно лишь представить новую технологию, а детали мы раскопаем самостоятельно. Я не верю, что для быстрого извлечения выгоды от новых технологий нужно обязательно прочитать чересчур объемную книгу. В этой книге описаны возможности, доступные в .NET 4.0 и VS2010, предполагая, что вы захотите и сможете при желании продолжить их изучение самостоятельно. При написании этой книги преследовались следующие цели. • Представление читателям новых технологий. • Описание основ. • Избегание излишних деталей, чтобы книга легко читалась. • Представление, насколько возможно, простых примеров, не засоряя материал излишними подробностями. Примеры кода Одна из вещей, которые меня раздражают в примерах кода в MSDN и некоторых книгах — излишние подробности, которые затеняют ключевые концепции. При иссле- 00_Introducing-NET-4-0.indd 23 24.03.2010 22:41:58 24 Введение довании примера не важно, красиво ли он выглядит. Примеры, приведенные в этой книге, по возможности сохранялись как можно более короткими, что должно сделать концепции более легкими для понимания и сокращают объем клавиатурного ввода. Однако обратная сторона медали состоит в том, что код в этой книге определенно нельзя рассматривать как пример хорошего стиля (например, в главе, посвященной MVC). Код должен включать обработку ошибок, закрытие соединений и т.п. Внимание: работы продолжаются! Большая часть настоящей книги написана с использованием предварительных выпусков Visual Studio и .NET 4, которые, конечно же, будут изменяться. На момент написания в документации о некоторых областях приводились очень скудные сведения, а некоторые средства просто не работали, что ограничивало глубину изложения материала. Также вероятно, что ко времени выхода финальной версии некоторые из приведенных примеров потребуют небольших исправлений, а некоторые экраны будут выглядеть слегка иначе. Мы собираемся поправить все это в будущем, а пока страница замеченных ошибок будет доступна на веб-сайте Apress по адресу http://www.apress.com/ book/errata/1247. Исходный код примеров Исходный код примеров, рассмотренных в книге, а также дополнительные главы, не вошедшие в печатное издание, доступны для загрузки на сайте издательства по адресу http://www.williamspublishing.com. От издательства Вы, читатель этой книги, и есть главный ее критик и комментатор. Мы ценим ваше мнение и хотим знать, что было сделано нами правильно, что можно было сделать лучше и что еще вы хотели бы увидеть изданным нами. Нам интересно услышать и любые другие замечания, которые вам хотелось бы высказать в наш адрес. Мы ждем ваших комментариев и надеемся на них. Вы можете прислать нам бумажное или электронное письмо, либо просто посетить наш Web-сервер и оставить свои замечания там. Одним словом, любым удобным для вас способом дайте нам знать, нравится или нет вам эта книга, а также выскажите свое мнение о том, как сделать наши книги более интересными для вас. Посылая письмо или сообщение, не забудьте указать название книги и ее авторов, а также ваш обратный адрес. Мы внимательно ознакомимся с вашим мнением и обязательно учтем его при отборе и подготовке к изданию последующих книг. Наши координаты: E-mail: [email protected] WWW: http://www.williamspublishing.com Информация для писем из: России: Украины: 00_Introducing-NET-4-0.indd 24 127055, г. Москва, ул. Лесная, д. 43, стр. 1 03150, Киев, а/я 152 24.03.2010 22:41:58 ГЛАВА 9 Службы WCF Data Services Доступность: .NET Framework 3.5 SP1 (ограниченная функциональность) и выше Службы данных WCF (WCF Data Services, ранее “Astoria” и ADO.NET Data Services) позволяют модифицировать и поставлять данные по интерфейсу HTTP REST. Службы WCF Data Services (WDS) включают богатый язык запросов и могут быть легко доступны через автоматически сгенерированные прокси-классы либо посредством низкоуровневых запросов HTTP. Службы WCF Data Services поддерживают возврат данных во множестве популярных форматов, в том числе XML, AtomPub и JSON, и потенциально очень полезны для сценариев интеграции и приложений, которые не поддерживают прямых соединений с базой данных, например, Silverlight. На заметку! Пока шла работа над этой главой, Microsoft изменила название ADO.NET Data Services на WCF Data Services. Однако имена шаблонов VS пока не изменены, поэтому в примерах настоящей главы используются имена шаблонов ADO.NET Data Services. Введение в WCF Data Services Прежде чем приступать к изучению WDS, понадобятся какие-то данные, чтобы было с чем поработать. Если это еще не сделано, обратитесь к введению и установите базу данных примеров. В этой главе будет использоваться SQL Server 2008, но не думайте, что вы ограничены использованием только SQL Server, поскольку WDS работает со всем, что поддерживает Entity Framework (см. главу 8). Чтобы представить данные с помощью этой службы, необходимо выполнить четыре следующих действия. 1. Создать классы Entity Framework для данных, которые должны быть представлены. 2. Создать приложение-хост ADO.NET для службы WDS. 3. Создать службу WDS. 4. Сконфигурировать правила доступа к службе. 204 Глава 9. Службы WCF Data Services Итак, приступим. Откройте Visual Studio и создайте новый веб-сайт ASP.NET; измените значение в раскрывающемся списке Web location (Веб-расположение) на HTTP и введите местоположение http://localhost/Chapter9/. Внимание! Хостинг служб WCF Data Services в IIS на одной машине постоянно приводил к ошибке HTTP 500 при попытке запроса данных. Я так и не смог докопаться до причин, поэтому если у вас получится то же самое, попробуйте вместо этого поработать с локальным веб-сервером. Entity Framework Службы WDS должны знать, как структурированы и связаны данные, которые мы хотим представить. Для предоставления этой информации используется Entity Framework. 1. Добавьте в проект новую сущностную модель данных ADO.NET. 2. Назовите эту новую сущностную модель данных ADO.NET как Chapter9Model.edmx (рис. 9.1). Рис. 9.1. Добавление сущностной модели данных ADO.NET 3. Щелкните на кнопке Add (Добавить). 4. Visual Studio предложит расположить эти файлы в каталоге App_Code. Согласитесь. 5. Теперь Visual Studio спросит, как необходимо генерировать модель. Выберите вариант Generate from database (Генерировать из базы данных) и затем щелкните на кнопке Next (Далее), как показано на рис. 9.2. 6. Если пока еще нет соединения с базой данных примеров, создайте его, щелкнув на кнопке New Connection (Новое соединение) и введите параметры соединения (рис. 9.3). 7. Visual Studio исследует структуру базы данных и отобразит экран, подобный показанному на рис. 9.4, где можно будет выбрать элементы для генерации классов для EF. Разверните узел Tables (Таблицы), чтобы отобразить все доступные таблицы. Глава 9. Службы WCF Data Services Рис. 9.2. Генерация модели из базы данных Рис. 9.3. Создание нового соединения с базой данных Рис. 9.4. Выбор элементов для генерации классов для EF 205 206 Глава 9. Службы WCF Data Services 8. Отметьте флажки возле всех таблиц кроме sysdiagrams. 9. Удостоверьтесь, что флажок Pluralize or singularize generate object names (Установить множественную или единственную форму для имен генерируемых объектов) отмечен. 10. Удостоверьтесь, что в поле Model Namespace (Пространство имен модели) установлено значение Models. 11. Щелкните на кнопке Finish (Готово). 12. Щелкните на кнопке OK. VS2010 сгенерирует классы EF для базы данных и отобразит поверхность визуального конструктора (рис. 9.5). Рис. 9.5. Сущностная модель Создание службы данных Все, что теперь осталось — это представить классы EF, добавив новую службу данных и сконфигурировав правила для доступа к ней. Ниже перечислены необходимые шаги. 1. Добавьте в проект новую службу данных ADO.NET и назовите ее MovieService.svc. 2. Щелкните на кнопке OK. 3. Откройте ~/MovieService.cs. 4. Теперь потребуется сообщить WDS, какой тип класса будет представлять служба. Модифицируйте код следующим образом: public class MovieService : DataService<Models.BookEntities> { // Этот метод вызывается только один раз для инициализации политик службы. Глава 9. Службы WCF Data Services 207 public static void InitializeService(DataServiceConfiguration config) { config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; } } Внимание! В приведенном примере DataService принимает тип по имени BookEntities, что зависит от имени базы данных. VS по умолчанию снабжает сущности префиксом по имени базы данных (при желании это можно исправить в Chapter9Model.Designer.cs). Настройка содержимого в Internet Explorer По умолчанию в ответ на запрос WDS возвращает XML-код. Во время тестирования удобно просматривать возвращенный XML-код в браузере, подобном Internet Explorer. Однако по умолчанию Internet Explorer воспринимает результаты, возвращенные службой данных, как информацию канала RSS в форме AtomPub. Это не слишком полезно, потому для просмотра XML-кода следует изменить настройки Internet Explorer. 1. Откройте Internet Explorer и выберите в меню пункт СервисÖСвойства обозревателя. В открывшемся диалоговом окне перейдите на вкладку Содержание. 2. Щелкните на кнопке Параметры в разделе Каналы и веб-фрагменты и в открывшемся диалоговом окне снимите отметку с флажка Включить показ ленты чтения канала (рис. 9.6). Рис. 9.6. Изменение настроек представления содержимого в Internet Explorer 8 Введение в WDS К этому моменту служба данных готова. 1. Щелкните правой кнопкой мыши на MovieService.svc и выберите в контекстном меню пункт Set As Start Page (Установить как стартовую страницу). 2. Нажмите <F5> для запуска приложения. Если все в порядке, то на экране отобразится XML-представление классов EF (рис. 9.7). Запрос служб WCF Data Services Для передачи параметров запроса службы WCF Data Services используют URL. Например, чтобы извлечь название фильмов, в конец существующего URL необходимо добавить /Films (например, URL может выглядеть так: http://localhost/Chapter9/ MovieService.svc/Films). В результате должен быть получен список всех фильмов в формате AtomPub, как показано на рис. 9.8. 208 Глава 9. Службы WCF Data Services Рис. 9.7. Вывод, полученный в результате обращения к тестовой службе Рис. 9.8. Возврат списка всех фильмов из базы данных Получать все данные сразу — не всегда удобно, поэтому WDS поддерживает набор операций запросов, которые работают с URL. Некоторые часто используемые методы перечислены в табл. 9.1, а полный их список доступен по адресу: http://msdn.microsoft.com/en-us/library/cc907912.aspx Глава 9. Службы WCF Data Services 209 Таблица 9.1. Список распространенных операций запросов Действие Операция Получить фильм с идентификатором, равным 3 Films(3) Выбрать фильм с FilmID, равным 3 Films?$filter=FilmID%20eq%203 Получить поле FilmName (Название фильма) из первого FilmShowing (Сеанс) FilmShowings(1)/Film/Title Получить сеансы первого фильма Films(1)/FilmShowings Отобразить заказы по дате заказа Orders?$orderby=OrderDate Упорядочить список фильмов по убыванию Orders?$orderby=OrderDate%20desc Выбрать два верхних заказа Orders?$top=2 Пропустить первый заказ и выбрать следующие два Orders?$skip=1&top=2 При работе со службами WCF Data Services необходимо помнить о следующих моментах. • Объекты чувствительны к регистру символов. Film — это не то же самое, что film. • Запрос должен быть закодирован для URL, поэтому пробелы следует заменять %20. • Для указания опций применяется символ строки запроса ? и $. Существует ли способ ограничения количества возвращаемых записей? Существует, если используются службы WCF Data Services версии 1.5. Изменения в VS2010/.NET 4.0 описаны далее в главе. Безопасность служб WCF Data Services WDS позволяет организовать тонко настраиваемый доступ к индивидуальным сущностям. Например, откройте MovieService.cs и найдите следующую строку: config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); Этот код позволяет организовать доступ только для чтения ко всем сущностям (определяется символом *). Чтобы открыть полный доступ ко всему (обычно это очень плохая идея, но для целей тестирования подходит), необходимо указать такую строку: config.SetEntitySetAccessRule("*", EntitySetRights.All); Внимание! Если сделать так, то любой, имеющий доступ к службе данных, получит полный доступ к данным. Привилегии могут применяться к отдельным объектам, которые указываются своими именами. Следующая строка кода откроет полный доступ к сущности Film: config.SetEntitySetAccessRule("Films", EntitySetRights.All); Очень скоро нам понадобится полный доступ к сущности Film, поэтому добавьте приведенную ниже строку в MovieService.cs. 210 Глава 9. Службы WCF Data Services Перехватчики запросов Иногда требуется перехватить пользовательский запрос, чтобы применить к нему дополнительную логику (например, чтобы фильтровать данные в зависимости от текущего пользователя). WDS позволяет делать это с помощью перехватчиков запросов. В следующем примере демонстрируется применение этой техники к любым запросам фильмов, разрешая передавать только те, у которых значение FilmID равно 1. Добавьте в MoveService.svc такой код: using System.Linq.Expressions; [QueryInterceptor("Films")] public Expression<Func<Film, bool>> FilterOnlyShowFilmID1() { return f => f.FilmID==1; } Возврат результатов в других форматах Службы WDS могут возвращать данные в следующих форматах: • AtomPub • JSON • XML AtomPub — формат возврата по умолчанию. Начиная с WDS 1.5, можно управлять отображением элементов на элементы AtomPub. Давайте посмотрим, как возвращать результаты в формате JSON, используя jQuery, а затем — как обратиться к службе WDS из консольного приложения. Использование JSON в JavaScript JSON — это формат, обычно используемый веб-приложениями, поскольку он существенно менее многословен, чем XML. Формат JSON также воспринимается многими библиотеками JavaScript. Если необходимо, чтобы службы WCF Data Services форматировали результаты в JSON, при выполнении запроса установите заголовок Accept в application/json. В следующем примере показано, как использовать jQuery для извлечения названия первого фильма в наборе (за дополнительной информацией о jQuery обращайтесь в главу 12): <script> function getMovieTitle() { $.ajax({ type: "GET", dataType: "json", url: "MovieService.svc/Films(1)", success: function (result) { alert(result.d.Title); }, error: function (error) { alert('error '); } }); } </script> <input type="button" Value="Get Movie Title" onclick="javascript:getMovieTitle();" /> Глава 9. Службы WCF Data Services 211 Какие данные JSON будут возвращены предыдущим вызовом? Используя прокси Fiddler (www.fiddlertool.com), предназначенный для отладки веб-приложений, можно посмотреть, что возвращается. Ниже приведен низкоуровневый код JSON: { "d" : { "__metadata": { "uri": "http://localhost/Chapter9/MovieService.svc/Films(1)", "type": "Models.Film" }, "FilmID": 1, "Title": "Kung Fu Panda", "Description": "Classic martial arts tale", "Length": 120, "FilmShowings": { "__deferred": { "uri": " http://localhost/Chapter9/MovieService.svc/Films(1)/FilmShowings" } } } } Обратите внимание, что результаты упакованы в объект по имени d. Это предотвращает атаки с использованием CSRF (Cross Site Request Forgery — межсайтовая подделка запросов). (Более подробную информацию можно получить в главе 11.) Использование JSON в C# В следующем коде показано, как извлекать результаты, сформатированные в виде JSON, с использованием класса HttpWebRequest в C#: System.Net.HttpWebRequest Request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create( "http://localhost/Chapter9/MovieService.svc/Films(1)" ); Request.Method = "GET"; Request.Accept = "application/json"; System.Net.HttpWebResponse Response = (System.Net.HttpWebResponse)Request. GetResponse(); using (System.IO.StreamReader sr = new System.IO.StreamReader(Response. GetResponseStream())) { Console.WriteLine(sr.ReadToEnd()); } Console.ReadKey(); Прокси-классы WDS Хотя во многих случаях работа будет осуществляться с низкоуровневым кодом XML или JSON, возвращенным из службы WDS, все же проще иметь дело со сгенерированными прокси-классами. Такие классы могут существенно облегчить выполнение простых операций CRUD и операций запросов. Разумеется, внутренне они используют HTTP. Извлечение элементов с помощью прокси-классов Давацте создадим приложение, которое будет выполнять итерацию по объектам Order, используя LINQ и класс DataServiceContext. Необходимые шаги перечислены ниже. 1. Добавьте к решению новое консольное приложение по имени Chapter9. ADOProxy. 2. Щелкните правой кнопкой мыши на папке References. 212 Глава 9. Службы WCF Data Services 3. Выберите в контекстном меню пункт Add Service Reference (Добавить ссылку на службу) для добавления URL, на который настроена служба WDS (например, http://localhost/Chapter9/MovieService.svc). 4. Выберите узел BookEntities в поле Services (Службы). 5. Введите пространство имен MovieService (рис. 9.9). Рис. 9.9. Добавление ссылки на службу WDS 6. Щелкните на кнопке OK. Visual Studio сгенерирует классы, представляющие сущности в консольном приложении. 7. Откройте Program.cs и добавьте следующий оператор using: using System.Data.Services.Client; 8. Введите приведенный ниже код для прохождения по списку заказов Order с выводом имени в окно консоли: static void Main(string[] args) { DataServiceContext ctx = new DataServiceContext( new Uri("http://localhost/Chapter9/MovieService.svc")); var Orders = ctx.Execute<MovieService.Models.Order>( new Uri("Orders", UriKind.Relative)); foreach (MovieService.Models.Order Order in Orders) { Console.WriteLine(Order.Firstname); } Console.ReadKey(); } 9. Нажмите <F5> для запуска приложения. Вы должны увидеть список имен из таблицы Orders. Глава 9. Службы WCF Data Services 213 Добавление нового элемента с помощью прокси-классов Создать новый элемент, используя WCF Data Services, очень легко. Для этого достаточно воспользоваться методами AddObject() и SaveChanges() класса DataServiceContext: static void Main(string[] args) { DataServiceContext ctx = new DataServiceContext(new Uri("http://localhost/Chapter9/MovieService.svc")); MovieService.Models.Film NewFilm = new MovieService.Models.Film(); NewFilm.Title = "Pulp Fiction"; NewFilm.Length = 124; NewFilm.Description = "Quentins classic movie"; ctx.AddObject("Films", NewFilm); ctx.SaveChanges(); } Обновление элемента Чтобы обновить существующий элемент, загрузите объект и воспользуйтесь методами UpdateObject() и SaveChanges() класса DataServiceContext: static void Main(string[] args) { DataServiceContext ctx = new DataServiceContext(new Uri("http://localhost/Chapter9/MovieService.svc")); MovieService.Models.Film FilmToUpdate = ctx.Execute<MovieService.Models.Film>( new Uri("Films(1)", UriKind.Relative)).First(); FilmToUpdate.Title = "Updated title"; ctx.UpdateObject(FilmToUpdate); ctx.SaveChanges(); } Удаление элемента Чтобы удалить элемент, последовательно вызовите методы DeleteObject() и SaveChanges() класса DataServiceContext (если определены табличные ограничения или правила, потребуется обеспечить их выполнение, иначе этот код даст сбой): static void Main(string[] args) { DataServiceContext ctx = new DataServiceContext(new Uri("http://localhost/Chapter9/MovieService.svc")); MovieService.Models.Film FilmToDelete = ctx.Execute<MovieService.Models.Film>( new Uri("Films(1)", UriKind.Relative)).First(); ctx.DeleteObject(FilmToDelete); ctx.SaveChanges(); } WDS 1.5 WDS версии 1.5 входит в состав VS2010 и добавляет ряд средств, таких как возможность ограничения количества возвращаемых элементов данных и генерация веб-каналов (отображений элементов AtomPub). 214 Глава 9. Службы WCF Data Services На заметку! Команда разработчиков даже утверждает, что они собираются реализовать автономный режим WDS. Подсчет строк и управляемое сервером разбиение на страницы Ранее одной из основных проблем при работе с WDS было отсутствие возможности узнать количество возвращаемых результатов. Это не позволяло организовать разбиение данных на страницы и эффективную работу со службами WDS. Версия WDS 1.5 предлагает возможность запросить количество записей в результате через операции $count и $inlinecount. $count Операция $count вернет одиночное текстовое значение, которое указывает количество строк, возвращаемых определенным запросом. Ниже показано, как вернуть количество заказов: http://localhost/Chapter9/MovieService.svc/Orders/$count Обратите внимание, что $count применяется к набору из 100 элементов. Кроме того, используются операции $skip, $top или $take, после чего возвращенное число представляет собой количество после применения операций $skip или $take. $inlinecount=allpages Операция $inlinecount=allpages возвращает счетчик элементов вместе с текущим результатом запроса. Это вернет количество элементов с игнорированием любых операций $skip или $take (в отличие от $count). Значение количества содержится в новом элементе m:count (m здесь означает “metadata” (метаданные)). Ниже демонстрируется использование этого средства в таблице Orders: http://localhost/Chapter9/MovieService.svc/Orders?$inlinecount=allpages В коде XML будет присутствовать новый элемент, показывающий встроенное значение счетчика: <m:count>4</m:count> Ограничение количества возвращаемых результатов Ограничение количества результатов, возвращаемых вызовом WDS, осуществляется с помощью нового метода Config.SetResourcePageSize(). Следующий код ограничивает запрос к таблице Orders только двумя результатами: config.SetEntitySetPageSize("Orders", 2); При наличии большего числа результатов, чем указанный размер страницы, то WDS также сделает доступной следующую ссылку, через которую можно извлечь последующие страницы: <link rel="next" href="http://localhost/Chapter9/MovieService.svc/Orders?$skiptoken=2" /> В настоящее время не существует поддержки этой функциональности на стороне клиента, хотя команда разработчиков WDS утверждает, что они намерены добавить ее в будущем выпуске. Глава 9. Службы WCF Data Services 215 Проекции Проекции позволяют сообщить службе WDS о необходимости возврата только определенных типов элементов и создаются добавлением операции $select к запросу. Например: http://localhost/Chapter9/MovieService.svc/Orders?$select=Firstname,Lastname Обратите внимание, что для использования этого средства должна быть активизирована версия 2 служб WDS: config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; При использовании проекций можно также применять сложные типы и свойства навигации: http://localhost/Chapter9/MovieService.svc/ Orders?$select=Firstname,Lastname,OrderItems Предыдущий запрос возвращает ссылку на сложный тип или свойство навигации. Для возврата деталей от связанного элемента служит операция $expand. Следующий запрос возвращает Firstname и Lastname, а также детали OrderItems: http://localhost/Chapter9/MovieService.svc/ Orders?$select=Firstname,Lastname,OrderItems&$expand=OrderItems Дружественные каналы Теперь можно отображать свойства модели EF на индивидуальные элементы AtomPub. В рассматриваемом примере с фильмами можно было бы отобразить имя режиссера на AtomPub-элемент author. Можно также создавать специальные классы и управлять форматированием вывода. За дополнительной информацией об этих средствах обращайтесь на http://blogs.msdn.com/astoriateam/archive/2009/09/01/ customizable-feed-support-in-ctp2.aspx. Прочие усовершенствования Команда разработчиков WDS также внесла и ряд других усовершенствований. • WDS 1.5 поддерживает двунаправленную привязку данных (DataServiceCollection), что замечательно для сценариев WPF/Silverlight. За дополнительной информацией обращайтесь в главу 15 и к следующей статье в блоге: http://blogs.msdn.com/ astoriateam/archive/2009/09/17/introduction-to-data-binding-insilverlight-3-with-ctp2.aspx • Улучшенная поддержка потоковой передачи крупных массивов двоичных данных. Какая связь между службами WDS и WCF RIA Services? Скотт Гатри (Scott Guthrie) говорил об этом на RedDevNews.com (еще до изменения названия служб): Следует ли отдавать предпочтение службам .NET RIA Services перед ADO.NET Data Services при доступе к данным Silverlight Data Access? Нет. То, что реализовано сегодня для RIA Services, построено на базе ADO.NET Data Services. Поэтому к ADO.NET Data Services можно относиться, как к низкоуровневому API-интерфейсу RAW/REST, а к RIA Services — как к верхнему уровню. 216 Глава 9. Службы WCF Data Services Мы определенно полагаем, что бывают сценарии, когда понадобится иметь дело с чистой моделью службы REST. Службы .NET RIA Services предоставляет такие вещи, как проверка достоверсности, межуровневое взаимодействие и высокоуровневые службы. Мы усердно потрудились, чтобы должным образом упорядочить их, так что службы RIA Services не являются конкурирующей технологией, и на самом деле они построены на основе ADO.NET Data Services. http://reddevnews.com/articles/2009/07/13/ interview-with-scott-guthrie-on-silverlight-3.aspx Резюме Службы WCF Data Services существенно облегчают представление данных в сценариях интеграции с третьими сторонами. WDS могут также использоваться как интеграционный уровень для проектов веб-приложений и проектов Silverlight. Последний выпуск WCF Data Services содержит столь необходимые средства разбиения на страницы и проекции, так что выглядит весьма удобной технологией. Заинтересованным разработчикам также стоит обратить внимание на построенные поверх WDS службы WCF RIA Services, которые добавляют множество дополнительных средств. Материалы для дополнительного чтения • http://blogs.msdn.com/astoriateam/ • http://msdn.microsoft.com/en-us/library/cc907912.aspx