8 сентября 2012 г.

Шаблоны T4 в Visual Studio


Всем привет! Сегодня я хочу рассказать вам о замечательной технологии, которую предоставляет разработчикам Visual Studio – среда разработки шаблонов, известная под кодовым именем Т4.
Наверняка многие из вас сталкивались с такой очень распространенной задачей, как генерация писем. Одним из самых распространенных решений для таких задач являются XSLT трансформации. Вы определяете шаблон письма, включая различные операторы XSLT и затем вызываете специальный генератор, который осуществляет трансформацию, на основе переданных данных для письма. Данная технология отлично работала, и я сам ею пользовался, пока не столкнулся с механизмом Т4.

2 сентября 2012 г.

Использование привязки Duplex Binding в WCF


Добрый день. Сегодня мы рассмотрим один из нестандартных типов связи, который предоставляет разработчикам Windows Communication Foundation - двухстороння связь или Duplex mode.
Классической схемой взаимодействия клиента с сервисом является режим запрос - ответ. Клиент посылает сервису запрос и немедленно получает от сервиса ответ с данными. Однако такая схема не всегда способна удовлетворить потребности разработчика, особенно при разработке сервисных систем со сложной архитектурой.

23 июля 2012 г.

Работа с XML данными в Microsoft SQL Server 2008. Особенности работы с XML.


В прошлой статье мы познакомились с типом данных «XML» в Microsoft SQL Server 2008, научились писать разнообразные запросы для выборки данных из XML документов. Однако на этом возможности этого типа данных не исчерпываются. Кроме операций для выборки данных, также предоставляются функции для добавления, обновления и удаления XML данных.
Все вышеперечисленные операции можно выполнить при помощи функции modify().

17 июля 2012 г.

Работа с XML данными в Microsoft SQL Server 2008. Тип данных «xml».



В прошлой статье мы узнали, каким образом из базы можно извлекать реляционные данные в виде XML структуры. Сегодня мы познакомимся с принципами хранения структуры XML данных в базе.
Основной элемент поддержки XML в MS SQL Server – тип данных “xml”. Данный тип может использоваться для объявления переменных и как тип колонки в таблице наравне со стандартными типами данных SQL (int, nvarchar и т.д.).
Для типа данных XML доступны следующие специализированные операции. Приведем их краткое описание:
  1. query() – осуществляет запросы к XML данным;
  2. nodes() – извлекает поддерево из структуры XML.
  3. value() – позволяет извлекать значения атрибутов из XML элемента;
  4. exist() – проверяет существуют ли результаты запроса;
  5. modify() – производит обновление XML данных;

8 июля 2012 г.

Работа с XML в Microsoft SQL Server 2008. Выборка данных в формате XML.


Всем привет! В этой статье мы поговорим о типе представления данных XML и рассмотрим, какие средства предоставляет Microsoft SQL Server 2008 для работы с XML. Для начала, давайте вспомним, что такое XML и как он выглядит. Язык XML – один из самых распространенных форматов представления иерархических данных практических во всех платформах и технологиях. В основе веб-страниц лежит язык HTML, который является подвидом XML. В основе сервисов SOAP лежит обмен данными в формате XML. Данное представление, также пользуется популярностью на многих платформах в качестве хранилища данных.

24 июня 2012 г.

Использование SQL CLR в Microsoft SQL Server 2008


Microsoft SQL Server и язык T -SQL обладают достаточно широким набором команд, параметров и функций, которые позволяют разработчику выполнять практически любые запросы к базам данных. Однако, в некоторых ситуациях данной инфраструктуры оказывается недостаточно для удовлетворения самых изощренных потребностей разработчиков. Здесь на помощь приходит расширение SQL Server под названием SQL CLR.
SQL CLR – это технология, позволяющая значительно увеличить гибкость и расширить возможности разработчиков при работе с базами данных в SQL Server. При помощи SQL CLR возможно писать собственные функции, хранимые процедуры и триггеры на языках программирования C# или Visual Basic, а затем импортировать этот код в среду SQL Server и использовать его при написании запросов на языке T-SQL. Поскольку такой язык как C# предоставляет разработчику гораздо более широкий набор возможностей, чем T-SQL, импортирование C# функций в SQL Server будет отличным решением многих задач, требующих специфичных вычислений.

17 июня 2012 г.

Управление транзакциями в C#


