+7 (495) 229-0436   shopadmin@itshop.ru 119334, г. Москва, ул. Бардина, д. 4, корп. 3
 
 
Вход
 
 
Каталог
 
 
Подписка на новости
Новости ITShop
Windows 7 и Office: Новости и советы
Обучение и сертификация Microsoft
Вопросы и ответы по MSSQLServer
Delphi - проблемы и решения
Adobe Photoshop: алхимия дизайна
 
Ваш отзыв
Оцените качество магазина ITShop.ru на Яндекс.Маркете. Если вам нравится наш магазин - скажите об этом Google!
 
 
Способы оплаты
 
Курс расчета
 
 1 у.е. = 93.25 руб.
 
 Цены показывать:
 
 
 
 
  
Новости, статьи, акции
 

ASP.Net Expression Builders. Редактор своего типа выражений. Часть 2

15.02.2010 15:52

Продолжим играться с "построителями выражений" в ASP.Net.

Напомню, что существует три выражения поставляемые по умолчанию вместе с ASP.Net:

<system.web>

    <compilation>

        <expressionBuilders>

            <add expressionPrefix="Resources"

                 type="System.Web.Compilation.ResourceExpressionBuilder"/>

            <add expressionPrefix="ConnectionStrings"

                 type="System.Web.Compilation.ConnectionStringsExpressionBuilder"/>

            <add expressionPrefix="AppSettings"

                 type="System.Web.Compilation.AppSettingsExpressionBuilder"/>

        </expressionBuilders>

    </compilation>

</system.web>

Для каждого из них существует некоторый редактор, который позволяет устанавливать значения свойств в Design-Time.

Рассмотрим нашу небольшую страничку:

default.aspx

<%@ Page Language="C#" AutoEventWireup="true"

    CodeBehind="Default.aspx.cs" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>ASP.Net Expression Builder Test</title>

</head>

<body>

    <h1>ASP.Net Expression Builder Test</h1>

    <table class=borderall cellpadding="3" cellspacing="0">

        <col style="color: DarkGreen" align="left" />

        <tr>

            <th>$AppSettings</th>

            <td>

                <asp:Label ID="appSettingsLabel" runat="server"

                           Text='<%$ AppSettings: MyAppSetting %>' />

            </td>

        </tr>

        <tr>

            <th>$ConnectionStrings</th>

            <td>

                <asp:Label ID="connectionStringsLabel" runat="server"

                           Text='<%$ ConnectionStrings: MyConnectionString %>' />

            </td>

        </tr>

        <tr>

            <th>$Resources</th>

            <td>

                <asp:Label ID="resourcesLabel" runat="server"

                           Text='<%$ Resources: MyResources, MyResourceKey %>' />

            </td>

        </tr>

    </table>

</body>

</html>

Переключаемся в просмотр дизайна:

Скриншот: default.aspx в режиме Дизайн

Выбираем произвольный серверный контрол (на скриншоте у меня выбран первый appSettingsLabel) и смотрим в окно Properties.

Скриншот: Окно свойств в Design-Time

Вещи, на которые стоит обратить внимание я выделил. Первое, это маленький квадратик возле свойства Text - если к нему подвести мышь, то появиться подсказка "Property is expression bound.". Второе, это секция Data и её элемент (Expressions). Именно в нём и скрыт редактор, который позволяет присваивать различным свойствам элемента значения параметрам выражения.

Скриншот: Редактор для связывания построителей со свойствами элемента управления 

"Bindable properties" показывает список доступных свойств элемента управления к которым можно "прибиндить" выражение.

В выпадающем списке "Expression type" можно выбрать любой ExpressionBuilder зарегистрированный в web.config.

Теперь самое интересное. В окне "Expression properties" можно увидеть стандартный грид с набором свойств (да, на скриншоте видно только одно свойство, но если выбрать Resources среди типов, то там будет уже два). Этот грид является "редактором" для выбранного типа выражения. И для своего типа выражения можно реализовать свой редактор.

Делается это с помощью атрибута ExpressionEditorAttribute, наследника ExpressionEditor (который находиться в System.Design.dll) и наследника ExpressionEditorSheet.

Реализация редактора свойств для выражения

В качестве выражения я буду использовать простенькое выражение HashItExpression. Синтаксис выдумаем следующим:

<%$ HashIt: MD5("строка, хеш которой я хочу получить") : Base64 %>

Параметрами моего выражения будут служить:

  • Алгоритм хэширования (MD5, SHA1, SHA256, SHA512),
  • Текст в кавычках, который надо захешировать,
  • Кодировка в которой следует вывести получившийся набор байт (Base64 или Hex - строка в шестнадцатеричном представлений).

