Функциональные возможности и расхождения

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

Раздел 2

Техническое задание

Разработка web-приложения для размещения объявления о продажах

Назначение и цели создания приложения:

- Изучение технологии ASP.NET

- Изучение языка C#

- Использования современных технологий разработки в виде паттерна MVC и View шаблонов

- Самообразование

Требование к сайту:

- Возможность просмотра активных и не активных объявлений

- Возможность добавления новых объявлений

- Возможность удаления не актуальных объявлений( переноса в секцию не активных)

- Архитектура приложения, дающая возможность масштабируемости и модификации

- Использование технологии ASP.NET

- Дизайн приложения, дающий визуальное представления об расположении блоков

Раздел 3

Этапы создания приложения

Выбор системы и инструментов разработки

Для технологии ASP.NET необходим сам .NET, который, в свою очередь, разрабатывает и поддерживает Microsoft, в связи с чем выбирать можно только между VisualStudio, кроссплатформенной VisualStudio code и кроссплатформенным решениям на основе Mono. Выбор пал на платформу Visual studio, так как ОС Windows является родной для платформы .NET- отпадают некоторые проблемы, связанные со сменой платформ и понижается порог вхождения в технологию.

Так как задание не является курсовой или дипломной работой- для построения «скелета» приложения мной были выбраны принципы MVC без использования каких либо фреймворков и баз данных. Данные приложения хранятся в отдельном классе модели приложения, что позволяет полно выполнить поставленные в ТЗ цели без использования лишних инструментов.

Описание структуры приложения

Функциональные возможности и расхождения - student2.ru TestAspNet45- название приложения

Views- Пример использования отдельной папки для представлений.

Site1.Master- Пример использования возможности шаблонов представлений, или мастер-страниц, как говорится в литературе ASP.NET.

Default.aspx- является представлением страницы добавления новых объявлений

Default.aspx.cs- контроллер представления Default.aspx

Summary.aspx- является представлением страницы добавления новых объявлений

Summary.aspx.cs- контроллер представления Summary.aspx

Style.css- файл каскадных таблиц стилей всего приложения

TestClass.cs- модель приложения, описывающая переменные, использующиеся для хранения информации об объявлениях в приложении, и возможности взаимодействия с ними

Repository.cs- модель приложения, описывающая функции для работы с хранилищем, описанным в модели TestClass

Описание приложения

Модель

TestClass.cs модель, описывающая объекты, с которыми будет взаимодействовать приложение. Аналогично, таблице реляционной базы данных.

using System;

using System.Collections.Generic;

using System.ComponentModel.DataAnnotations;

using System.Linq;

using System.Web;

namespace TestAspNet45

{

public class TestClass

{

public string Id { get; set; } //Номер объявления

[Required] //Параметр валидации поля

public string Title { get; set; } //заголовок объявления

[Required]

public string Body { get; set; } //Текст объявления

[Required]

public string Phone { get; set; } //Номер телефона

public bool? WillAttend { get; set; } //параметр актуальности объявления

}

}

Repository.cs модель, описывающая функции взаимодействия с объектами модели, содержащими данные, которые хранит приложение.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace TestAspNet45

{

public class Repository //модель с механизмами взаимодействия с хранилищем

{

private static Repository repository = new Repository(); //Создание экземпляра класса модели взаимодействия

private List<TestClass> responses = new List<TestClass>(); //Список объектов модели хранилища

public static Repository GetRepository() { // "Геттер", функция для получения хранилища

return repository;

}

public IEnumerable<TestClass> GetAllResponses() { // "Геттер", функция для получения перебора объектов хранилища

return responses;

}

public void AddResponse(TestClass response) { //Добавление объекта в хранилище

responses.Add(response);

}

}

}

Контроллеры

Summary.aspx.cs контроллер главной страницы, формирующий динамический контент, расширяя страницу шаблон(мастер-страницу). В связке Viewer-Controller Summary применено 2 способа формирования динамического контента- в Представлении(не правильно), и в Контроллере(правильно).

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace TestAspNet45

{

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

{

protected void Page_Load(object sender, EventArgs e)

{}

protected string GetNoShowHtml() //Пример вывода дигнамической разметки из контроллера

{

StringBuilder html = new StringBuilder(); //создание строки

var noData = Repository.GetRepository().GetAllResponses().Where(i => !i.WillAttend.Value); //Получение значений из хранилища по ключу

foreach (var rsvp in noData) { //Перебор значений

html.Append(String.Format("<div>" +

"<h3> Тема: {1} </h3> </ br>" +

"<p>{2}</p> </ br>" +

"<h3> Номер телефона: {3} </h3> &nbsp <a href=Default.aspx?id={0}>Убрать?</a>" +

"</div>", rsvp.Id, rsvp.Title, rsvp.Body, rsvp.Phone)); //Формирование динамической разметки

}

return html.ToString(); //возврат строки в представление

}

}

}

Default.aspx.cs Контроллер страницы добавления контента. Отвечает за создание новых объектов в хранилище, и смены флага активности объявления. Показывает способы обработки Get и Post запросов.

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 WebForm1 : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e) //Функиця, отвечающая за дейсвтие при загрузке страницы

{

if (IsPostBack) // Если приходит Post-данные, например кнопка send формы

{

TestClass rsvp = new TestClass(); //создание экземпляра модели

if (TryUpdateModel(rsvp, new FormValueProvider(ModelBindingExecutionContext))) //попытка заполнить поля модели данными из формы

{

rsvp.Id = Repository.GetRepository().GetAllResponses().Count().ToString(); //Создание порядкового номера

rsvp.WillAttend = true; //Активация объявления

Repository.GetRepository().AddResponse(rsvp); //добавление объекта в хранилище

Response.Redirect("Summary.aspx"); //редирект на главную страницу

}

}

if (Request.QueryString["id"] != null) { //Если страница открывается с параметром id

string id = Request.QueryString["id"];

var noData = Repository.GetRepository().GetAllResponses().Where(i => i.WillAttend.Value); //то получаем из хранилища объекты с активными объявлениями

foreach(var r in noData) //перебираем

{

if (r.Id == id) //и ищем значения, равные параметру id

{

r.WillAttend = false; //и снимаем флаг активности

break;

}

}

Response.Redirect("Summary.aspx"); //переходим на главную страницу

}

}

}

}

Представления

Front-end составляющая приложения создалась в цветовых тонах и стилях, позволяющих легко визуально контролировать расположение статических блоков, и блоков динамического контента.

Style.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[type=submit] { margin-top: 15px; padding: 5px; }   table, td, th { border: thin solid black; border-collapse: collapse; padding: 5px; background-color: lemonchiffon; text-align: left; margin: 10px 0; }   #validationSummary { color: red; }   #willattend { height: 40px; width: 349px; }   body { background-color: darkgrey; }   #container { background-color:brown; width: 80%; height: auto; margin: 0 auto; }   #header { background-color: wheat; width: 100%; height: 100px; }   .c { border: 1px solid #333; display: inline-block; padding: 10px 15px; text-decoration: underline; color: #000; }   .c:hover { box-shadow: 0 0 5px rgba(0,0,0,0.3); background: linear-gradient(to bottom, #fcfff4, #e9e9ce); color: #a00; //margin-top: 50px; }   #head_h { font-family: Mistral; color: red; -webkit-text-stroke: 1px black; }   .content_div div { width: 70%; background-color: blueviolet; margin: 0 auto; }  

Site1.master файл шаблон Представления(мастер-страница). Еще один хороший подход в практике веб-программирования. Использование шаблонов Представлений позволяет делать приложение более гибким, сокращает код и позволяет внося изменения в один файл- вносить изменения во внешний вид приложения в целом.

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site1.master.cs" Inherits="TestAspNet45.Views.Site1" %>

<!DOCTYPE html>

<!-- мастер старница(шаблон представления приложения) -->

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

<head runat="server">

<link rel="stylesheet" href="~/Styles.css" /> <!-- подключение файла стилей -->

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<title></title>

</head>

<body>

<div id="container">

<div id="header">

<div id="top" class="head_inside">

<h1 align="center" id="head_h" >Площадка для размещения объявлений</h1>

</div>

<div id="menu" class="head_inside">

<a href="Summary.aspx" class="c">На главную</a>

<a href="Default.aspx" class="c">Добавить объявление</a>

</div>

</div>

<div class="content_div"> <!-- Контейнер содержимого -->

<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"> <!-- Подключения динамического контента в шаблон -->

</asp:ContentPlaceHolder>

</div>

</div>

</body>

</html>

Функциональные возможности и расхождения - student2.ru

Summary.aspx Представление главной страницы. Содержимое представления встраивается в верстку мастер-страницы, создавая законченный вид приложения. Имеет элементы формирования динамического контента.

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

MasterPageFile="~/Views/Site1.master" Title="Title" %>

<%@ Import Namespace="TestAspNet45" %> <!-- Служебная информация, включая подключение мастер-страницы(шабблона представления) -->

<asp:Content ID="Conten1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server" > <!-- Все, что в этом блоке- будет встроено в представление шаблона-->

<h2>Актуальные объявления</h2>

<% var yesData = Repository.GetRepository().GetAllResponses().Where(r => r.WillAttend.Value);

foreach (var rsvp in yesData) {

string htmlString = String.Format("<div>" +

"<h3> Тема: {1} </h3> </ br>" +

"<p>{2}</p> </ br>" +

"<h3> Номер телефона: {3} </h3> &nbsp <a href=Default.aspx?id={0}>Убрать?</a>" +

"</div>", rsvp.Id, rsvp.Title, rsvp.Body, rsvp.Phone);

Response.Write(htmlString);

}

%> <!-- Пример динамической разметки в представлении -->

<h2>Не актуальные объявления</h2>

<%= GetNoShowHtml()%> <!-- вывод динамической разметки из контроллера -->

</asp:Content>

Функциональные возможности и расхождения - student2.ru

Верстка сайта без динамического контента.

Default.aspx Представление формы добавления новых объявлений. Не получилось подсунуть это представление в мастер-страницу из за изменение имен элементов формы.

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

<!DOCTYPE html>

<!-- страница без использования шаблона, так как не смог справится с проблеммой переименования элементов формы -->

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

<head runat="server">

<link rel="stylesheet" href="~/Styles.css" />

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<title></title>

</head>

<body>

<div id="container"> <!-- стандартная разметка шаблона -->

<div id="header">

<div id="top" class="head_inside">

<h1 align="center" id="head_h" >Площадка для размещения объявлений</h1>

</div>

<div id="menu" class="head_inside">

<a href="Summary.aspx" class="c">На главную</a>

</div>

</div>

<div class="content_div">

<form id="rsvpform" runat="server" > <!-- Форма, передающая данные контроллеру -->

<asp:ValidationSummary ID="validationSummary" runat="server" ShowModelStateErrors="true" /> <!-- тег валидации -->

<div>

<h1>Форма добавления объявления:</h1>

<label> Тема: </label> <input type="text" id="title" name="title" runat="server"/>

</div>

<div>

<label> Содержание: </label> <input type="text" id="body" runat="server"/>

</div>

<div>

<label> Номер телефона: </label> <input type="text" id="phone" runat="server"/>

</div>

<div>

<button type="submit">Отправить объявление</button>

</div>

</form>

</div>

</body>

</html>

Функциональные возможности и расхождения - student2.ru

Верстка формы добавления новых объявлений.

Пример использования приложения

В связи с отсутствием базы данных- каждый перезапуск приложения влечет за собой удаление всех созданных данных. Первый запуск приложения

Объявлений пока нет, но их можно до Функциональные возможности и расхождения - student2.ru бавить!

Переходим во вкладку «Добавить объявление»:

Функциональные возможности и расхождения - student2.ru
Функциональные возможности и расхождения - student2.ru Нас встречает форма добавления объявлений.

Функциональные возможности и расхождения - student2.ru После добавления на главной странице формируется динамический контент с данными, которые написал пользователь. И ссылка, предлагающая убрать объявление в не активные. Добавим еще несколько штук.

Функциональные возможности и расхождения - student2.ru При попытке отправить форму с незаполненными одним или несколькими полями- сработает валидация.

Добавлено несколько объявлений. Можно попробовать одно удалить. Поле id, как Primary key, отвечает за уникальность, и с его помощью можно удалять объявления, не боясь ошибиться.

Функциональные возможности и расхождения - student2.ru

Контроллер меняет параметр, отвечающий за активность объявления, и оно переходит в стадию не активных.

Раздел 4

Вывод

В рамках контрольной работы было создано простое web-приложение. Я изучил основы технологии ASP.NET, языка C#, и устройство приложения с использованием этих технологий. Так же я применил современные концепции в веб-разработке(MVC, шаблон представления), которые используются повсеместно. Не со всеми проблемами получилось справиться. Я так и не смог разобраться как засовывать формы в шаблоны представлений, чтобы не изменялись имена элементов, либо обращаться в контроллере к измененным именам. При необходимости развития приложения- требуется написать пагинатор для динамического контента главной страницы, админ панель, сложную валидацию, аутентификацию, и подключить базу данных.

Список литературы

https://habrahabr.ru
https://www.asp.net
https://professorweb.ru

Наши рекомендации