Как правильно реализовать классы C# с использованием ASP.NET Core MVC?

Задача — создать веб-приложение ASP.NET Core MVC, имеющее классы Student и StudentWorker. Затем вы просите пользователя ввести информацию для объекта StudentWorker (идентификатор, имя, почасовую оплату и отработанное время). Вы выводите еженедельную зарплату (часовая оплата * часы работы) в представление, следя за тем, чтобы почасовая оплата находилась в диапазоне (7,25–14,75), а количество отработанных часов – в диапазоне (1–15).

Я без проблем создал классы Student и StudentWorker, а также представление (по большей части). Я почти уверен, что большая часть проблем кроется в контроллере. Мне сложно понять структуру ASP.NET Core MVC, и я просто пытаюсь завершить этот класс C#.

Я перечислю файлы проекта ниже:

Классы моделей:

namespace FinalProject.Models
{
    public class Student
    {
        // Private fields
        private int id;
        private string name;

        // Public property for ID
        public int ID
        {
            get { return id; }
            set { id = value; }
        }

        // Public property for Name
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        // Constructors
        public Student(int id, string name)
        {
            this.id = id;
            this.name = name;
        }

        // Default constructor (demonstrates method overloading)
        public Student()
        {
            id = 0;
            name = "";
        }

        // Method to display student information (overrides default ToString method)
        public override string ToString()
        {
            return ($"ID: {ID}, Name: {Name}");
        }
    }

    public class StudentWorker : Student
    {
        // Private fields
        private double hourlyPay;
        private int hoursWorked;

        // Public property for HourlyPay
        public double HourlyPay
        {
            get { return hourlyPay; }
            set
            {
                if (value >= 7.25 && value <= 14.75)
                    hourlyPay = value;
                else
                    hourlyPay = 0;
            }
        }

        // Public property for HoursWorked
        public int HoursWorked
        {
            get { return hoursWorked; }
            set
            {
                if (value >= 1 && value <= 15)
                    hoursWorked = value;
                else
                    hoursWorked = 0;
            }
        }

        // Constructor
        public StudentWorker(int id, string name, double hourlyPay, int hoursWorked)
                    : base(id, name)
        {
            HourlyPay = hourlyPay;
            HoursWorked = hoursWorked;
        }

        // Default constructor (demonstrates method overloading)
        public StudentWorker() : base()
        {
            HourlyPay = 0;
            HoursWorked = 0;
        }

        // Method to calculate weekly salary
        public double WeeklySalary()
        {
            if (HourlyPay == 0 || HoursWorked == 0)
                return 0;

            return HourlyPay * HoursWorked;
        }

        // Method to display student worker information (overrides default ToString method)
        public override string ToString()
        {
            return ($"ID: {ID}, Name: {Name}, Hourly Pay: {HourlyPay:C}, Hours Worked: {HoursWorked}, Weekly Salary: {WeeklySalary():C}");
        }
    }
}

Вид

@model FinalProject.Models.StudentWorker

@{
    ViewBag.Title = "Create Student Worker";
}
<html>
<head>
    <title>Student Worker</title>
    <link rel = "stylesheet" href = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>

<h2>Create Student Worker</h2>

<form asp-action = "Index" method = "post">
    <div class = "form-group">
        <label asp-for = "ID" class = "control-label">Student ID</label>
        <input asp-for = "ID" class = "form-control" />
        <span asp-validation-for = "ID" class = "text-danger"></span>
    </div>
    <div class = "form-group">
        <label asp-for = "Name" class = "control-label">Student Name</label>
        <input asp-for = "Name" class = "form-control" />
        <span asp-validation-for = "Name" class = "text-danger"></span>
    </div>
    <div class = "form-group">
        <label asp-for = "HourlyPay" class = "control-label">Hourly Pay</label>
        <input asp-for = "HourlyPay" class = "form-control" />
        <span asp-validation-for = "HourlyPay" class = "text-danger"></span>
    </div>
    <div class = "form-group">
        <label asp-for = "HoursWorked" class = "control-label">Hours Worked</label>
        <input asp-for = "HoursWorked" class = "form-control" />
        <span asp-validation-for = "HoursWorked" class = "text-danger"></span>
    </div>
    <button type = "submit" class = "btn btn-primary">Calculate Weekly Salary</button>
</form>


@if (ViewBag.WeeklySalary != null)
{
    <h3>Weekly Salary: @ViewBag.WeeklySalary</h3>
}

</body>
</html>

Контроллер

using FinalProject.Models;
using Microsoft.AspNetCore.Mvc;

