Как отразить фотку в фотошопе. Как легко сделать зеркальное отражение изображения в фотошопе? Отражение картинки «зеркально»

This is the HttpHandler and HttpModule in real scenario article series. In this series we are learning various concepts and uses of HttpHandler and HttpModule. In our previous article we have covered various important concepts, you can read them here.

This is another example where we can measure the time gap between a request and its response. Sinice HttpModule is in the middle of a request and response, we can measure the time taken by a specific HTTP request.

In this example we will measure the time taken by one HTTP request to complete. Have a look at the following example.

using System;

using System.Drawing;

using System.IO;

using System.Linq;

using System.Text;

using System.Web;

using System.Xml.Linq;

using Newtonsoft.Json;

namespace WebApp

public void Dispose()

Context.BeginRequest += new EventHandler (OnBeginRequest);

Context.EndRequest += new EventHandler (OnEndRequest);

// Record the time of the begin request event.

public void OnBeginRequest(Object sender, EventArgs e)

HttpApp.Context.Items[ "beginTime" ] = DateTime .Now;

public void OnEndRequest(Object sender, EventArgs e)

HttpApplication httpApp = (HttpApplication )sender;

// Get the time of the begin request event.

DateTime beginTime = (DateTime )httpApp.Context.Items[ "beginTime" ];

// Evaluate the time between the begin and the end request events.

TimeSpan ts = DateTime .Now - beginTime;

// Write the time span out as a request header.

HttpApp.Context.Response.AppendHeader("TimeSpan" , ts.ToString());

// Get the current user"s Machine Name.

string user = WindowsIdentity .GetCurrent().Name;

// Display the information in the page.

StringBuilder sb = new StringBuilder ();

