Форум программистов, компьютерный форум, киберфорум
C#: Web, ASP.NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
3 / 2 / 1
Регистрация: 13.11.2024
Сообщений: 8

Поиск страниц в проекте на Razor

21.07.2025, 10:40. Показов 1054. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, форумчане!
Я как новичок и самоучка делаю проект, где нужно добавить нормальный поиск страниц (скрин структуры во вложении). Идея сделать Search.cshtml с кодом к нему, чтобы искал по всем Pages страницы по тайтлу и контенту. Неожиданно наткнулся на сложности с реализацией, мой код просто ничего не возвращает, даже если я знаю что страницы такие в проекте есть. Я потом уже подключил нейросети, они намудрили, уточнили поиск с регулярками, но возврата результатов поиска нет (например, по "BMI" пусто, нет якобы результатов). Кто сталкивался, скажите что не так. Я думаю, с путями проблема.

Ниже приводится страница поиска и код за ней:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@page
@model WebMedCalculator.Pages.SearchModel
@{
    ViewData["Title"] = "Suche";
}
 
<div class="container mt-4">
    <h2>Suchergebnisse für "@Model.Q"</h2>
 
    @if (Model.Results.Count == 0)
    {
        <div class="alert alert-warning mt-3">
            Keine Ergebnisse gefunden für "@Model.Q".
        </div>
    }
    else
    {
        <div class="list-group mt-3">
            @foreach (var result in Model.Results)
            {
                <a href="@result.Url" class="list-group-item list-group-item-action">
                    <h5>@result.Title</h5>
                    @if (!string.IsNullOrEmpty(result.Snippet))
                    {
                        <p class="mb-0 text-muted">...@result.Snippet...</p>
                    }
                    <small class="text-muted">@result.Url</small>
                </a>
            }
        </div>
    }
</div>
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Hosting;
 
namespace WebMedCalculator.Pages
{
    public class SearchModel : PageModel
    {
        private readonly IWebHostEnvironment _environment;
 
        public SearchModel(IWebHostEnvironment environment)
        {
            _environment = environment;
        }
 
        [BindProperty(SupportsGet = true)]
        public string? Q { get; set; }
 
        public List<ResultItem> Results { get; set; } = new();
 
        public void OnGet()
        {
            if (string.IsNullOrWhiteSpace(Q))
                return;
 
            var pagesPath = Path.Combine(_environment.ContentRootPath, "Pages");
            Console.WriteLine($"Content Root: {_environment.ContentRootPath}");
            Console.WriteLine($"pagesPath: {pagesPath}");
 
            var files = Directory.EnumerateFiles(pagesPath, "*.cshtml", SearchOption.AllDirectories)
                               .Where(f => !f.EndsWith(".cshtml.cs"));
            Console.WriteLine($"Found {files.Count()} files: {string.Join(", ", files)}");
 
            foreach (var file in files)
            {
                string content = System.IO.File.ReadAllText(file);
                string fileName = Path.GetFileNameWithoutExtension(file);
                string relativePath = GetRelativePath(file, pagesPath);
 
                string? title = GetPageTitle(content, fileName);
                string plainTextContent = GetSearchableContent(content);
 
                if (IsMatchFound(plainTextContent, title, fileName, relativePath))
                {
                    Results.Add(new ResultItem
                    {
                        Title = title ?? fileName,
                        Url = relativePath,
                        Snippet = GetContentSnippet(plainTextContent)
                    });
                }
            }
        }
 
        // Rest des Codes bleibt unverändert
        private string GetRelativePath(string fullPath, string basePath)
        {
            string relativePath = fullPath
                .Replace(basePath, "")
                .Replace("\\", "/")
                .Replace(".cshtml", "");
 
            return relativePath.StartsWith("/") ? relativePath : "/" + relativePath;
        }
 
        private string? GetPageTitle(string content, string fileName)
        {
            var titleMatch = Regex.Match(content, @"@ViewData\[""Title""\]\s*=\s*""(.+?)""");
            if (titleMatch.Success)
                return titleMatch.Groups[1].Value;
 
            var hMatch = Regex.Match(content, @"<h\d[^>]*>(.*?)<\/h\d>", RegexOptions.IgnoreCase);
            return hMatch.Success ? hMatch.Groups[1].Value : fileName;
        }
 
        private string GetSearchableContent(string content)
        {
            string withoutRazor = Regex.Replace(content, @"@\{(.*?)\}|@[A-Za-z0-9_.]+", "", RegexOptions.Singleline);
            return Regex.Replace(withoutRazor, @"<[^>]+>", " ")
                       .Replace("\n", " ")
                       .Replace("\r", " ")
                       .Trim();
        }
 
        private bool IsMatchFound(string content, string? title, string fileName, string relativePath)
        {
            if (string.IsNullOrWhiteSpace(Q))
                return false;
 
            string query = Q.Trim();
            StringComparison comparison = StringComparison.OrdinalIgnoreCase;
 
            return (title != null && title.Contains(query, comparison)) ||
                   fileName.Contains(query, comparison) ||
                   relativePath.Contains(query, comparison) ||
                   content.Contains(query, comparison);
        }
 
        private string GetContentSnippet(string content)
        {
            if (string.IsNullOrWhiteSpace(Q))
                return string.Empty;
 
            int pos = content.IndexOf(Q, StringComparison.OrdinalIgnoreCase);
            if (pos < 0)
                return string.Empty;
 
            int start = Math.Max(0, pos - 50);
            int end = Math.Min(content.Length, pos + Q.Length + 50);
            return content[start..end].Trim();
        }
 