Вначале реализуем набор структур и функций, которые делают разбор выражения и вычисляют его значение.

HashItEvaluator.cs

using System;

using System.Linq;

using System.Security.Cryptography;

using System.Text;

using System.Text.RegularExpressions;

 

namespace Home.Andir.Examples

{

    public enum HashAlg

    {

        MD5,

        SHA1,

        SHA256,

        SHA512

    }

 

    public enum EncodeType

    {

        Base64,

        Hex

    }

 

    public static class HashItEvaluator

    {

        public class HashItParseResults

        {

            public HashAlg HashAlg { get; set; }

            public string Source { get; set; }

            public EncodeType EncodeType { get; set; }

        }

 

        public static string Eval(string expression)

        {

            var parseResults = ParseExpression(expression);

            if (parseResults != null)

            {

                return Eval(parseResults);

            }

 

            return "Invalid expression";

        }

 

        private static string Eval(HashItParseResults parseResults)

        {

            HashAlgorithm hash = CreateAlgorithm(parseResults.HashAlg);

 

            var result = hash.ComputeHash(

                Encoding.Default.GetBytes(parseResults.Source));

 

            if (parseResults.EncodeType == EncodeType.Hex)

            {

                return String.Concat(

                    result.Select(x => String.Format("{0:x2}", x)).ToArray()

                    );

            }

 

            return Convert.ToBase64String(result);

        }

 

        private static HashAlgorithm CreateAlgorithm(HashAlg alg)

        {

            switch (alg)

            {

                case HashAlg.MD5: return MD5.Create();

                case HashAlg.SHA1: return new SHA1Managed();

                case HashAlg.SHA256: return new SHA256Managed();

                case HashAlg.SHA512: return new SHA512Managed();

            }

 

            throw new ArgumentOutOfRangeException("alg");

        }

 

        public static HashItParseResults ParseExpression(string expression)

        {

            // expression == MD5(source) [: Base64]

            Regex expRe = new Regex(

                @"(?<alg>MD5/SHA1/SHA256/SHA512)\('(?<source>.+)'\)(\s*:\s*(?<enc>(Base64/Hex)))?",

                RegexOptions.IgnoreCase

                );

 

            var match = expRe.Match(expression);

 

            if (match != null)

            {

                string alg = match.Groups["alg"].Value;

                string source = match.Groups["source"].Value;

                string enc = match.Groups["enc"].Value;

 

                return new HashItParseResults()

                {

                    HashAlg = (HashAlg)Enum.Parse(typeof(HashAlg), alg, true),

                    Source = source,

                    EncodeType = enc.ToUpper() == "BASE64" ? EncodeType.Base64 : EncodeType.Hex

                };

            }

 

            return null;

        }

    }

}

Метод HashItEvaluator. ParseExpression   пытается распарсить выражение с помощью регулярных выражений и если ему это удаётся, то возвращает структуру с результатами.

Метод HashItEvaluator. Eval используя результаты парсинга, вычисляет выражение (то есть хеширует строчку и полученный результат представляет в текстовом виде).

Ну а теперь можно и реализовать сам ExpressionBuilder и его редактор. Следите за руками.

HashItExpressionBuilder.cs

using System.CodeDom;

using System.Web.Compilation;

using System.Web.UI;

 

namespace Home.Andir.Examples

{

    [ExpressionEditor(typeof(HashItExpressionEditor))]

    public class HashItExpressionBuilder : ExpressionBuilder

    {

        public override CodeExpression GetCodeExpression(

            BoundPropertyEntry entry,

            object parsedData,

            ExpressionBuilderContext context)

        {

            return new CodePrimitiveExpression(

                HashItEvaluator.Eval(entry.Expression));

        }

    }

}

Обращаем внимание на атрибут установленный у класса.

HashItExpressionEditor.cs

using System;

using System.Web.UI.Design;

 

namespace Home.Andir.Examples

{

    public class HashItExpressionEditor : ExpressionEditor

    {

        public override object EvaluateExpression(

            string expression,

            object parseTimeData,

            Type propertyType,

            IServiceProvider serviceProvider)

        {

            return HashItEvaluator.Eval(expression);

        }

 

        public override ExpressionEditorSheet GetExpressionEditorSheet(

            string expression,

            IServiceProvider serviceProvider)

        {

            return new HashItExpressionEditorSheet(expression, serviceProvider);

        }

    }

}

У редактора надо реализовать две функции: EvaluateExpression - вычисляющий выражение и GetExpressionEditorSheet - возвращающий источник для редактора свойств (тот самый грид!).

HashItExpressionEditorSheet.cs

using System;

using System.ComponentModel;

using System.Web.UI.Design;

 

namespace Home.Andir.Examples

{

    public class HashItExpressionEditorSheet : ExpressionEditorSheet

    {

        public HashItExpressionEditorSheet(

            string expression,

            IServiceProvider serviceProvider

            ) : base(serviceProvider)

        {

            var parseResults = HashItEvaluator.ParseExpression(expression);

            if (parseResults != null)

            {

                HashAlg = parseResults.HashAlg;

                EncodeType = parseResults.EncodeType;

                Source = parseResults.Source;

            }

        }

 

        [DefaultValue(HashAlg.MD5), DisplayName("Hash algorithm")]

        public HashAlg HashAlg { get; set; }

        [DefaultValue(EncodeType.Hex), DisplayName("Result encoding")]

        public EncodeType EncodeType { get; set; }

        [DefaultValue(""), DisplayName("Some text")]

        public string Source { get; set; }

 

        public override bool IsValid

        {

            get { return true; }

        }

 

        public override string GetExpression()

        {

            var result = String.Format("{0}('{1}')", HashAlg.ToString(), Source);

 

            if (EncodeType == EncodeType.Base64)

                result += ": Base64";

 

            return result;

        }

    }

}

Итак, тут три свойства, которые и определяют параметры моего выражения.

Тестируем.

Примечание: Чтобы студия подгрузила новый зарегистрированный редактор для выражения, нужно скомпилировать проект и студию перезапустить.

Регистрируем новое выражение в web.config

<?xml version="1.0"?>

<configuration>

    <system.web>

        <compilation debug="true">

            <expressionBuilders>

                <add expressionPrefix="HashIt"

                     type="Home.Andir.Examples.HashItExpressionBuilder"

                     />

            </expressionBuilders>

        </compilation>

    </system.web>

</configuration>

Создаём тестовую страничку:

HashItExpression.aspx

<%@ Page Language="C#" %>

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>ASP.Net HashIt Expression Builder Test</title>

</head>

<body>

    <h1>ASP.Net HashIt Expression Builder Test</h1>

    <table class=borderall cellpadding="3" cellspacing="0">

        <col style="color: DarkGreen" align="left" />

        <tr>

            <th>

                <span>$HashItExpression</span>

            </th>

            <td>

                <asp:Label ID="hashItLabel" runat="server"

                           Text="<%$ HashIt:MD5('Строка'): Base64 %>" />

            </td>

        </tr>

    </table>

</body>

</html>

И открываем её в режиме Design:

Скриншот: Тестовая страница с выражением в Design-Time

Выбираем элемент управления hashItLabel и открываем диалог для биндинга выражений:

Скриншот: Диалог биндинга выражений к свойствам элемента управленияКак видно на скриншоте, появился тип выражения "HashIt" и в редакторе свойств появились все свойства этого выражения. Отлично!

Ссылки по теме

Файлы

  
Помощь
Задать вопрос
 программы
 обучение
 экзамены
 компьютеры
Бесплатный звонок
ICQ-консультанты
Skype-консультанты

Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 
Бестселлеры
Курсы обучения "Atlassian JIRA - система управления проектами и задачами на предприятии"
Microsoft Windows 10 Профессиональная 32-bit/64-bit. Все языки. Электронный ключ
Microsoft Office для Дома и Учебы 2019. Все языки. Электронный ключ
Курс "Oracle. Программирование на SQL и PL/SQL"
Курс "Основы TOGAF® 9"
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год. Электронный ключ
Курс "Нотация BPMN 2.0. Ее использование для моделирования бизнес-процессов и их регламентации"
 

О нас
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.

На протяжении многих лет интернет-магазин предлагает товары и услуги, ориентированные на бизнес-пользователей и специалистов по информационным технологиям.

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

В нашем магазине вы можете приобрести лицензионное ПО выбрав необходимое из широкого спектра и ассортимента по самым доступным ценам. Наши менеджеры любезно помогут определиться с выбором ПО, которое необходимо именно вам. Также мы проводим учебные курсы. Мы приглашаем к сотрудничеству учебные центры, организаторов семинаров и бизнес-тренингов, преподавателей. Сфера сотрудничества - продвижение бизнес-тренингов и курсов обучения по информационным технологиям.



 

О нас

 
Главная
Каталог
Новинки
Акции
Вакансии
 

Помощь

 
Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 

Способы оплаты

 

Проекты Interface Ltd.

 
Interface.ru   ITShop.ru   Interface.ru/training   Olap.ru   ITnews.ru  
 

119334, г. Москва, ул. Бардина, д. 4, корп. 3
+7 (495) 229-0436   shopadmin@itshop.ru
Проверить аттестат
© ООО "Interface Ltd."
Продаем программное обеспечение с 1990 года