Sb.AppendLine("

RequestTimeInterval from HttpModule Output

" );

Sb.AppendFormat("Current user: {0}
" , user);

Sb.AppendFormat("Time span between begin-request and end-request events: {0}
"
,

Ts.ToString());

HttpApp.Context.Response.Output.WriteLine(sb.ToString());

The implementation is pretty simple. When a request is coming we are recording the time and when the request finishs we again measure the time and then calculate the time taken by that specific HTTP request to complete.

Add the following code to your web.config file to register the HttpModule.

< system.webServer >

< modules >

< add name = " mymodule1 " type = " WebApp.MyHttpModule1 " />

< system.webServer >

Here is the output of the receding implementation. We see that the HTTP request is taking nearly 2 miliseconds to finish. (Ha..Ha..Pretty fast execution).

Count number of requests by user by Form authentication

This is another real situation where we can implement HttpModule as a solution. Sometimes it’s very useful to count the number of login attemts from a specific user. There might be a business need or other motive behind that (we are not concerned with it).

So, if the requirement is something like. “We need to count the number of logins of a specific user, then we can implement the counting mechanism using HttpModule. I am not demanding that, this is the best and only one solution in this reqirement, but this is also a possible solution among others.

When we want to count the login attempts of a user then we need to count with respect to username and for that we will implement Form Authentication in the application.

Step 1: Create login form with a few controls

Here is the code of the login form. It’s very simple. We just must use two text boxes with one button.

<% @ Page Language ="C#" AutoEventWireup ="true" CodeBehind ="login.aspx.cs" Inherits ="WebApp.login" %>

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

< head runat ="server">

< title >

< body >

< form id ="form1" runat ="server">

< div >

UserName:- < asp : TextBox ID ="TextBox1" runat ="server">< br />

Password:- < asp : TextBox ID ="TextBox2" runat ="server">< br />

< asp : Button ID ="Login" runat ="server" Text ="Button" OnClick ="Login_Click" />

Step 2: Write the following code in code behind of login form

This is the normal form of Authentication code, nothing special in this. We are checking the username and password with a constant string, in reality it might check with some persistence storage. Once both the username and password is “abc” we are setting the form authentication cookies and then redirecting the user to the Home page.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Security;

using System.Web.Security;

namespace WebApp

public partial class login : System.Web.UI. Page

protected void Page_Load(object sender, EventArgs e)

protected void Login_Click(object sender, EventArgs e)

if (this .TextBox1.Text == "abc" && this .TextBox2.Text == "abc" ){

FormsAuthentication .SetAuthCookie(

this .TextBox1.Text.Trim(), true );

Response.Redirect("Home.aspx" );

Step 3: Configure Form Authentication in web.config file

This is necessary when we want to configure Form Authentication in an ASP.NET application.

< authentication mode = " Forms " >

< forms loginUrl = " login.aspx " >

Step 4: Implement HttpModule that will count user

Here is the core part of this example. We will implement one HttpModule that will count the user depending one URL.

Have a look at the following code. Here we will detect the user who will try to browse to the Home.aspx page.

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Drawing.Imaging;

using System.IO;

using System.Linq;

using System.Security.Principal;

using System.Text;

using System.Web;

using System.Xml.Linq;

using Newtonsoft.Json;

namespace WebApp

public class MyHttpModule1 : IHttpModule

public void Dispose()

throw new NotImplementedException ();

public void Init(HttpApplication context)

Context.AuthenticateRequest += new EventHandler (OnAuthentication);

void OnAuthentication(object sender, EventArgs a)

HttpApplication application = (HttpApplication )sender;

HttpContext context = application.Context;

if (context.Request.Url.AbsolutePath.Contains("Home" ))

String user = context.User.Identity.Name;

We are checking the URL, If the URL pattern contains the keyword Home then will check the username as it’s showing in the following example.

And when we are getting the username it’s very simple to implement a counting mechanism depending on username. I have skipped this part to make the example simple. With a little effort, you can implement the rest.

Conclusion

In this article we have learned two important concepts for implementing HttpModule as a solution. I hope you have understood the real example of HttpModule in this article.

Запустите Visual Studio 2012 и выберите пункт New Project (Создать проект) в меню File (Файл). Откроется диалоговое окно New Project (Новый проект), которое позволяет создавать новые проекты Visual Studio.

В левой панели этого диалогового окна вы увидите список доступных типов проектов. Перейдите к элементу Installed --- Templates --- Visual C# --- Web (Установленные --- Шаблоны --- Visual C# --- Веб) и в центральной панели отобразится набор проектов ASP.NET, как показано на рисунке ниже:

Удостоверьтесь, что выбрали Visual C#, а не Visual Basic. Попытка выполнить приведенные примеры на C# в проекте Visual Basic приведет к весьма странному поведению и множеству ошибок.

Выберите в центральной панели элемент ASP.NET Empty Web Application (Пустое веб-приложение ASP.NET) - имена некоторых проектов, несмотря на их отличия, выглядят похожими, поэтому внимательно выбирайте нужный тип проекта. Удостоверьтесь, что в раскрывающемся списке в верхней части экрана выбран вариант.Net Framework 4.5 и введите в поле Name (Имя) строку TestAspNet45 в качестве имени проекта. Щелкните на кнопке OK для создания нового проекта.

Среда Visual Studio устанавливает в поле Solution name (Имя решения) строку TestAspNet45 для соответствия имени проекта. Решение Visual Studio - это контейнер для одного или большего числа проектов.

Шаблон ASP.NET Empty Web Application - простейший из всех шаблонов проектов. Он создает проект, содержащий лишь файл Web.config, в котором находится конфигурационная информация для приложения ASP.NET. Среда Visual Studio отображает файлы в окне Solution Explorer (Проводник решения), показанном на рисунке ниже. Окно Solution Explorer является основным инструментом для навигации внутри проекта.

Добавление новой веб-формы

Как вы уже видели при создании проекта Visual Studio, существуют разнообразные типы приложений ASP.NET. Для выбранного типа приложения, контент генерируется из веб-формы (Web Form).

Чтобы добавить в проект новую веб-форму, щелкните правой кнопкой мыши на записи проекта TestAspNet45 в окне Solution Explorer и выберите в контекстном меню пункт Add --- Web Form (Добавить --- Веб-форма). В появившемся диалоговом окне введите Default в качестве имени нового элемента проекта:

Щелкните на кнопке OK для закрытия диалогового окна и создания нового элемента. Вы заметите в окне Solution Explorer, что среда Visual Studio добавила в проект файл Default.aspx и открыла его для редактирования. Первоначальное содержимое этого файла приведено в коде ниже:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestAspNet45.Default" %>

Файл веб-формы в сущности представляет собой расширенный HTML-файл. Наличие элемента, имеющего дескрипторы <% и %>, говорит о том, что это не обычный файл HTML. То же самое касается атрибутов runat в элементах head и form.

Как показано ниже, в файл Default.aspx было добавлено несколько стандартных HTML-элементов:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestAspNet45.Default" %>

Привет!

Это новая веб-форма!

В файл Default.aspx были добавлены элементы h1 и p, содержащие простой текст. Они не содержат ничего, связанного с ASP.NET - это стандартные HTML-элементы.

Тестирование примера приложения

Панель инструментов Visual Studio содержит раскрывающийся список с названиями браузеров, которые установлены на рабочей станции (чтобы увидеть этот список, щелкните на небольшой стрелке вниз, расположенной справа от названия браузера).

Пример списка показан на рисунке ниже, где можно видеть несколько браузеров, установленных в системе. Как минимум, в списке будут присутствовать элементы Internet Explorer и Page Inspector (инструмент, который помогает отлаживать HTML-код).

Я обычно использую браузер Google Chrome. Встречаются случаи использования других браузеров для демонстрации определенных возможностей, но это всегда будет выделено особо.

Удостоверьтесь, что в списке выбран нужный браузер и затем щелкните на соответствующей кнопке в панели инструментов или выберите пункт Start Debugging (Начать отладку) в меню Debug (Отладка) среды Visual Studio. Проект будет скомпилирован и откроется новое окно браузера, отображающее веб-форму, как показано на рисунке ниже. На данный момент контент веб-формы довольно скуден, но мы, по крайней мере, знаем, что все работает должным образом.

Для этого примера Google Chrome использует следующий URL:

http://localhost:40035/Default.aspx

Запустив приложение, вы увидите похожий, но не идентичный URL. Будет присутствовать часть http://, указывающая на применение протокола HTTP, и часть localhost, которая представляет собой специальное имя, ссылающееся на рабочую станцию. Часть URL, касающаяся порта, 40035 в данном случае, назначается произвольно, поэтому вы, скорее всего, увидите другой номер порта. Последняя часть URL, Default.aspx, указывает на необходимость использования содержимого из файла Default.aspx, которое и можно видеть в окне браузера.

Так к чему же относится этот URL? В состав Visual Studio 2012 входит инструмент IIS Express, который представляет собой усеченную версию сервера приложений Microsoft, предназначенную для запуска разрабатываемых приложений ASP.NET. Сервер IIS Express устанавливается автоматически; когда он запущен, в области уведомлений отображается значок. Щелкнув правой кнопкой мыши на этом значке, можно просмотреть список приложений ASP.NET, которые были запущены, и открыть окно браузера для их отображения:

Когда приложение запускается из Visual Studio, сервер IIS Express стартует и начинает прослушивать входящие запросы (на порте 40035 или любом другом). Как только сервер IIS Express запустился, Visual Studio создает новое окно Internet Explorer и применяет его для перехода на URL, который приводит к загрузке файла Default.aspx из IIS Express.

Чтобы просмотреть HTML-код, который сервер IIS Express и платформа ASP.NET Framework (интегрированная в IIS) отправляют браузеру, необходимо щелкнуть правой кнопкой мыши в окне браузера и выбрать в контекстном меню пункт View Source (Просмотр HTML-кода). Этот HTML-код показан ниже, легко заметить, что он отличается от содержимого файла Default.aspx:

Привет!

Это новая веб-форма!

Отправленный браузеру HTML-код является результатом обработки файла Default.aspx платформой ASP.NET Framework. Удалены дескрипторы <% и %> и добавлен скрытый элемент input, но поскольку данный файл Default.aspx не делает ничего особо интересного, его содержимое передается браузеру в основном без изменений.

Итак, вы создали очень простое веб-приложение ASP.NET. Сейчас следует запомнить следующие ключевые моменты:

    Пользователь запрашивает URL, которые указывают на файлы веб-форм, добавленные к проекту.

    Запросы получает сервер IIS Express, который находит запрашиваемые файлы.

    Сервер IIS Express обрабатывает файл веб-формы с целью генерации страницы стандартного HTML-кода.

    Код HTML возвращается браузеру, который отображает его для пользователя.

Это сущность любого приложения ASP.NET. Наша цель - воспользоваться тем способом, которым ASP.NET Framework обрабатывает файлы веб-форм, для создания более сложного HTML-кода и последовательностей взаимодействий с пользователем. В последующих разделах мы будем опираться на данный фундамент.

Создание простого приложения

В оставшейся части статьи мы исследуем некоторые из базовых средств ASP.NET, используемых для создания простого приложения ввода данных. В этом разделе мы нарастим темпы - цель заключается в том, чтобы продемонстрировать ASP.NET в действии поэтому мы опустим детальные пояснения того, как все это работает "за кулисами".

Предварительная настройка

Предположим, что ваша подруга решила организовать новогоднюю вечеринку. Она попросила вас создать веб-сайт, который дал бы возможность приглашенным отправлять ответы на приглашение (repondez s"il vous plait - RSVP) по электронной почте. Она высказала пожелание о наличии следующих основных средств:

    страница, которая отображает информацию о вечеринке и форму RSVP;

    проверка достоверности для формы RSVP, которая будет отображать страницу подтверждения;

    страница, на которой выводится список ответов от приглашенных.

В следующих нескольких разделах мы достроим проект ASP.NET по имени TestAspNet45, созданный в начале статьи, добавив указанные средства.

Создание модели данных и хранилища

Почти все веб-приложения полагаются на какую-нибудь разновидность модели данных, независимо от технологии, используемой для их создания. Поскольку мы строим простое приложение, нам нужна лишь простая модель данных. Щелкните правой кнопкой мыши на элементе TestAspNet45 в окне Solution Explorer и выберите в контекстном меню пункт Add --> Class (Добавить --- Класс).

Если пункт меню Class отсутствует или не доступен, это может означать, что вы оставили отладчик Visual Studio в функционирующем состоянии. Среда Visual Studio ограничивает изменения, которые можно вносить в проект, пока выполняется приложение. Выберите пункт Stop Debugging (Остановить отладку) в меню Debug (Отладка) и попробуйте заново.

Откроется диалоговое окно Add New Item (Добавление нового элемента), содержащее шаблоны для всех элементов, которые можно добавлять к проекту ASP.NET. Шаблон Class (Класс) будет уже выбран, так что укажите в качестве имени GuestResponse.cs и щелкните на кнопке Add (Добавить). Среда Visual Studio создаст новый файл класса C# и откроет его для редактирования. Приведите содержимое этого файла в соответствие с кодом:

Namespace TestAspNet45 { public class GuestResponse { public string Name { get; set; } public string Email { get; set; } public string Phone { get; set; } public bool? WillAttend { get; set; } } }

В классе Guest Response применяется средство языка C# под названием автоматически реализуемые свойства, с которым вы можете быть не знакомы, если имели дело с более старыми версиями.NET Framework.

Обратите внимание, что свойство WillAttend определено с типом bool, допускающим null. Это означает, что свойство может принимать значения true, false или null. Причины выбора этого типа данных объясняются в разделе "Выполнение проверки достоверности" далее в статье.

Для представления ответов от гостей вечеринки будут применяться экземпляры класса GuestResponse. Созданные объекты GuestResponse должны записываться в хранилище. В реальном приложении в его качестве обычно выступает база данных, нам же требуется нечто быстрое и простое, поэтому мы собираемся хранить объекты в памяти. Преимущество такого подхода связано с простотой реализации, однако следует учитывать, что данные будут теряться при каждом останове или перезапуске приложения. Это было бы довольно странным выбором для реального веб-приложения, но вполне подходит для целей настоящей статьи.

Чтобы определить хранилище, добавьте в проект новый файл класса по имени ResponseRepository.cs и поместите в него код, показанный ниже:

Using System.Collections.Generic; namespace TestAspNet45 { public class ResponseRepository { private static ResponseRepository repository = new ResponseRepository(); private List responses = new List(); public static ResponseRepository GetRepository() { return repository; } public IEnumerable GetAllResponses() { return responses; } public void AddResponse(GuestResponse response) { responses.Add(response); } } }

Хранилище обычно располагает методами для создания, чтения, обновления и удаления объектов данных (вместе называемых методами CRUD (creating, reading, updating, deleting - создание, чтение, обновление, удаление) , но в этом приложении нужна только возможность чтения всех объектов данных и добавления новых объектов данных.

Создание и стилизация формы

Следующий шаг заключается в создании страницы, которая содержит информацию о вечеринке и HTML-форму, позволяющую гостям подготовить ответ. Мы будем использовать файл Default.aspx, который был создан ранее. Внесенные в него изменения представлены в коде ниже:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestAspNet45.Default" %>

Новый год у Татьяны!

Здесь было изменено значение атрибута id элемента form и добавлены стандартные HTML-элементы, предназначенные для отображения информации о вечеринке, а также для сбора деталей формы RSVP от пользователей. Запустив приложение (либо выбором пункта меню Start Debugging из меню Debug, либо щелчком на кнопке браузера в панели инструментов), можно посмотреть, как выглядят указанные изменения.

Элементы веб-формы стилизуются точно так же, как элементы обычной HTML-страницы - с применением каскадных таблиц стилей (Cascading Style Sheets - CSS). Для добавления к приложению нескольких базовых стилей щелкните правой кнопкой мыши на элементе TestAspNet45 в окне Solution Explorer и выберите в контекстном меню пункт Add --> StyleSheet (Добавить --> Таблица стилей). В появившемся диалоговом окне в качестве имени укажите Styles и щелкните на кнопке OK. Среда Visual Studio добавит к проекту новый файл Styles.css. Приведите содержимое этого файла в соответствие с примером ниже. Несмотря на простоту этих стилей CSS, они существенно улучшат внешний вид полей формы.

#rsvpform label { width: 120px; display: inline-block; } #rsvpform input { margin: 2px; margin-left: 4px; width: 150px; } #rsvpform select { margin: 2px 0; width: 154px; } button { margin-top: 15px; padding: 5px; }

Таблица стилей CSS ассоциируется с веб-формой с помощью элемента link. В коде ниже показано, как добавить такой элемент в раздел head файла Default.aspx:

... ...

И снова обратите внимание, что для ссылки на файл, содержащий базовые стили CSS, используется стандартный HTML-элемент. (Мы не хотим акцентировать на этом внимание, но один из замечательных аспектов работы с платформой ASP.NET состоит в том, что она построена на основе существующих знаний веб-стандартов.) Запустив приложение, можно увидеть эффект от применения CSS:

Обработка данных формы

У нас есть HTML-форма, которую можно отобразить приглашенным на вечеринку, однако при щелчке пользователями на кнопке "Отправить приглашение RSVP" постоянно отображается одна и та же страница. Чтобы исправить это, понадобится написать код, который будет обрабатывать данные формы, когда они отправляются серверу.

В начале файла Default.aspx находится следующий элемент:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestAspNet45.Default" %> ...

Это называется страничной директивой (или директивой Page). Определенные в ней атрибуты предоставляют ASP.NET детали о файле веб-формы. Нас интересует атрибут CodeBehind. Данный атрибут сообщает ASP.NET, какой файл класса C# содержит код, ассоциированный с веб-формой. В приведенном примере это файл Default.aspx.cs, который является файлом отделенного кода для Default.aspx.

Среда Visual Studio группирует вместе связанные файлы в виде одиночного элемента в окне Solution Explorer, что упрощает навигацию по крупным проектам. Если щелкнуть на стрелке слева от записи Default.aspx, можно увидеть файлы, сокрытые средой Visual Studio. Одним из них является файл Default.aspx.cs, на который производится ссылка с помощью атрибута CodeBehind.

Дважды щелкните на файле Default.aspx.cs, чтобы открыть его в редакторе; отобразится код, приведенный ниже:

Using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace TestAspNet45 { public partial class Default: System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } } }

Базовым для класса отделенного кода является класс System.Web.UI.Page , который содержит несколько полезных методов и свойств для ответа на веб-запросы. Пока что в классе отделенного кода нас интересует метод Page_Load() , вызываемый ASP.NET Framework при поступлении запросов для Default.aspx и предоставляющий возможность отреагировать на такие запросы.

В рассматриваемом примере метод Page_Load() будет вызван один раз во время первоначальной загрузки страницы и еще раз - когда пользователь отправит форму. В примере ниже показан код, добавленный к методу Page_Load() для реагирования на запросы:

Using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.ModelBinding; namespace TestAspNet45 { public partial class Default: System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { GuestResponse rsvp = new GuestResponse(); if (TryUpdateModel(rsvp, new FormValueProvider(ModelBindingExecutionContext))) { ResponseRepository.GetRepository().AddResponse(rsvp); if (rsvp.WillAttend.HasValue && rsvp.WillAttend.Value) { Response.Redirect("seeyouthere.html"); } else { Response.Redirect("sorryyoucantcome.html"); } } } } } }

Здесь за счет проверки свойства IsPostBack выясняется, относится ли запрос, на который производится ответ, к форме, отправленной обратно серверу. Если это так, мы создаем новый экземпляр объекта GuestResponse модели данных и передаем его методу TryUpdateModel() , унаследованному от базового класса Page.

Метод TryUpdateModel() выполняет процесс, который называется привязкой модели и предполагает использование значений данных из запроса браузера для заполнения свойств соответствующего объекта модели данных. Еще одним аргументом метода TryUpdateModel() является объект, который платформа ASP.NET должна применять для получения необходимых значений - мы используем класс System.Web.ModelBindlng.FormValueProvider , который предоставляет значения из данных формы. В результате вызова метода TryUpdateModel() свойства объекта GuestResponse обновляются, чтобы отразить значения данных, которые пользователь отправил внутри формы. Затем объект GuestResponse помещается в хранилище.

Пользователю необходимо предоставить какой-либо отклик после того, как он отправил форму, и это делается с помощью метода Response.Redirect (), который выполняет перенаправление пользовательского браузера. Если свойство WillAttend равно true, пользователь придет на вечеринку, поэтому он перенаправляется на файл seeyouthere.html. В противном случае перенаправление происходит на файл sorryyoucantcome.html.

Создание HTML-файлов ответов

Не все страницы в приложении ASP.NET должны генерироваться из файлов веб-форм. Можно также включать обычные, статические HTML-файлы. Чтобы создать первый файл ответа, щелкните правой кнопкой мыши на элементе TestAspNet45 в окне Solution Explorer и выберите в контекстном меню пункт Add --> New Item (Добавить --> Новый элемент). В открывшемся диалоговом окне Add New Item укажите шаблон HTML Page (HTML-страница) и назначьте странице имя seeyouthere.html. Наконец, щелкните на кнопке Add (Добавить) для создания HTML-файла. Приведите содержимое нового файла в соответствие с примером ниже:

Увидимся на вечеринке!

Увидимся на вечеринке! ;)

Приходите в 9 вечера. Маски являются обязательными!

Повторите описанный процесс для создания файла sorryyoucantcome.html с содержимым, которое показано в примере ниже:

Жаль что вы не сможете прийти!

Жаль что вы не сможете прийти:(

Увидимся в следующем году!

Установка области действия HTML-элементов

Базовая структура приложения в основном построена, однако оно еще не полностью работоспособно. Мы должны сообщить Visual Studio, какой файл необходимо загружать при запуске приложения. Ранее это не имело значения, т.к. существовал только один файл Default.aspx, а среда Visual Studio достаточно интеллектуальна, чтобы определить его в качестве стартового. Но теперь есть еще и пара HTML-файлов, поэтому нужно предоставить Visual Studio некоторую помощь. Щелкните правой кнопкой мыши на элементе Default.aspx в окне Solution Explorer и выберите в контекстном меню пункт Set as Start Page (Установить как стартовую страницу).

Теперь можно запустить приложение, либо выбрав пункт Start Debugging в меню Debug, либо щелкнув на кнопке Google Chrome в панели инструментов. Заполните поля формы и удостоверьтесь, что в элементе select выбран вариант "Да". После отправки формы вы увидите ответ, который должен отображаться в случае выбора варианта "Нет", как показано на рисунке ниже. Очевидно, что-то не в порядке.

Причина этой проблемы в том, что при обработке файлов веб-форм платформа ASP.NET ищет только элементы, которые имеют атрибут runat со значением server. Все остальные элементы игнорируются, и поскольку элементы input и select в файле Default.aspx не имеют указанной комбинации атрибута и значения, процесс привязки модели не имеет возможности найти значения, отправленные внутри HTML-формы. В примере ниже показано, как скорректировать проблему:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestAspNet45.Default" %>

Новый год у Татьяны!

Мы устроим классную вечеринку и вы приглашены!

runat="server" />
runat="server" />
runat="server" />

Для атрибута runat предусмотрено только значение server. Если опустить атрибут runat или указать значение, отличное от server, то такие HTML-элементы станут невидимыми для ASP.NET. Пропуск атрибутов runat - это первое, что следует проверить в ситуации, когда веб-формы ведут себя не так, как ожидалось.

Снова запустите приложение и заполните форму. На этот раз отправка формы приводит к выдаче корректного ответа:

Создание итогового представления

Итак, базовые строительные блоки приложения на месте, и приглашенные могут отправлять формы RSVP. В этом разделе мы добавим поддержку для отображения итоговых сведений по полученным ответам, чтобы можно было видеть, кто намерен прибыть, и должным образом планировать вечеринку.

Щелкните правой кнопкой мыши на элементе TestAspNet45 в окне Solution Explorer и выберите в контекстном меню пункт Add --> Web Form. В открывшемся диалоговом окне укажите Summary для имени веб-формы и щелкните на кнопке OK, чтобы создать новый файл Summary.aspx. Приведите содержимое файла в соответствие с примером:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Summary.aspx.cs" Inherits="TestAspNet45.Summary" %> <%@ Import Namespace="TestAspNet45" %>

Приглашения

<% var yesData = ResponseRepository.GetRepository().GetAllResponses() .Where(r => r.WillAttend.Value); foreach (var rsvp in yesData) { string htmlString = String.Format("", rsvp.Name, rsvp.Email, rsvp.Phone); Response.Write(htmlString); } %>
Имя Email Телефон
{0}{1}{2}

Поскольку это первое создаваемое приложение ASP.NET, мы хотим продемонстрировать в этой статье максимально возможное количество приемов. Именно поэтому содержимое файла Summary.aspx существенно отличается от содержимого файла Default.aspx.

Вскоре мы подробно опишем различные разделы этого файла, но первое, что должно быть заметно - отсутствие элемента form в файле Summary.aspx. Название "веб-форма" несколько вводит в заблуждение, и хотя обычные формы удобны в большинстве приложений, файл веб-формы - это просто расширенный HTML-файл, который обрабатывается ASP.NET. В файле Default.aspx такие расширения имеют вид файла отделенного кода, поэтому его можно использовать для работы с отправками формы. В файле Summary.aspx дополнительно применяются дескрипторы <% и %> для добавления динамического контента к генерируемому HTML-коду, когда браузер запрашивает данный файл.

Дескрипторы <% и %> формально называются ограничителями сценариев серверной стороны, хотя более распространено название фрагменты кода . Доступны различные виды фрагментов кода и в примере были добавлены два типа таких фрагментов. Вот первый из них:

<%@ Import Namespace="TestAspNet45" %>

Фрагмент кода с открывающим дескриптором <%@ представляет собой директиву. Директивы позволяют выполнять действие, оказывающее влияние на веб-форму целиком. В данном случае была создана директива Import, которая помещает в область видимости пространство имен из проекта, что дает возможность ссылаться на классы, указывая только их имена.

Почему мы заботимся о пространствах имен? Поскольку второй фрагмент кода в примере выше является блоком кода C#, который будет выполнен при запросе страницы, ссылка на классы без снабжения их пространствами имен упрощает код. Открывающий дескриптор для блока кода выглядит просто как <% и не включает каких-либо дополнительных символов. (Закрывающий дескриптор для всех разновидностей фрагментов кода - всегда %>.)

Внутри блока кода используются обычные операторы C# для генерации набора HTML-элементов, представляющих собой строки в элементе table; в этих строках перечислены люди, принявшие приглашение на вечеринку. Для получения всех объектов данных из хранилища вызывается метод ResponseRepository.GetRepository().GetAllResponses(), а для выборки всех подтверждающих участие ответов применяется LINQ-метод Where(). Затем в цикле foreach генерируются HTML-строки для каждого объекта данных:

string htmlString = String.Format("{0}{1}{2}", rsvp.Name, rsvp.Email, rsvp.Phone);

Метод String.Format() позволяет компоновать HTML-строки, содержащие значения свойств из каждого объекта GuestResponse, который необходимо отобразить. Для добавления HTML-кода в вывод, отправляемый браузеру, используется метод Response.Write().

Форматирование динамического HTML-кода

Вы заметите, что в файл Summary.aspx включен элемент link, который импортирует файл Styles.css с содержащимися внутри него стилями. Это сделано для демонстрации того, что элемент, генерируемый в блоке кода, стилизуется точно так же, как статический HTML-элемент на странице. В примере ниже показан стиль, добавленный в файл Styles.css для применения внутри Summary.aspx.

Table, td, th { border: thin solid black; border-collapse: collapse; padding: 5px; background-color: lemonchiffon; text-align: left; margin: 10px 0; }

Тестирование динамического кода

Чтобы протестировать файл Summary.aspx, запустите приложение и воспользуйтесь страницей Default.aspx для добавления данных в хранилище - помните, что в этом примере данные не хранятся постоянно, а их нужно вводить заново при каждом запуске приложения. После нескольких отправок формы перейдите на URL вида "/Summary.aspx"; появится вывод, который похож на показанный на рисунке:

Вызов метода из отделенного кода

Хотя и можно включать блоки кода C# в файл веб-формы, обычно делать это не имеет смысла, т.к. файл становится трудным в чтении и сопровождении. Намного более ясный и распространенный подход предусматривает определение методов в файле отделенного кода, а затем использование фрагментов кода для вызова этих методов и вставки результатов в HTML-код, отправляемый браузеру.

В примере ниже показано, как определить новый метод по имени GetNoShowHtml() в файле отделенного кода Summary.aspx.cs. Этот метод генерирует таблицу строк, аналогичную той, что создавалась в предыдущем разделе:

Using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Text; namespace TestAspNet45 { public partial class Summary: System.Web.UI.Page { protected string GetNoShowHtml() { StringBuilder html = new StringBuilder(); var noData = ResponseRepository.GetRepository() .GetAllResponses().Where(r => !r.WillAttend.Value); foreach (var rsvp in noData) { html.Append(String.Format("{0}{1}{2}", rsvp.Name, rsvp.Email, rsvp.Phone)); } return html.ToString(); } } }

После этого новый метод можно вызывать внутри фрагмента кода в файле Summary.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Summary.aspx.cs" Inherits="TestAspNet45.Summary" %> <%@ Import Namespace="TestAspNet45" %>

Приглашения

Люди которые были приглашены:

Люди которые не придут:

<%= GetNoShowHtml()%>
Имя Email Телефон

В этом примере применяется фрагмент кода с открывающим дескриптором <%=. Это сообщает ASP.NET о необходимости вставки результата выполнения метода в вывод, отправляемый браузеру, что представляет собой более аккуратный и читабельный подход, чем включение кода непосредственно в страницу. Генерируется такой же HTML-код, что и с помощью предыдущего фрагмента кода, но только в данном случае получается таблица строк для людей, которые отклонили приглашение на вечеринку:

Выполнение проверки достоверности

Приложение почти завершено, однако осталась еще одна нерешенная проблема: пользователи могут отправлять внутри формы Default.aspx произвольные данные или вообще отправлять пустую форму. Необходимо обеспечить наличие значений во всех полях формы, чтобы данные были корректными и отражали точно, кто принял приглашение на вечеринку, а кто от него отказался.

Платформа ASP.NET предоставляет целый набор разнообразных приемов проверки достоверности, но мы отдаем предпочтение подходу, при котором к классу модели данных применяются атрибуты, задающие требования проверки. В примере ниже показано, как реализовать базовую проверку достоверности в классе GuestResponse:

Using System.ComponentModel.DataAnnotations; namespace TestAspNet45 { public class GuestResponse { public string Name { get; set; } public string Email { get; set; } public string Phone { get; set; } public bool? WillAttend { get; set; } } }

Атрибут Required , определенный в пространстве имен System.ComponentModel.DataAnnotations, сообщает ASP.NET, что для свойства, к которому он применен, наличие значения является обязательным. Так как указанный атрибут применен ко всем свойствам в классе GuestResponse, ASP.NET известно, что все свойства класса модели данных являются обязательными. Это довольно простая форма проверки достоверности, поскольку мы не проверяем, полезно ли значение, а только сам факт его предоставления пользователем; тем не менее, такой подход вполне адекватен для рассматриваемого примера.

Когда пользователь отправляет форму в файле Default.aspx, платформа ASP.NET Framework вызывает метод Page_Load() из файла отделенного кода Default.aspx.cs. Ранее в этой статье было показано, как вызывать метод TryUpdateModel() для выполнения привязки модели. После добавления атрибута Required этот метод будет проверять, получены ли значения для всех свойств.

В файл Default.aspx понадобится внести дополнение для отображения пользователям сообщений, когда возникают проблемы с проверкой достоверности данных формы, которая была отправлена. Это дополнение показано в примере ниже:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestAspNet45.Default" %>

Новый год у Татьяны!

Мы устроим классную вечеринку и вы приглашены!

Здесь был добавлен элемент управления ASP.NET Web Forms. Такой элемент управления генерирует HTML-код внутри страницы - доступны различные виды элементов управления, которые предоставляют удобный способ инкапсуляции функциональности, делающий возможным их повторное использование в рамках приложения. Можно создавать собственные элементы управления либо применять предлагаемые Microsoft. В рассматриваемом примере был добавлен элемент управления ValidationSummary, разработанный в Microsoft, который отображает сообщения об ошибках проверки достоверности.

Для подсветки ошибок красным цветом добавьте следующий стиль в файл Styles.css:

... #validationSummary { color: red; }

Этот элемент управления генерирует порцию HTML-кода, которая выводит список проблем проверки, найденных в данных формы. Чтобы увидеть, как он работает, запустите приложение и щелкните на кнопке "Отправить приглашение RSVP", не вводя никаких данных. Результат показан на рисунке ниже:

При определении свойства WillAttend в классе GuestResponse применялся тип bool, допускающий null, который может принимать значения true и false, но также может быть null. Эта возможность используется для определения, выбрал ли пользователь значение в элементе select по имени WillAttend:

... ...

Существует удобное взаимодействие между процессом привязки модели и атрибутом проверки достоверности Required, которым можно воспользоваться. Процесс привязки модели преобразует значение пустой строки первого элемента option в null, но атрибут Required сгенерирует ошибку проверки достоверности, если не будет получено значение true или false. Такое несоответствие позволяет автоматически генерировать ошибку, если пользователь не выбрал значения "Да" или "Нет" в раскрывающемся списке.

Единственная проблема этого подхода в том, что сообщение проверки достоверности бессмысленно для пользователя, который ничего не знает о том, что элемент select, помеченный как "Вы придете?", соответствует свойству модели данных по имени WillAttend. Чтобы решить эту проблему, необходимо предоставить атрибут Required с другим сообщением для отображения, как показано в примере ниже:

Using System.ComponentModel.DataAnnotations; namespace TestAspNet45 { public class GuestResponse { public string Name { get; set; } public string Email { get; set; } public string Phone { get; set; } public bool? WillAttend { get; set; } } }

В свойстве ErrorMessage было указано более полезное сообщение, которое отобразится в браузере, если запустить приложение и снова отправить форму, не вводя никаких данных:

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

С помощью зеркалирования фотографий можно изменить восприятие кадра и сделать его более выразительным. Считается, что люди, смотрящие на снимке вправо, воспринимаются более позитивно, чем люди, смотрящие влево. Влево - как бы назад, в прошлое. В пейзаже и городской съёмке примерно такая же ситуация: мосты, реки, улицы, уходящие вправо - это движение в будущее.

Но, кроме изменения восприятия снимка, с помощью зеркалирования и копирования можно добиться некоторых интересных эффектов.

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

Открываем изображение в Adobe Photoshop. Наша фотография будет открыта в виде слоя Background. И, по умолчанию, к такому слою нельзя применять никакие изменения. Это сделано специально, чтобы при работе у вас всегда оставался исходный кадр. Для того, чтобы базовый слой стало возможным изменять, надо дважды кликнуть на пиктограмму замочка справа на панели слоёв. Это позволит разблокировать слой. Ещё один вариант - просто скопировать слой и применять все изменения к копии.

Для того, чтобы зеркально отразить слой в Фотошопе, есть две команды. Они находятся в меню Edit/«Редактирование» → Transform/«Трансформирование» .

Flip Horizontal/«Отразить по горизонтали» - позволяет отразить фотографию по горизонтали.

Делает зеркалирование по вертикали.

Давайте разберём ещё один пример, который показывает, как зеркально отразить слой в Фотошопе и добиться эффекта калейдоскопа.

Сначала создадим копию исходного слоя. Для этого можно либо выбрать пункт меню Layer/«Слои» → Duplicate Layer…/«Создать дубликат слоя…» , либо мышкой перетащить пиктограмму слоя на пиктограмму создания нового слоя на панели слоёв.

Теперь давайте увеличим размер холста, чтобы все части будущего «калейдоскопа» были видны.

Нам понадобится пункт меню Image/«Изображение» → Canvas Size/«Размер холста» .

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

В качестве якорной точки Anchor/«Расположение» мы задали левый край изображения - он останется на месте. И указали, что ширина холста должна увеличиться на 200% относительно исходной ширины. Высоту пока оставим без изменений.

После нажатия на кнопку Ok и применения всех сделанных изменений окно Photoshop будет выглядеть как на снимке ниже.

Убеждаемся, что верхний слой активный, и зеркалируем его относительно вертикальной оси с помощью команды Edit/«Редактирование» → Transform/«Трансформирование» → Flip Horizontal/«Отразить по горизонтали» . После чего мышкой меняем расположение двух слоёв таким образом, чтобы они совмещались по одному из краёв.

Для точного и аккуратного позиционирования удобно воспользоваться клавишами «Вверх», «Вниз», «Вправо» и «Влево» на клавиатуре.

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

Объединим два текущих слоя в один. Это можно сделать командой *Layer/«Слои» → Merge Visible/«Объединить видимые» . Увеличим размер холста аналогично тому, как делали раньше, но на этот раз по вертикали. Якорная точка будет у нижней границы, а увеличивать на 200% мы будем высоту.

Получится вот так.

Создадим копию верхнего слоя (который уже включает в себя исходное и отзеркалированное изображения). И применим к этой копии команду отражения Flip Vertical/«Отразить по вертикали» . После этого мышкой поместим зеркалированный слой на новое место.

Вот такой эффект калейдоскопа можно получить с помощью зеркалирования картинок в Фотошопе.

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

Подобных сервисов в интернете большое количество, ниже рассмотрим подробнее самые популярные:

IMGOnline

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

ReflectionMaker

Онлайн-сервис с звучным названием ReflectionMaker, которое говорит само за себя. Ресурс специализируется на создании зеркального отражения в онлайн режиме и не имеет больше никаких дополнительных функций. ReflectionMaker полностью на английском языке, но это никак не усложняет работу с ним. Количество функций на сайте минимальное, поэтому разобраться с ними не составит труда.

Примечание! Можно производить отражение на фотографии строго по вертикале, подобно отражению в воде. Если данный способ вас не устраивает, рекомендуем перейти к следующему варианту.

Порядок действий для создание зеркального отражения картинки:


MirrorEffect

Идеологически данный сервис похож на предыдущий. Его возможности ограничиваются только отзеркаливанием изображений. MirrorEffect полностью на английском языке, но малое количество функций и удобный интерфейс помогут быстро в нём разобраться. Отличие от предыдущего сервиса в том, что присутствует возможность выбора стороны отражения.

Для того, чтобы повернуть фотографию зеркально онлайн потребуется выполнить следующие действия:


Croper

Онлайн фоторедактор без каких-либо излишеств с минималистичным интерфейсом. Преимуществом Croper является загрузка фото для отзеркаливания онлайн с разных источников.

Как обработать фотографию:

Inettools

Сайт схож с предыдущим сервисов. Выполнен без каких-либо излишеств, всё максимально просто и понятно.
Чтобы зеркально отобразить фото онлайн в Inettools нужно:


Как отзеркалить изображение в Paint

В эру доступности интернета случаются и такие моменты, когда возможности использовать онлайн-сервисы нет. Если вы попали как раз в такую ситуацию, а сделать отзеркаливание нужно срочно, на помощь придёт стандартная утилита Windows, графический редактор Paint. Большая часть пользователей ПК знакома с данным редактором, но не все знают про его возможности.

Paint – это простой графический редактор, который является лицензионной составляющей версии операционной системы Windows. Не смотря на то, что в современном мире существует много других более функциональных программ и утилит, Paint остается прекрасным решением для стандартных операций. Любой пользователь может легко и быстро разобраться в его функциях. В данной статье будут рассмотрены три операции, которые можно произвести с фотофайлом или картинкой в Paint.

Как уменьшить обрезать и отзеркалить изображение в Paint?

Microsoft Paint считается редактором, который позволяет справиться с задачами минимальной и средней сложности. Часто пользователи сталкиваются с такой проблемой, как уменьшение размера изображения. Особенно это важно, если в дальнейшем файл необходимо отправить на устройство, которое не может открыть фотографию или картинку с высоким разрешением. Другой вариант подобной ситуации – желание уменьшить объем файла. Например, фотография занимает на носителе 5 Мбайт, а вам необходимо ее снизить до 3 Мбайт.

Итак, как уменьшить изображение в Paint?

  • Действие №1: откройте свой редактор и запустите на нем картинку или фотографию, которую необходимо уменьшить. Сделать это можно двумя способами – либо через меню «Файл» и вкладку «Открыть» (сочетание славишь Ctrl+О) либо просто перетянув файл в рабочее окно с помощью мыши.
  • Действие №2: после того, как изображение появилось в вашей рабочей зоне, откройте меню «Изображение», расположенное в верхнем левом углу редактора. Здесь будет вкладка «Изменить размер». Ее также можно запустить с помощью сочетания клавиш Ctrl+L.
  • Действие №3: в появившемся диалоговом окне вы столкнетесь сразу с несколькими полями. Первое из них, расположенное в самом верху, сообщит о новом размере изображения после изменения размеров. В дальнейшем, изменяя размер, вы будете видеть, как изменяются и объемы изображения в Кбайтах или Мбайтах. Далее идет поле выборки. Здесь следует установить вариант «Лучшее качество», потому что именно он позволит максимально сохранить первоначальное состояние изображения. Дальше идет поле в процентах. Это довольно удобно, если вы желаете уменьшить изображение в несколько раз. Например, если хотите, чтобы ваш файл стал вдвое меньше, то выставьте показатель «50%». Точно также по аналогии можно сделать в другом случае.
  • Действие №4: если вам необходимо установить исключительно тот размер, который нужен индивидуально, то поставьте галочку напротив поля «Абсолютный размер». Теперь ниже вы можете выставить показатели высоты, ширины и размещения в пикселях. Ставя галочку напротив поля «Сохранять пропорции», можно получить изображение без искажения.
  • Действие №5: после проделанных операций необходимо нажать команду «Окей». Изображение стало меньше. Осталось лишь его сохранить. Это можно сделать с помощью таких команд, как «Сохранить» и «Сохранить как…» в меню «Файл».

Как обрезать изображение в Paint ?

Часто возникает ситуация, когда изображение содержит лишние для вас детали. При этом хочется оставить лишь то, что должно находиться в фокусе. Такую операцию можно легко сделать с помощью Paint.

  • Действие №1: проделываем аналогичные операции с файлом как в первом случае (добавляем его на рабочее пространство).
  • Действие №2: зайдите в меню инструментов и выберите пункт «Прямоугольник». С помощью него выделите тот фрагмент, который желаете оставить.
  • Действие №3: зайдите в контекстное меню «Изображение». Самой верхней командой должно быть «Обрезать по выделению». Нажав на эту команду, у вас остается лишь то изображение, которое было выделено. Также после выделения обрезать изображение можно с помощью сочетания клавиш Ctrl+Shift+Х. Если же результат операции вам не понравился, нажмите клавишу «Отмена» или Ctrl+Z.

Как отзеркалить изображение в Paint ?

После того, как вы проведете аналогичную первым двум разделам операцию с файлом, следует отправиться в меню «Слои». Здесь вы встретитесь с такой командой как «Добавить новый слой», ее и выбирайте. Также это можно осуществить с помощью сочетания клавиш Ctrl+Shift+N. У вас появился новый прозрачный слой в изображении. Далее следует лишь внести некоторые регулировки. Отзеркалить активный слой, как по горизонтали, так и по вертикали, вам поможет команда «Отразить по горизонтали» или «Отразить по вертикали», которые также находятся в меню «Слои». Готово!

Вывод

В целом выполнять операции в Paint не сложно. Тем не менее, есть и определенные нюансы. Надеемся, что эта статья вам поможет.




Top