        public class ResultItem
        {
            public string Title { get; set; } = "";
            public string Url { get; set; } = "";
            public string Snippet { get; set; } = "";
        }
    }
}
Можно проще, но главное почему не возвращает то что на сайте явно есть?
Миниатюры
Поиск страниц в проекте на Razor  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.07.2025, 10:40
Ответы с готовыми решениями:

Создание страниц в ASP проекте
День добрый! У меня довольно мудреная ситуация. Необходимо при нажатии Button создать отдельную...

В проекте выполняется асинхронная работа через Ajax перелистывание страниц возникает ошибка
В проекте перелистывание страниц выполнено асинхронным методом. При переходе на другую страницу в...

В созданном по шаблону проекте, почему то отсутствует конструктор для XAML страниц
Всем привет! Установил в Visual Studio 2022 шаблон Template Studio для WinUI. В созданном по...

9
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,218
21.07.2025, 11:18
Цитата Сообщение от mkpetrovich Посмотреть сообщение
но главное почему не возвращает то что на сайте явно есть?
Отладчиком умеете пользоваться?
0
Эксперт .NET
 Аватар для Usaga
14077 / 9294 / 1347
Регистрация: 21.01.2016
Сообщений: 34,890
21.07.2025, 11:20
Цитата Сообщение от mkpetrovich Посмотреть сообщение
Можно проще, но главное почему не возвращает то что на сайте явно есть?
Открой папку bin и посмотри, что там реально есть...
1
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,218
21.07.2025, 11:21
Цитата Сообщение от mkpetrovich Посмотреть сообщение
return hMatch.Success ? hMatch.Groups[1].Value : fileName;
Имя razor-файла никак не должно ассоциироваться с title-ом страницы.
В общем случае надо рендерить страницы, скармливая им все нужные модели, и по результату рендера уже искать.
1
Эксперт .NET
 Аватар для Usaga
14077 / 9294 / 1347
Регистрация: 21.01.2016
Сообщений: 34,890
21.07.2025, 11:21
А вообще, задумка ужасная - по исходникам проходиться.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,218
21.07.2025, 11:23
Если у вас просто статика, то да, так тоже сойдет.
0
3 / 2 / 1
Регистрация: 13.11.2024
Сообщений: 8
22.07.2025, 13:06  [ТС]
Прошу прощения и спасибо всем кто помог и направил, я по недосмотру забыл method="get" в форму вписать вот и все. Причем что обидно даже не выложил на форум эту часть кода. Что тут сказать)))

HTML5
1
2
3
4
5
6
7
8
9
10
11
                    <form class="d-flex ms-3" role="search" asp-page="/Search" method="get">
                        <input class="form-control me-2" type="search" name="q" placeholder="Search..." aria-label="Search">
                        <button class="btn btn-outline-success" type="submit">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-search" viewBox="0 0 16 16">
                                <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.397h-.001l3.85 3.85a1 1 0 0 0
                                1.415-1.414l-3.85-3.85zm-5.242 1.156a5.5 5.5 0 1
                                1 0-11 5.5 5.5 0 0 1 0 11z" />
                            </svg>
                        </button>
                    </form>
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,218
22.07.2025, 13:13
Вам ведь намекнули, что нету Pages директории в выходной папке проекта. Хотя в отладке это может еще и работает.
1
3 / 2 / 1
Регистрация: 13.11.2024
Сообщений: 8
22.07.2025, 13:21  [ТС]
Да вот как то так, до отладчика не дошел, перечитал все что внес в код в связи с поиском и порядок, нашел свой огрех) Кстати, сам поиск придется еще допиливать, так как не совсем релевантные вещи ищет и много мусора. Пока заткнул поиск обычным словарем, чтобы вообще страницы не проходить при поиске, благо там не статьи а просто калькуляторы с парой ключевых слов. Но в будущем, когда проект разрастется, это, конечно, нужно поменять. А вообще если метод гет добавить, поиск представленный выше работает, хоть и не совсем красиво)
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,218
22.07.2025, 13:31
Цитата Сообщение от mkpetrovich Посмотреть сообщение
Но в будущем, когда проект разрастется, это, конечно, нужно поменять.
В больших проектах типа CMS с динамическим контентом, этот самый контент хранится в базе и производится полнотекстовый поиск по нему.
Можно еще зайти со стороны sitemap или swagger-а, фильтруя все неообходимые endpoint-ы с последующим поиском по результату рендера.
Вообщем, решений может быть много с разной степенью пригодности.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.07.2025, 13:31
Помогаю со студенческими работами здесь

Где можно взять полную документацию по Razor-хелперам?
Подскажите где можна взять полную документацию по Razor - хелперах?

Подключение фотогалереи highslide на страницу cshtml (Razor MVC3)
http://highslide.com/editor/ Если подключаю на html страницу все работает &lt;html&gt; &lt;head&gt; ...

не выводятся абзацы в Html.DisplayFor() (Razor MVC3, C#)
string text = Model.IAText.Replace(&quot;\n&quot;, &quot;&lt;p&gt;&lt;p/&gt;&quot;); @Html.DisplayFor(i =&gt; text).ToHtmlString(); ...

Вызов частичного представления из обычного mvc razor
Всем доброго времени суток. Недавно начал работать с Razor. Задача - вызвать частичное...

Не могу разобраться с Razor.
Здрасти! Разница между MVC и Razor заключатеся в том, что код по разному выделяется на сколько я...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru