Загрузка данных
# -*- coding: utf-8 -*-
import os
import glob
root = os.path.dirname(os.path.abspath(__file__))
FILES = {}
FILES['Global.asax'] = r'''
<%@ Application Codebehind="Global.asax.cs" Inherits="WebApplication3.Global" Language="C#" %>
'''
FILES['Global.asax.cs'] = r'''
using System;
using System.Web.Routing;
namespace WebApplication3
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
}
'''
FILES['RouteConfig.cs'] = r'''
using System.Web.Routing;
namespace WebApplication3
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("NewProductRoute", "products/new", "~/NewProduct.aspx");
routes.MapPageRoute("ProductsListRoute", "products", "~/Products.aspx");
routes.MapPageRoute("ProductsRoute", "products/{id}", "~/Product.aspx",
false, null,
new RouteValueDictionary { { "id", @"^\d+$" } });
routes.MapPageRoute("StudentsRoute", "students", "~/Student.aspx");
routes.MapPageRoute("StudentRoute", "students/{id}", "~/Student.aspx",
false, null,
new RouteValueDictionary { { "id", @"^[1-9]\d*$" } });
routes.MapPageRoute("CatalogRoute", "catalog/{category}", "~/Catalog.aspx");
routes.MapPageRoute("CatalogItemRoute", "catalog/{category}/{id}", "~/Catalog.aspx",
false, null,
new RouteValueDictionary { { "id", @"^\d+$" } });
routes.MapPageRoute("ArchiveRoute", "archive/{year}/{month}", "~/Archive.aspx",
false, null,
new RouteValueDictionary
{
{ "year", @"^\d{4}$" },
{ "month", @"^(0[1-9]|1[0-2])$" }
});
routes.MapPageRoute("BooksRoute", "books", "~/Books.aspx");
routes.MapPageRoute("BooksPageRoute", "books/page/{page}", "~/Books.aspx",
false,
new RouteValueDictionary { { "page", "1" } },
new RouteValueDictionary { { "page", @"^\d+$" } });
routes.MapPageRoute("BookRoute", "books/{id}", "~/Book.aspx",
false, null,
new RouteValueDictionary { { "id", @"^\d+$" } });
routes.MapPageRoute("AuthorRoute", "authors/{name}", "~/Author.aspx");
routes.MapPageRoute("GenreRoute", "genres/{name}", "~/Genre.aspx");
routes.MapPageRoute("SearchRoute", "search/{text}", "~/Search.aspx");
routes.MapPageRoute("AuthorBookRoute", "authors/{name}/books/{id}", "~/Book.aspx",
false, null,
new RouteValueDictionary { { "id", @"^\d+$" } });
routes.MapPageRoute("RouteDebugRoute", "routedebug", "~/RouteDebug.aspx");
}
}
}
'''
FILES['Data.cs'] = r'''
using System.Collections.Generic;
using System.Linq;
namespace WebApplication3
{
public class ProductItem
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
}
public static class Shop
{
public static readonly List<ProductItem> Products = new List<ProductItem>
{
new ProductItem { Id = 1, Name = "Ноутбук Lenovo IdeaPad 3", Category = "laptops", Price = 45990m, Description = "15.6\", Ryzen 5, 16 ГБ ОЗУ, SSD 512 ГБ." },
new ProductItem { Id = 2, Name = "Ноутбук ASUS TUF Gaming", Category = "laptops", Price = 79990m, Description = "Игровой ноутбук, RTX 3050, экран 144 Гц." },
new ProductItem { Id = 3, Name = "Ноутбук HP Pavilion 15", Category = "laptops", Price = 54990m, Description = "15.6\", Core i5, 8 ГБ ОЗУ, SSD 256 ГБ." },
new ProductItem { Id = 4, Name = "Смартфон Samsung Galaxy A54", Category = "phones", Price = 32990m, Description = "6.4\", 8/128 ГБ, камера 50 Мп." },
new ProductItem { Id = 5, Name = "Смартфон Xiaomi Redmi Note 13", Category = "phones", Price = 19990m, Description = "6.6\", 8/256 ГБ, AMOLED 120 Гц." },
new ProductItem { Id = 6, Name = "Смартфон iPhone 15", Category = "phones", Price = 89990m, Description = "6.1\", процессор A16, 128 ГБ." },
new ProductItem { Id = 7, Name = "Планшет Samsung Galaxy Tab S9", Category = "tablets", Price = 64990m, Description = "11\", 8/128 ГБ, стилус S Pen." },
new ProductItem { Id = 8, Name = "Планшет Apple iPad 10.2", Category = "tablets", Price = 37990m, Description = "10.2\", A13, 64 ГБ." },
new ProductItem { Id = 9, Name = "Планшет Huawei MatePad SE", Category = "tablets", Price = 16990m, Description = "10.4\", 4/128 ГБ." }
};
public static readonly List<string> Categories = new List<string> { "laptops", "phones", "tablets" };
public static ProductItem Find(int id)
{
return Products.FirstOrDefault(p => p.Id == id);
}
}
public class BookItem
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Genre { get; set; }
public int Year { get; set; }
public string Description { get; set; }
}
public static class Library
{
public static readonly List<BookItem> Books = new List<BookItem>
{
new BookItem { Id = 1, Title = "Мастер и Маргарита", Author = "Михаил Булгаков", Genre = "Роман", Year = 1967, Description = "Мистический роман о визите дьявола в Москву." },
new BookItem { Id = 2, Title = "Собачье сердце", Author = "Михаил Булгаков", Genre = "Повесть", Year = 1925, Description = "История превращения собаки в человека." },
new BookItem { Id = 3, Title = "Преступление и наказание", Author = "Фёдор Достоевский", Genre = "Роман", Year = 1866, Description = "Роман о студенте, переступившем нравственный закон." },
new BookItem { Id = 4, Title = "Идиот", Author = "Фёдор Достоевский", Genre = "Роман", Year = 1869, Description = "История князя Мышкина." },
new BookItem { Id = 5, Title = "Война и мир", Author = "Лев Толстой", Genre = "Роман", Year = 1869, Description = "Эпопея о судьбах дворянства в эпоху наполеоновских войн." },
new BookItem { Id = 6, Title = "Анна Каренина", Author = "Лев Толстой", Genre = "Роман", Year = 1878, Description = "Трагедия любви Анны и Вронского." },
new BookItem { Id = 7, Title = "Евгений Онегин", Author = "Александр Пушкин", Genre = "Роман в стихах", Year = 1833, Description = "Роман в стихах о «лишнем человеке»." },
new BookItem { Id = 8, Title = "Капитанская дочка", Author = "Александр Пушкин", Genre = "Повесть", Year = 1836, Description = "Повесть о Пугачёвском восстании." },
new BookItem { Id = 9, Title = "Тихий Дон", Author = "Михаил Шолохов", Genre = "Роман", Year = 1940, Description = "Эпопея о донском казачестве." },
new BookItem { Id = 10, Title = "Судьба человека", Author = "Михаил Шолохов", Genre = "Рассказ", Year = 1957, Description = "Рассказ о судьбе солдата, прошедшего войну и плен." }
};
public static BookItem Find(int id)
{
return Books.FirstOrDefault(b => b.Id == id);
}
}
}
'''
FILES['Site.Master'] = r'''
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.Master.cs" Inherits="WebApplication3.Site" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Лабораторная: маршрутизация</title>
<style>
body { font-family: Arial; margin: 20px; }
.menu a { margin-right: 15px; }
.error { color: red; font-weight: bold; }
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="menu">
<a href='<%: GetRouteUrl("ProductsListRoute", null) %>'>Товары</a>
<a href='<%: GetRouteUrl("CatalogRoute", new { category = "laptops" }) %>'>Ноутбуки</a>
<a href='<%: GetRouteUrl("StudentRoute", new { id = 1 }) %>'>Студент №1</a>
<a href='<%: GetRouteUrl("ArchiveRoute", new { year = "2025", month = "12" }) %>'>Архив</a>
<a href='<%: GetRouteUrl("BooksRoute", null) %>'>Книги</a>
<a href='<%: GetRouteUrl("RouteDebugRoute", null) %>'>RouteDebug</a>
</div>
<hr />
<div>
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
</form>
</body>
</html>
'''
FILES['Site.Master.cs'] = r'''
using System;
namespace WebApplication3
{
public partial class Site : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e) { }
}
}
'''
FILES['Site.Master.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Site
{
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
protected global::System.Web.UI.WebControls.ContentPlaceHolder MainContent;
}
}
'''
FILES['Student.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Student.aspx.cs" Inherits="WebApplication3.Student" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Профиль студента</h1>
<asp:PlaceHolder ID="phProfile" runat="server" Visible="false">
<p><b>ФИО:</b> <asp:Literal ID="lblName" runat="server" /></p>
<p><b>Группа:</b> <asp:Literal ID="lblGroup" runat="server" /></p>
<p><b>Курс:</b> <asp:Literal ID="lblCourse" runat="server" /></p>
</asp:PlaceHolder>
<asp:Label ID="lblError" runat="server" CssClass="error" Visible="false" />
</asp:Content>
'''
FILES['Student.aspx.cs'] = r'''
using System;
namespace WebApplication3
{
public partial class Student : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
object idObj = RouteData.Values["id"];
if (idObj == null)
{
ShowError("Ошибка: параметр id отсутствует в адресе.");
return;
}
int id;
if (!int.TryParse(idObj.ToString(), out id) || id <= 0)
{
ShowError("Ошибка: id должен быть целым положительным числом.");
return;
}
string name, group;
int course;
bool found = true;
switch (id)
{
case 1: name = "Иванов Иван Иванович"; group = "ИСП-31"; course = 3; break;
case 25: name = "Петров Пётр Петрович"; group = "ИСП-22"; course = 2; break;
case 100: name = "Сидорова Анна Сергеевна"; group = "ИСП-44"; course = 4; break;
default: name = null; group = null; course = 0; found = false; break;
}
if (!found)
{
ShowError("Студент не найден");
return;
}
lblName.Text = name;
lblGroup.Text = group;
lblCourse.Text = course.ToString();
phProfile.Visible = true;
}
private void ShowError(string message)
{
phProfile.Visible = false;
lblError.Text = message;
lblError.Visible = true;
}
}
}
'''
FILES['Student.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Student
{
protected global::System.Web.UI.WebControls.PlaceHolder phProfile;
protected global::System.Web.UI.WebControls.Literal lblName;
protected global::System.Web.UI.WebControls.Literal lblGroup;
protected global::System.Web.UI.WebControls.Literal lblCourse;
protected global::System.Web.UI.WebControls.Label lblError;
}
}
'''
FILES['Products.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Products.aspx.cs" Inherits="WebApplication3.Products" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Каталог товаров</h1>
<asp:Repeater ID="RepeaterProducts" runat="server">
<ItemTemplate>
<p>
<%# Eval("Id") %>.
<a href='<%# GetRouteUrl("ProductsRoute", new { id = Eval("Id") }) %>'><%# Eval("Name") %></a>
— <%# Eval("Category") %>, <%# Eval("Price", "{0:N0}") %> руб.
</p>
</ItemTemplate>
</asp:Repeater>
</asp:Content>
'''
FILES['Products.aspx.cs'] = r'''
using System;
namespace WebApplication3
{
public partial class Products : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
RepeaterProducts.DataSource = Shop.Products;
RepeaterProducts.DataBind();
}
}
}
'''
FILES['Products.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Products
{
protected global::System.Web.UI.WebControls.Repeater RepeaterProducts;
}
}
'''
FILES['Product.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Product.aspx.cs" Inherits="WebApplication3.Product" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Информация о товаре</h1>
<asp:Panel ID="pnlProduct" runat="server" Visible="false">
<h2><asp:Literal ID="lblName" runat="server" /></h2>
<p><b>Категория:</b> <asp:Literal ID="lblCategory" runat="server" /></p>
<p><b>Цена:</b> <asp:Literal ID="lblPrice" runat="server" /> руб.</p>
<p><b>Описание:</b> <asp:Literal ID="lblDescription" runat="server" /></p>
</asp:Panel>
<asp:Label ID="lblError" runat="server" CssClass="error" Visible="false" />
</asp:Content>
'''
FILES['Product.aspx.cs'] = r'''
using System;
namespace WebApplication3
{
public partial class Product : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
object idObj = RouteData.Values["id"];
if (idObj == null) { ShowError("Ошибка: не передан id товара."); return; }
int id;
if (!int.TryParse(idObj.ToString(), out id)) { ShowError("Ошибка: id должен быть числом."); return; }
var product = Shop.Find(id);
if (product == null) { ShowError("Товар не найден"); return; }
lblName.Text = product.Name;
lblCategory.Text = product.Category;
lblPrice.Text = product.Price.ToString("N0");
lblDescription.Text = product.Description;
pnlProduct.Visible = true;
}
private void ShowError(string message)
{
pnlProduct.Visible = false;
lblError.Text = message;
lblError.Visible = true;
}
}
}
'''
FILES['Product.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Product
{
protected global::System.Web.UI.WebControls.Panel pnlProduct;
protected global::System.Web.UI.WebControls.Literal lblName;
protected global::System.Web.UI.WebControls.Literal lblCategory;
protected global::System.Web.UI.WebControls.Literal lblPrice;
protected global::System.Web.UI.WebControls.Literal lblDescription;
protected global::System.Web.UI.WebControls.Label lblError;
}
}
'''
FILES['Catalog.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Catalog.aspx.cs" Inherits="WebApplication3.Catalog" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Категория: <asp:Literal ID="lblCategory" runat="server" /></h1>
<p>
<a href='<%: GetRouteUrl("CatalogRoute", new { category = "laptops" }) %>'>Ноутбуки</a> |
<a href='<%: GetRouteUrl("CatalogRoute", new { category = "phones" }) %>'>Телефоны</a> |
<a href='<%: GetRouteUrl("CatalogRoute", new { category = "tablets" }) %>'>Планшеты</a>
</p>
<asp:Panel ID="pnlProduct" runat="server" Visible="false">
<h2><asp:Literal ID="lblName" runat="server" /></h2>
<p><b>Цена:</b> <asp:Literal ID="lblPrice" runat="server" /> руб.</p>
<p><b>Описание:</b> <asp:Literal ID="lblDescription" runat="server" /></p>
<asp:HyperLink ID="lnkBack" runat="server" Text="← ко всем товарам категории" />
</asp:Panel>
<asp:Repeater ID="RepeaterProducts" runat="server">
<ItemTemplate>
<p>
<a href='<%# GetRouteUrl("CatalogItemRoute", new { category = Eval("Category"), id = Eval("Id") }) %>'><%# Eval("Name") %></a>
— <%# Eval("Price", "{0:N0}") %> руб.
</p>
</ItemTemplate>
</asp:Repeater>
<asp:Label ID="lblError" runat="server" CssClass="error" Visible="false" />
</asp:Content>
'''
FILES['Catalog.aspx.cs'] = r'''
using System;
using System.Linq;
namespace WebApplication3
{
public partial class Catalog : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string category = Convert.ToString(RouteData.Values["category"]);
string canonical = Shop.Categories
.FirstOrDefault(c => string.Equals(c, category, StringComparison.OrdinalIgnoreCase));
if (canonical == null)
{
ShowError("Категория \"" + category + "\" не найдена.");
return;
}
lblCategory.Text = canonical;
object idObj = RouteData.Values["id"];
if (idObj == null)
{
RepeaterProducts.DataSource = Shop.Products.Where(p => p.Category == canonical).ToList();
RepeaterProducts.DataBind();
return;
}
int id;
if (!int.TryParse(idObj.ToString(), out id))
{
ShowError("Ошибка: id должен быть числом.");
return;
}
var product = Shop.Find(id);
if (product == null) { ShowError("Товар не найден."); return; }
if (!string.Equals(product.Category, canonical, StringComparison.OrdinalIgnoreCase))
{
ShowError("Некорректный адрес: товар №" + id + " не относится к категории \"" + canonical + "\".");
return;
}
lblName.Text = product.Name;
lblPrice.Text = product.Price.ToString("N0");
lblDescription.Text = product.Description;
lnkBack.NavigateUrl = GetRouteUrl("CatalogRoute", new { category = canonical });
pnlProduct.Visible = true;
RepeaterProducts.Visible = false;
}
private void ShowError(string message)
{
pnlProduct.Visible = false;
RepeaterProducts.Visible = false;
lblError.Text = message;
lblError.Visible = true;
}
}
}
'''
FILES['Catalog.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Catalog
{
protected global::System.Web.UI.WebControls.Literal lblCategory;
protected global::System.Web.UI.WebControls.Panel pnlProduct;
protected global::System.Web.UI.WebControls.Literal lblName;
protected global::System.Web.UI.WebControls.Literal lblPrice;
protected global::System.Web.UI.WebControls.Literal lblDescription;
protected global::System.Web.UI.WebControls.HyperLink lnkBack;
protected global::System.Web.UI.WebControls.Repeater RepeaterProducts;
protected global::System.Web.UI.WebControls.Label lblError;
}
}
'''
FILES['Archive.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Archive.aspx.cs" Inherits="WebApplication3.Archive" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Архив материалов</h1>
<p>Выбранный период: <b><asp:Literal ID="lblPeriod" runat="server" /></b></p>
<asp:Repeater ID="RepeaterMaterials" runat="server">
<ItemTemplate><p><%# Container.DataItem %></p></ItemTemplate>
</asp:Repeater>
</asp:Content>
'''
FILES['Archive.aspx.cs'] = r'''
using System;
using System.Collections.Generic;
namespace WebApplication3
{
public partial class Archive : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string year = RouteData.Values["year"].ToString();
string month = RouteData.Values["month"].ToString();
string[] monthsRu =
{
"", "январь", "февраль", "март", "апрель", "май", "июнь",
"июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"
};
int monthNum = int.Parse(month);
lblPeriod.Text = monthNum + " " + year + " (" + month + "/" + year + ")";
var materials = new List<string>();
for (int i = 1; i <= 3; i++)
materials.Add("Материал №" + i + " — обзор за " + monthsRu[monthNum] + " " + year + " года");
RepeaterMaterials.DataSource = materials;
RepeaterMaterials.DataBind();
}
}
}
'''
FILES['Archive.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Archive
{
protected global::System.Web.UI.WebControls.Literal lblPeriod;
protected global::System.Web.UI.WebControls.Repeater RepeaterMaterials;
}
}
'''
FILES['NewProduct.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="NewProduct.aspx.cs" Inherits="WebApplication3.NewProduct" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Создание нового товара</h1>
<p>Отдельная страница для адреса <b>/products/new</b>.</p>
<p>Здесь могла бы быть форма создания товара.</p>
</asp:Content>
'''
FILES['NewProduct.aspx.cs'] = r'''
using System;
namespace WebApplication3
{
public partial class NewProduct : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e) { }
}
}
'''
FILES['NewProduct.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class NewProduct
{
}
}
'''
FILES['Books.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Books.aspx.cs" Inherits="WebApplication3.Books" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Библиотека — список книг</h1>
<p><asp:Literal ID="lblPage" runat="server" /></p>
<asp:Repeater ID="RepeaterBooks" runat="server">
<ItemTemplate>
<p>
<a href='<%# GetRouteUrl("BookRoute", new { id = Eval("Id") }) %>'><b><%# Eval("Title") %></b></a><br />
Автор:
<a href='<%# GetRouteUrl("AuthorRoute", new { name = Eval("Author") }) %>'><%# Eval("Author") %></a>
| Жанр:
<a href='<%# GetRouteUrl("GenreRoute", new { name = Eval("Genre") }) %>'><%# Eval("Genre") %></a>
| Год: <%# Eval("Year") %>
</p>
</ItemTemplate>
</asp:Repeater>
</asp:Content>
'''
FILES['Books.aspx.cs'] = r'''
using System;
namespace WebApplication3
{
public partial class Books : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int page = 1;
if (RouteData.Values["page"] != null)
int.TryParse(RouteData.Values["page"].ToString(), out page);
lblPage.Text = "Страница: " + page;
RepeaterBooks.DataSource = Library.Books;
RepeaterBooks.DataBind();
}
}
}
'''
FILES['Books.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Books
{
protected global::System.Web.UI.WebControls.Literal lblPage;
protected global::System.Web.UI.WebControls.Repeater RepeaterBooks;
}
}
'''
FILES['Book.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Book.aspx.cs" Inherits="WebApplication3.Book" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Книга</h1>
<asp:Panel ID="pnlBook" runat="server" Visible="false">
<h2><asp:Literal ID="lblTitle" runat="server" /></h2>
<p><b>Автор:</b> <a id="lnkAuthor" runat="server"></a></p>
<p><b>Жанр:</b> <a id="lnkGenre" runat="server"></a></p>
<p><b>Год:</b> <asp:Literal ID="lblYear" runat="server" /></p>
<p><b>Описание:</b> <asp:Literal ID="lblDescription" runat="server" /></p>
</asp:Panel>
<asp:Label ID="lblError" runat="server" CssClass="error" Visible="false" />
</asp:Content>
'''
FILES['Book.aspx.cs'] = r'''
using System;
namespace WebApplication3
{
public partial class Book : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
object idObj = RouteData.Values["id"];
if (idObj == null) { ShowError("Ошибка: не передан id книги."); return; }
int id;
if (!int.TryParse(idObj.ToString(), out id)) { ShowError("Ошибка: id должен быть числом."); return; }
var book = Library.Find(id);
if (book == null) { ShowError("Книга не найдена"); return; }
object nameObj = RouteData.Values["name"];
if (nameObj != null)
{
string name = nameObj.ToString();
if (!string.Equals(book.Author, name, StringComparison.OrdinalIgnoreCase))
{
ShowError("Некорректный адрес: книга \"" + book.Title + "\" написана " +
book.Author + ", а не " + name + ".");
return;
}
}
lblTitle.Text = book.Title;
lblYear.Text = book.Year.ToString();
lblDescription.Text = book.Description;
lnkAuthor.InnerText = book.Author;
lnkAuthor.HRef = GetRouteUrl("AuthorRoute", new { name = book.Author });
lnkGenre.InnerText = book.Genre;
lnkGenre.HRef = GetRouteUrl("GenreRoute", new { name = book.Genre });
pnlBook.Visible = true;
}
private void ShowError(string message)
{
pnlBook.Visible = false;
lblError.Text = message;
lblError.Visible = true;
}
}
}
'''
FILES['Book.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Book
{
protected global::System.Web.UI.WebControls.Panel pnlBook;
protected global::System.Web.UI.WebControls.Literal lblTitle;
protected global::System.Web.UI.HtmlControls.HtmlAnchor lnkAuthor;
protected global::System.Web.UI.HtmlControls.HtmlAnchor lnkGenre;
protected global::System.Web.UI.WebControls.Literal lblYear;
protected global::System.Web.UI.WebControls.Literal lblDescription;
protected global::System.Web.UI.WebControls.Label lblError;
}
}
'''
FILES['Author.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Author.aspx.cs" Inherits="WebApplication3.Author" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Автор: <asp:Literal ID="lblAuthor" runat="server" /></h1>
<p>Книги этого автора:</p>
<asp:Repeater ID="RepeaterBooks" runat="server">
<ItemTemplate>
<p>
<a href='<%# GetRouteUrl("BookRoute", new { id = Eval("Id") }) %>'><%# Eval("Title") %></a>
(<%# Eval("Year") %>, <%# Eval("Genre") %>)
</p>
</ItemTemplate>
</asp:Repeater>
<asp:Label ID="lblError" runat="server" CssClass="error" Visible="false" />
</asp:Content>
'''
FILES['Author.aspx.cs'] = r'''
using System;
using System.Linq;
namespace WebApplication3
{
public partial class Author : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string name = Convert.ToString(RouteData.Values["name"]);
var books = Library.Books
.Where(b => string.Equals(b.Author, name, StringComparison.OrdinalIgnoreCase))
.ToList();
if (books.Count == 0) { ShowError("Автор не найден"); return; }
lblAuthor.Text = books[0].Author;
RepeaterBooks.DataSource = books;
RepeaterBooks.DataBind();
}
private void ShowError(string message)
{
lblAuthor.Text = "?";
RepeaterBooks.Visible = false;
lblError.Text = message;
lblError.Visible = true;
}
}
}
'''
FILES['Author.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Author
{
protected global::System.Web.UI.WebControls.Literal lblAuthor;
protected global::System.Web.UI.WebControls.Repeater RepeaterBooks;
protected global::System.Web.UI.WebControls.Label lblError;
}
}
'''
FILES['Genre.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Genre.aspx.cs" Inherits="WebApplication3.Genre" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Жанр: <asp:Literal ID="lblGenre" runat="server" /></h1>
<p>Книги этого жанра:</p>
<asp:Repeater ID="RepeaterBooks" runat="server">
<ItemTemplate>
<p>
<a href='<%# GetRouteUrl("BookRoute", new { id = Eval("Id") }) %>'><%# Eval("Title") %></a>
(<%# Eval("Author") %>, <%# Eval("Year") %>)
</p>
</ItemTemplate>
</asp:Repeater>
<asp:Label ID="lblError" runat="server" CssClass="error" Visible="false" />
</asp:Content>
'''
FILES['Genre.aspx.cs'] = r'''
using System;
using System.Linq;
namespace WebApplication3
{
public partial class Genre : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string name = Convert.ToString(RouteData.Values["name"]);
var books = Library.Books
.Where(b => string.Equals(b.Genre, name, StringComparison.OrdinalIgnoreCase))
.ToList();
if (books.Count == 0) { ShowError("Жанр не найден"); return; }
lblGenre.Text = books[0].Genre;
RepeaterBooks.DataSource = books;
RepeaterBooks.DataBind();
}
private void ShowError(string message)
{
lblGenre.Text = "?";
RepeaterBooks.Visible = false;
lblError.Text = message;
lblError.Visible = true;
}
}
}
'''
FILES['Genre.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Genre
{
protected global::System.Web.UI.WebControls.Literal lblGenre;
protected global::System.Web.UI.WebControls.Repeater RepeaterBooks;
protected global::System.Web.UI.WebControls.Label lblError;
}
}
'''
FILES['Search.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Search.aspx.cs" Inherits="WebApplication3.Search" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Поиск книг</h1>
<p>Результаты по запросу «<asp:Literal ID="lblQuery" runat="server" />»:</p>
<asp:Repeater ID="RepeaterBooks" runat="server">
<ItemTemplate>
<p>
<a href='<%# GetRouteUrl("BookRoute", new { id = Eval("Id") }) %>'><%# Eval("Title") %></a>
— <%# Eval("Author") %>, <%# Eval("Year") %>
</p>
</ItemTemplate>
</asp:Repeater>
<asp:Label ID="lblError" runat="server" CssClass="error" Visible="false" />
</asp:Content>
'''
FILES['Search.aspx.cs'] = r'''
using System;
using System.Linq;
namespace WebApplication3
{
public partial class Search : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string text = Convert.ToString(RouteData.Values["text"]);
lblQuery.Text = text;
var results = Library.Books
.Where(b => b.Title.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
.ToList();
if (results.Count == 0)
{
RepeaterBooks.Visible = false;
lblError.Text = "По запросу \"" + text + "\" ничего не найдено";
lblError.Visible = true;
return;
}
RepeaterBooks.DataSource = results;
RepeaterBooks.DataBind();
}
}
}
'''
FILES['Search.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class Search
{
protected global::System.Web.UI.WebControls.Literal lblQuery;
protected global::System.Web.UI.WebControls.Repeater RepeaterBooks;
protected global::System.Web.UI.WebControls.Label lblError;
}
}
'''
FILES['RouteDebug.aspx'] = r'''
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="RouteDebug.aspx.cs" Inherits="WebApplication3.RouteDebug" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>RouteDebug</h1>
<h2>Все значения RouteData.Values текущего запроса</h2>
<asp:Literal ID="lblValues" runat="server" />
</asp:Content>
'''
FILES['RouteDebug.aspx.cs'] = r'''
using System;
using System.Text;
namespace WebApplication3
{
public partial class RouteDebug : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var sb = new StringBuilder();
sb.Append("<table border='1' cellpadding='4'>");
foreach (string key in RouteData.Values.Keys)
{
sb.Append("<tr><td><b>").Append(Server.HtmlEncode(key))
.Append("</b></td><td>")
.Append(Server.HtmlEncode(Convert.ToString(RouteData.Values[key])))
.Append("</td></tr>");
}
sb.Append("</table>");
lblValues.Text = sb.ToString();
}
}
}
'''
FILES['RouteDebug.aspx.designer.cs'] = r'''
namespace WebApplication3
{
public partial class RouteDebug
{
protected global::System.Web.UI.WebControls.Literal lblValues;
}
}
'''
for name, content in FILES.items():
path = os.path.join(root, name)
text = content.strip().replace('\r\n', '\n')
with open(path, 'w', encoding='utf-8-sig', newline='\r\n') as f:
f.write(text)
print('создан:', name)
projects = glob.glob(os.path.join(root, '*.csproj'))
if not projects:
print('ВНИМАНИЕ: csproj не найден. Положи скрипт в папку проекта (рядом с .csproj).')
else:
csproj = projects[0]
with open(csproj, 'r', encoding='utf-8-sig') as f:
text = f.read().replace('\r\n', '\n')
entries = []
def add(tag, include, dep=None, subtype=None):
entries.append((tag, include, dep, subtype))
add('Content', 'Global.asax')
add('Compile', 'Global.asax.cs', 'Global.asax')
add('Content', 'Site.Master')
add('Compile', 'Site.Master.cs', 'Site.Master', 'ASPXCodeBehind')
add('Compile', 'Site.Master.designer.cs', 'Site.Master')
add('Compile', 'Data.cs')
add('Compile', 'RouteConfig.cs')
for p in ['Student', 'Products', 'Product', 'Catalog', 'Archive', 'NewProduct',
'Books', 'Book', 'Author', 'Genre', 'Search', 'RouteDebug']:
add('Content', p + '.aspx')
add('Compile', p + '.aspx.cs', p + '.aspx', 'ASPXCodeBehind')
add('Compile', p + '.aspx.designer.cs', p + '.aspx')
lines = [' <ItemGroup>']
added = 0
for tag, include, dep, subtype in entries:
if ('Include="%s"' % include) in text:
continue
added += 1
if dep is None and subtype is None:
lines.append(' <%s Include="%s" />' % (tag, include))
else:
lines.append(' <%s Include="%s">' % (tag, include))
if dep:
lines.append(' <DependentUpon>%s</DependentUpon>' % dep)
if subtype:
lines.append(' <SubType>%s</SubType>' % subtype)
lines.append(' </%s>' % tag)
lines.append(' </ItemGroup>')
block = '\n'.join(lines) + '\n'
if added > 0:
idx = text.rfind('</Project>')
text = text[:idx] + block + '\n' + text[idx:]
with open(csproj, 'w', encoding='utf-8-sig', newline='\r\n') as f:
f.write(text)
print('csproj обновлён, добавлено записей:', added)
else:
print('csproj уже содержит все файлы.')
print()
print('Готово. Открывай Visual Studio и делай Rebuild Solution.')