В прошлой статье мы познакомились с таким понятием, как транзакция. Было рассмотрено, каким образом можно управлять транзакциями на уровне SQL Server. Сегодня мы научимся создавать и использовать транзакции из программного кода C#.
В .NET существуют два типа транзакций: локальная транзакция и распределенная транзакция. Локальные транзакции работают в пределах одного соединения к базе данных, а распределенные способны отслеживать команды к нескольким источникам данных одновременно.

10 июня 2012 г.

Управление транзакциями в Microsoft SQL Server 2008


Сегодня мы обсудим одно из фундаментальных понятий в SQL Server 2008 – транзакции. Транзакции позволяют управлять набором команд, которые выполняются в базе данных, как единым целым. Использование транзакции предоставляют разработчику следующие преимущества:
  1. Если две команды работают внутри одной транзакции – то будут выполнены обе команды, либо ни одной;
  2. Если какая-либо команда внутри транзакции завершится с ошибкой – все команды транзакции будут отмены и данные вернутся в то состояние, в каком они были до начала транзакции;
  3. Во время выполнения транзакции данные могут оставаться изолированными и недоступными для других транзакций;
  4. После успешного выполнения команды фиксации транзакции данные гарантированно сохранятся в базе.

18 мая 2012 г.

Windows Live SDK: Аутентификация пользователя на сайте

 

    Здравствуйте друзья! Сегодня я бы хотел вам рассказть о наборе инструментов, который позволяет разработчикам легко организовать взаимодействие их приложений с сервисами семейства Windows Live от компании Microsoft.

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

    Провайдеры внешних сервисов аутентификации (в первую очередь конечно социальные сети) предоставляют широкий набор средств (API) для использования их возможностей извне.

    Не осталась в стороне и компания Microsoft. И хотя сервисы Windows Live нельзя назвать социальной сетью, это достаточно распостраненная система аутентификации для всех, кто так или иначе взаидоействует с ресурсами компании Microsoft.

    В 2012 году Microsoft выпускает первые версии новой операционной системы Windows 8 и анонсирует новую концепцию разработки приложений для платформы Windows – Metro приложения написанные при помощи HTML и JavaScript.

    В связи с этим Майкрософт также выпускает новый пакет средств (SDK) для работы с сервисами Windows Live из Metro приложений при помощи JavaScript. Надо отметить, что сервисы Windows Live существует достаточно давно, и, конечно, раньше тоже существовали средства для работы с ними. Однако, назвать их удобными и понятными явно было нельзя. Поэтому новый SDK приятно всех удивил своей простотой и схожестью с похожимы интерфейсами Twitter и Facebook.

   Сегодня, я хочу вам показать каким образом можно интегрировать аутетификацию через Windows Live в ваш ASP.NET MVC сайт.

  Первым делом необходимо зарегистрировать ваше приложение в центре разработки Windows Live по следующей ссылке: https://manage.dev.live.com/Applications/Index

Необходимо ввести название приложения, адрес возврата ответа от сервиса аутентификации (доменное имя вашего сайта) и скопировать значение “Client ID”. Примеры форм находятся на скриншотах ниже:

 

 

 

 

 

 

 

 

  

   Создадим стандартный сайт шаблона ASP.NET MVC Framework и перейдем в представление Index.cshtml.

   Для использования Windows Live JavaScript SDK необходимо разместить на странице ссылку на следующий скрипт:

<script type="text/javascript" src="http://js.live.net/v5.0/wl.js"></script>

   Далее нам необходимо кнопка, при нажатии на которую пользователь бы начинал процедуру аутентификации через Windows Live Connect. Тут у вас есть выбор, можно создать свой элемент разметки и привязать функции входа к какому-либо событию этого элемента, или попросить Windows Live SDK создать для нас красивую “фирменную” кнопку входа. Мы поступим вторым способом. Для этого в разметку страницы необходимо добавить следующий фрагмент кода:

<p>   
    <div id="signin"></div>
</p>

<script type="text/javascript">
    WL.init({
        client_id: "ваш CLIENT ID",
        redirect_uri: "@(Request.Url.AbsoluteUri)",
        scope: ["wl.signin"],
        response_type: "token"
    });
   
    WL.ui({
        name: "signin",
        element: "signin"
    });
</script>

   В результате на странице будет отображена кнопка следующего вида:

  При нажатии на кнопку будет открываться диалоговое окно, где пользователь сможет ввести свой логин и пароль в сиcтеме Windows Live. На кнопке изображена надпись “Sign In”, когда пользователь неавторизированный, и “Sign Out”, когда пользователь уже прошел аутентификацию.

  Все что нам осталось -  узнать когда пользователь успешно пройдет атентификацию и мы сможем работать с его данными из сервиса Windows Live. Для этого определим JavaScript функцию, которая будет выполнена после того как пользователь успешно авторизируется:

<script type="text/javascript">
    WL.Event.subscribe("auth.login", onLogin);

    function onLogin() {
        WL.api({ path: "me", method: "GET" }).then(
            function (response) {
                $('#userName').text("Hello " + response.name + "!");
            }
        );
    }
</script>

  Теперь мы можем осуществлять запросы к сервисам Windows LIve. Для примера давате загрузим имена и почтовые ящики контактов из почты HotMail. Для этого необходимо сначала модифицировать функцию инициализации среды Windows Live SDK:

<script type="text/javascript">
    WL.init({
        client_id: "00000000480C037B",
        redirect_uri: "@(Request.Url.AbsoluteUri)",
        scope: ["wl.signin", "wl.basic"],
        response_type: "token"
    });
</script>

  Если вы заметили, я добавил еще одну перменную в поле “scope”. В этом поле хранится список ресурсов к которым вы хотите получить доступ. При аутентификации сервис конекта Windows Live покажет пользователю какую информацию запрашивает ваш сайт и спросит его дает ли он свое согласие на использование его персональных данных.

  После получения подтверждения пользователя мы можем еще раз обратиться к сервису Windows Live и запросить у него список контактов почты HotMail пользователя:

<p>
    <ul id="contacts"></ul>
</p>
<script type="text/javascript">
    $('#loadLiveFriends').click(function() {
        WL.api({
            path: "me/contacts",
            method: "GET"
        }).then(
                function (response) {
                    $.each(response.data, function(key, value) {
                        $('#contacts').append('<li>Name - ' + value.name + ‘ Email - ’ + value.email +'</li>');
                    });
                }
            );
    });
</script>

  Данная функцию выведет имя контакта и его почтовый ящик в список на странице. Список – это элемент разметки “ul” с идентификатором “contacts”.

  В данной статье мы рассмотрели пример использования элементарных функций Windows Live SDK для веб платформы. Были описаны функции для аутентификации пользователей и загрузки списка контактов. Полный список предоставляемых функций намного больше, вы можете найти их описание и примеры использования на новом портале MSDN: http://msdn.microsoft.com/en-us/library/live/

21 апреля 2012 г.

Организация работы с базой данных посредством сервисов WCF

 

Часть 1. Создание тестовой базы данных.

   Целью данной статьи является создание сервиса при помощи технологии Windows Communication Foundation для демонстрации слоя доступа к базе данных в контексте сервис-ориентированной архитектуры.

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

  Для этого выполним следующую последовательность действий:

  1) Открыть приложение Microsoft SQL Server Management Studio и подключится к серверу баз данных на локальном компьютере или на удаленном хосте;

  2) Создадим базу данных выполнив следующий скрипт:

CREATE DATABASE [ProductsDB] ON PRIMARY

( NAME = N'ProductsDB',

FILENAME = N'c:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\ProductsDB.mdf' ,

SIZE = 3072KB , FILEGROWTH = 1024KB )

LOG ON ( NAME = N'ProductsDB_log',

FILENAME = N'c:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\ProductsDB_log.ldf' ,

SIZE = 1024KB , FILEGROWTH = 10%) GO

   При необходимости можно изменить параметр FILENAME для файла базы данных и лог-файла.

   3) Создадим таблицу Products в ранее созданной базе данных ProductsDB, выполнив следующий скрипт:

USE [ProductsDB] GO

CREATE TABLE [dbo].[tb_Products]

( [Id] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](50) NOT NULL, [Description] [nvarchar](500) NOT NULL,

[Price] [int] NOT NULL, CONSTRAINT [PK_tb_Products] PRIMARY KEY CLUSTERED

( [Id] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO

   4) Для тестирования различных способов взаимодействия с базой данных создадим тестовую хранимую процедуру, которая будет возвращать записи из таблицы tb_Products, у которых поле Name будет совпадать с параметром @Name, переданным в хранимую процедуру:

CREATE PROCEDURE sp_GetProductsByName

@Name nvarchar(50)

AS BEGIN

SELECT Id, Name, Description, Price FROM tb_Products WHERE Name LIKE '%' + @Name + '%';

END GO

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

 

Часть 2. Разработка WCF сервиса.