namespace FinalProject.Controllers
{
    public class HomeController : Controller
    {
        // GET: StudentWorker/Create
        public IActionResult Index()
        {
            return View();
        }

        // POST: StudentWorker/Create
        [HttpPost]
        public IActionResult Index(StudentWorker model)
        {
            if (ModelState.IsValid)
            {
                // Calculate weekly salary
                var weeklySalary = model.WeeklySalary();
                ViewBag.WeeklySalary = weeklySalary;

                // Return view with the weekly salary
                return View(model);
            }

            // If model state is not valid, redisplay the form
            return View(model);
        }
    }
}

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

«...большинство проблем...», «...кажется, ничего не делает...» Вы сказали, чего пытаетесь достичь, и опубликовали код (хотя это довольно много и минимальный воспроизводимый пример было бы лучше), но вы не сказали, что делает этот код по сравнению с тем, что вы ожидаете от него.

gunr2171 22.07.2024 23:30

Добавьте точки останова в контроллер и посмотрите, доберетесь ли вы до точек останова. Вы устанавливаете HTTP-соединение, в котором есть клиент и сервер. Контроллер — это серверный код. Вы делаете HTTP-запрос от клиента и используете [HttpPost], который указывает, что запрос имеет тело. Я не вижу клиентского кода, в котором делается запрос. Вам нужно проверить ответ на запрос и посмотреть, какой статус возвращается. Обычно хороший ответ будет содержать 200 ОК, а ошибка обычно будет иметь статус 400/500.

jdweng 22.07.2024 23:34

@jdweng Я добавил точки останова, чтобы увидеть, что происходит со значениями переменных-членов в моем классе StudetWorker, и кажется, что ни одной из них не присваивается значение, которое я ввожу, когда я запускаю веб-приложение. Я не знаю, как должен выглядеть мой контроллер. Прямо сейчас у меня нет никаких упоминаний об идентификаторе, имени, HourlyPay или HoursWorked в контроллере, который, как я предполагаю, необходимо там реализовать, я использовал ChatGPT, чтобы помочь мне, к вашему сведению. Я могу заставить веб-приложение работать нормально и вводить значения. Проблема в том, что моим переменным-членам не присваиваются эти значения.

Nedmac624 23.07.2024 01:09

В .NET мы обычно не пишем класс так, как вы. Вместо этого мы пишем так: ` public string Name { get; набор; }` затем, когда вы отправите значение из значения, попробуйте извлечь значение из параметра запроса и привязать его к своей модели. Вот как вам следует работать.

Md Farid Uddin Kiron 23.07.2024 03:13

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

jdweng 23.07.2024 11:53

@jdweng Я не понимаю сериализацию, я новичок в веб-разработке.

Nedmac624 23.07.2024 17:18

Вам не нужно сериализовать. Вы можете сделать HTTP-заголовок Content-Type клиентского запроса «text/html», а затем добавить HTML в тело запроса. Затем контроллер на сервере автоматически обработает данные HTML.

jdweng 23.07.2024 17:55

Я не понимаю, что вы просите меня сделать. Где мне это сделать, в представлении? Я не знаю, как это реализовать. Я новичок в веб-приложениях, и мой профессор не очень хорошо объяснил, как все работает.

Nedmac624 23.07.2024 20:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я почти уверен, что большинство проблем связано с контроллером. МВК Мне сложно понять структуру ASP.NET, и я просто пытаюсь завершить этот курс C#.

На основе вашего общего кода в ядре .NET или asp.net или даже на C# мы пишем классы с ​​чистыми атрибутами получения и установки, а не так, как вы. Таким образом, вы не получаете ожидаемого результата, который ищете.

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

В дополнение к этому вы также можете написать метод расчета оплаты внутри этого класса. Наконец, верните рассчитанное значение в представление, если проверка прошла успешно.

Давайте посмотрим на практике, как мы можем реализовать это более чистым способом.

Модель:

public class Student
{
    [Required]
    public int ID { get; set; }

    [Required]
    [StringLength(100)]
    public string Name { get; set; }
}

public class StudentWorker : Student
{
    [Required]
    [Range(7.25, 14.75, ErrorMessage = "Hourly pay must be between $7.25 and $14.75")]
    public double HourlyPay { get; set; }

    [Required]
    [Range(1, 15, ErrorMessage = "Hours worked must be between 1 and 15")]
    public int HoursWorked { get; set; }

    public double WeeklySalary()
    {
        return HourlyPay * HoursWorked;
    }
}

Контроллер:

public class StudentWorkerController : Controller
{
    [HttpGet]
    public IActionResult Index()
    {
        return View(new StudentWorker());
    }

    [HttpPost]
    public IActionResult CalculatePayment(StudentWorker model)
    {
        if (ModelState.IsValid)
        {
            ViewBag.WeeklySalary = model.WeeklySalary();
        }
        return View("Index");
    }
}

Вид:

@model StudentWorker

@{
    ViewBag.Title = "Create Student Worker";
}
<div class = "container">
    <h2>Create Student Worker</h2>

    <form asp-action = "CalculatePayment" method = "post">
        <div class = "form-group">
            <label asp-for = "ID" class = "control-label">Student ID</label>
            <input asp-for = "ID" class = "form-control" />
            <span asp-validation-for = "ID" class = "text-danger"></span>
        </div>
        <div class = "form-group">
            <label asp-for = "Name" class = "control-label">Student Name</label>
            <input asp-for = "Name" class = "form-control" />
            <span asp-validation-for = "Name" class = "text-danger"></span>
        </div>
        <div class = "form-group">
            <label asp-for = "HourlyPay" class = "control-label">Hourly Pay</label>
            <input asp-for = "HourlyPay" class = "form-control" />
            <span asp-validation-for = "HourlyPay" class = "text-danger"></span>
        </div>
        <div class = "form-group">
            <label asp-for = "HoursWorked" class = "control-label">Hours Worked</label>
            <input asp-for = "HoursWorked" class = "form-control" />
            <span asp-validation-for = "HoursWorked" class = "text-danger"></span>
        </div>
        <button type = "submit" class = "btn btn-primary">Calculate Weekly Salary</button>
    </form>

    @if (ViewBag.WeeklySalary != null)
    {
        <h3>Weekly Salary: $ @ViewBag.WeeklySalary</h3>
    }
</div>

Упате:

Структура проекта:

Имейте в виду, что Middleware, Enum, Services — это моя персональная папка.

Контроллер:

Модель:

Вид:

Файлы Program.cs используются по умолчанию при создании проекта. И маршрутизация также используется по умолчанию, как показано ниже:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
  
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Выход:

Примечание. Приведенный выше образец обозначает одно из приложений в ядре asp.net. Однако есть и несколько других способов. Если вы хотите знать, пожалуйста обратитесь к этому официальному документу для проверки модели. и дополнительный образец.

Это все еще не работает. Я получаю следующую ошибку: Эта страница не работает. Если проблема не исчезнет, ​​обратитесь к владельцу сайта. HTTP ОШИБКА 405. Когда я запускаю его в режиме отладки, он даже не достигает точек останова. Я предполагаю, что это потому, что когда я нажимаю «Рассчитать еженедельную зарплату», я получаю это сообщение об ошибке.

Nedmac624 23.07.2024 20:33

Согласно сообщению об ошибке 405, ваш метод запроса формы отправки и HTTP-глагол метода контроллера (GET, POST) не совпадают. Пожалуйста, проверьте еще раз, если они верны, а также проверьте определение класса. Проверьте трассировку сети браузера, это даст вам более подробную информацию. Кроме того, если вы напрямую скопируете и вставите мой код, он будет работать нормально, как только вы сможете заставить его работать, вы сможете начать рефакторинг своего кода.

Md Farid Uddin Kiron 24.07.2024 03:11

Я думаю, проблема в именах файлов и их расположении. Можете ли вы показать мне свой обозреватель решений с развернутыми папками? Я знаю, что почти у цели, потому что я провел еще несколько исследований. и я лучше понимаю MVC. Кроме того, как выглядит нижняя часть вашего Progam.cs? (поскольку именно там находится маршрут)

Nedmac624 24.07.2024 04:40

Это обычный основной проект MVC asp.net, версия .NET была 8, и я обновлю ответ, добавив снимок экрана проекта и файл progra.cs. Обычно контроллер должен находиться в папке контроллера, а представления — в папке представления.

Md Farid Uddin Kiron 24.07.2024 04:58

Спасибо :)

Nedmac624 24.07.2024 05:03

Проверьте обновленный ответ, дайте мне знать, если вы смогли решить.

Md Farid Uddin Kiron 24.07.2024 05:09

Наконец-то я заработал!!! Мне пришлось внести некоторые изменения, и мой файл Program.cs на самом деле отличается от вашего. Спасибо за всю вашу помощь, я так рад! :)

Nedmac624 24.07.2024 05:35

Я рад узнать, что вы смогли решить эту проблему.

Md Farid Uddin Kiron 24.07.2024 05:39

Другие вопросы по теме