Следующий этап – создание кода ля выполнения запросов к базе данных средствами языка программирования C#.

Откроем среду разработки Microsoft Visual Studio 2010 и создадим новый проект, выбрав тип проекта – ASP.NET Empty Web Application. Проекты на основе языка программирования ASP.NET идеально подходят для быстрого создания и развертывания сервисов WCF. Назовем проект «WCF_DataAccess».

clip_image002

Теперь приступим к созданию WCF сервиса. Перейдем в Solution Explorer и поставив курсор на узел проекта нажмем правую кнопку мыши. Далее в контекстном меню необходимо выбрать пункт «Add – New Item». Далее на вкладке Web нужно выбрать тип файла – «WCF Service». Назовем файл «DbService.svc».

clip_image004

Среда выполнения добавит в наш проект два новых файла «DbService.svc» и «IDbService.cs»:

clip_image005

Также необходимо создать вспомогательный класс ProductBO, который будет выполнять сразу несколько функций – это будет оболочка для записи из таблицы tb_Products, а также контракт данных для использования его в WCF. Сигнатура класса приведена ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
namespace WCF_DataAccess

{
   [DataContract]
   public class ProductBO
   {
       [DataMember]
       public int Id { get; set; }
       [DataMember]
       public string Name { get; set; }
       [DataMember]
       public string Description { get; set; }
       [DataMember]
       public int Price { get; set; }
}
}

Аттрибут [DataContract] означет что этот класс может использоваться для передачи данных между сервисом WCF и его клиентами. Атрибут [DataMember] указывает какие поля данных должны быть включены в сообщение при передаче по каналам связи WCF.

Теперь мы можем перейти к написанию сервиса. Сервис в WCF сосотит из двух частей:

1) Контракт сервиса – это файл «IDbService.cs». В этом файле находится контракт сервиса – интерфейс на языке C#, который помечен атрибутом [ServiceContract]. Интерфейс содержит набор определений методов, которые помечены атрибутом [OperationContract]. Данный интерфейс называется контрактом сервиса, птомучто он декларирует точное описание методов, которые будет предоставлять своим клиентам WCF сервис. Код интерфейса приведен ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WCF_DataAccess
{
     [ServiceContract]
      public interface IDbService
      {
          [OperationContract]
          List<ProductBO> GetAllProducts();
          [OperationContract]
          void InsertProduct(ProductBO product);
          [OperationContract]
          void DeleteProductById(int productId);
         [OperationContract]
         List<ProductBO> GetProductsByName(string name);
     }
}

2) Реализация сервиса – файл «DbService.svc». Здесь находится класс DbService, который наследует и реализует контракт сервиса – интерфейс IDbService. Поскольку мы будем работать с базой данных через наш сервис, класс DbService будет также реализовывать интерфейс IDisposable.

public class DbService : IDbService, IDisposable

Класс будет содержать одно поле и конструктор:

private SqlConnection _connection;
public DbService()
{
    string connectionString = ConfigurationManager.ConnectionStrings["ProductsDBConnectionString"].ConnectionString;
    _connection = new SqlConnection(connectionString);
    _connection.Open();
}

В конструкторе создается соединение с базой данных. Строка соединения берется из файла конфигурации Web.config, где она имеет следующий вид:

<configuration>
     <connectionStrings>
            <add name="ProductsDBConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=ProductsDB;Integrated Security=True" />
      </connectionStrings>

Приступим к реализации методов сервиса:

Выборка всех продуктов из таблицы:

public List<ProductBO> GetAllProducts()
{
       string query = "SELECT Id, Name, Description, Price FROM tb_Products";
       SqlCommand command = new SqlCommand(query, _connection);
       SqlDataReader dataReader = command.ExecuteReader();
       List<ProductBO> products = new List<ProductBO>();
       while (dataReader.Read())
      {
            products.Add(new ProductBO()
           {
               Id = dataReader.GetInt32(0),
               Name = dataReader.GetString(1),
               Description = dataReader.GetString(2),
               Price = dataReader.GetInt32(3)
          });
     }
     return products;
}

Добавление записи в таблицу продуктов:

public void InsertProduct(ProductBO product)
{
       string query = "INSERT INTO tb_Products VALUES (@name, @desc, @price);";
       SqlCommand command = new SqlCommand(query, _connection);
       command.Parameters.Add(new SqlParameter()
       {
            DbType = DbType.String,
            Value = product.Name,
            ParameterName = "name"
      });
      command.Parameters.Add(new SqlParameter()
      {
           DbType = DbType.String,
           Value = product.Description,
           ParameterName = "desc"
     });
     command.Parameters.Add(new SqlParameter()
     {
          DbType = DbType.Int32,
          Value = product.Price,
          ParameterName = "price"
     });
     command.ExecuteNonQuery();
}

Удаление продукта из таблицы по его Id:

public void DeleteProductById(int productId)
{
        string query = "DELETE FROM tb_Products WHERE Id = @id";
        SqlCommand command = new SqlCommand(query, _connection);
        command.Parameters.Add(new SqlParameter()
       {
            DbType = DbType.Int32,
            Value = productId,
            ParameterName = "id"
       });
       command.ExecuteNonQuery();
}

Выборка продуктов с фильтрацией продуктов по полю Name, при помощи хранимой процедуры:

public List<ProductBO> GetProductsByName(string name)
{
         SqlCommand command = new SqlCommand();
         command.Connection = _connection;
         command.CommandType = CommandType.StoredProcedure;
        command.CommandText = "sp_GetProductsByName";
        command.Parameters.Add(new SqlParameter()
        {
             DbType = DbType.String,
             Value = name,
             ParameterName = "Name"
        });
        SqlDataReader dataReader = command.ExecuteReader();
        List<ProductBO> products = new List<ProductBO>();
        while (dataReader.Read())
        {
              products.Add(new ProductBO()
              {
                    Id = dataReader.GetInt32(0),
                    Name = dataReader.GetString(1),
                    Description = dataReader.GetString(2),
                    Price = dataReader.GetInt32(3)
              });
       }
       return products;
}

И последний метод – член интерфейса IDisposable – Dispose:

public void Dispose()
{
       _connection.Close();
}

Данный метод будет вызываться автоматически после завершения работы сервиса.

На этом написание кода сервиса завершено. Попробуем его запустить, для этого в Solution Explorer необходимо установить курсор на файл DbService.svc и в контекстном меню выбрать пункт “View In Browser”. После нажатия откроется окно браузера. Адрес страницы, которая откроется в браузере, и будет адресом нашего сервиса(он нам понадобится позже, для тестирования сервиса). В окне браузера должно быть приблизительно следующее содержимое:

clip_image007

Это значит, что наш сервис правильно настроен и работает. На этом разработка сервиса завершена. Давайте проверим его в действии.

 

Часть 3. Разработка клиента для тестирования сервиса.

Для тестирования сервиса создадим простое консольное приложение:

clip_image001

Для работы с сервисом нам понадобится ссылка на этот сервис. Чтобы ее добавить необходимо в Solution Explorer установить курсор на узел проекта и выбрать пункт «Add Service Reference». На экране появится следущее окно:

clip_image003

В поле Address необхимо ввести адрес из браузера и нажать кнопку Go. Затем в поле Namespace указать значение «Service Refference» - это пространство имен в котором будут расположены классы для работы с сервисом. В конце жмем кнопку «Ok».

Модифицируем файл Program.cs внеся туда код для использования нашего сервиса:

class Program
{
    static void Main(string[] args)
    {
          var service = new DbServiceClient();
          Console.WriteLine("Add product: ");
          ProductBO newProduct = new ProductBO() { Name = "Book", Description = "Classic", Price = 5 };
          service.InsertProduct(newProduct);
          Console.WriteLine("Success!\n");
          Console.WriteLine("Add product: ");
          newProduct = new ProductBO() { Name = "Pencil", Description = "Red", Price = 1 };
          service.InsertProduct(newProduct);
          Console.WriteLine("Success!\n");
          Console.WriteLine("Products list:");
          List<ProductBO> products = service.GetAllProducts().ToList();
          string productFormat = "Id - {0}, Name - {1}, Desc - {2}, Price - {3}";
          products.ForEach(product => Console.WriteLine(String.Format(productFormat, product.Id, product.Name,      product.Description, product.Price)));
          Console.WriteLine("Search by Name 'Book':");
          products = service.GetAllProducts().ToList();
          products.ForEach(product => Console.WriteLine(String.Format(productFormat, product.Id, product.Name,  product.Description, product.Price)));
          Console.WriteLine("Delete product with Id = 1: ");
          service.DeleteProductById(1);
          Console.WriteLine("Success!");
   }
}

Теперь нажав комбинацию клавиш Ctrl + F5 можно запустить тестовую программу.

На этом написание всех модулей системы завершено. Спасибо за внимание.