Задача — создать веб-приложение 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, но, похоже, это ничего не дало. Опять же, я не знаком с написанием веб-приложений и буду очень признателен за любую помощь :)
Добавьте точки останова в контроллер и посмотрите, доберетесь ли вы до точек останова. Вы устанавливаете HTTP-соединение, в котором есть клиент и сервер. Контроллер — это серверный код. Вы делаете HTTP-запрос от клиента и используете [HttpPost], который указывает, что запрос имеет тело. Я не вижу клиентского кода, в котором делается запрос. Вам нужно проверить ответ на запрос и посмотреть, какой статус возвращается. Обычно хороший ответ будет содержать 200 ОК, а ошибка обычно будет иметь статус 400/500.
@jdweng Я добавил точки останова, чтобы увидеть, что происходит со значениями переменных-членов в моем классе StudetWorker, и кажется, что ни одной из них не присваивается значение, которое я ввожу, когда я запускаю веб-приложение. Я не знаю, как должен выглядеть мой контроллер. Прямо сейчас у меня нет никаких упоминаний об идентификаторе, имени, HourlyPay или HoursWorked в контроллере, который, как я предполагаю, необходимо там реализовать, я использовал ChatGPT, чтобы помочь мне, к вашему сведению. Я могу заставить веб-приложение работать нормально и вводить значения. Проблема в том, что моим переменным-членам не присваиваются эти значения.
В .NET мы обычно не пишем класс так, как вы. Вместо этого мы пишем так: ` public string Name { get; набор; }` затем, когда вы отправите значение из значения, попробуйте извлечь значение из параметра запроса и привязать его к своей модели. Вот как вам следует работать.
Ваш клиент должен сериализовать студента и добавить сериализованные данные в тело запроса (сообщение). Затем контроллер должен десериализовать тело запроса, которым является студент (модель). Проверьте клиентский код, чтобы убедиться, что данные помещаются в модель и сериализуются.
@jdweng Я не понимаю сериализацию, я новичок в веб-разработке.
Вам не нужно сериализовать. Вы можете сделать HTTP-заголовок Content-Type клиентского запроса «text/html», а затем добавить HTML в тело запроса. Затем контроллер на сервере автоматически обработает данные HTML.
Я не понимаю, что вы просите меня сделать. Где мне это сделать, в представлении? Я не знаю, как это реализовать. Я новичок в веб-приложениях, и мой профессор не очень хорошо объяснил, как все работает.





Я почти уверен, что большинство проблем связано с контроллером. МВК Мне сложно понять структуру 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. Когда я запускаю его в режиме отладки, он даже не достигает точек останова. Я предполагаю, что это потому, что когда я нажимаю «Рассчитать еженедельную зарплату», я получаю это сообщение об ошибке.
Согласно сообщению об ошибке 405, ваш метод запроса формы отправки и HTTP-глагол метода контроллера (GET, POST) не совпадают. Пожалуйста, проверьте еще раз, если они верны, а также проверьте определение класса. Проверьте трассировку сети браузера, это даст вам более подробную информацию. Кроме того, если вы напрямую скопируете и вставите мой код, он будет работать нормально, как только вы сможете заставить его работать, вы сможете начать рефакторинг своего кода.
Я думаю, проблема в именах файлов и их расположении. Можете ли вы показать мне свой обозреватель решений с развернутыми папками? Я знаю, что почти у цели, потому что я провел еще несколько исследований. и я лучше понимаю MVC. Кроме того, как выглядит нижняя часть вашего Progam.cs? (поскольку именно там находится маршрут)
Это обычный основной проект MVC asp.net, версия .NET была 8, и я обновлю ответ, добавив снимок экрана проекта и файл progra.cs. Обычно контроллер должен находиться в папке контроллера, а представления — в папке представления.
Спасибо :)
Проверьте обновленный ответ, дайте мне знать, если вы смогли решить.
Наконец-то я заработал!!! Мне пришлось внести некоторые изменения, и мой файл Program.cs на самом деле отличается от вашего. Спасибо за всю вашу помощь, я так рад! :)
Я рад узнать, что вы смогли решить эту проблему.
«...большинство проблем...», «...кажется, ничего не делает...» Вы сказали, чего пытаетесь достичь, и опубликовали код (хотя это довольно много и минимальный воспроизводимый пример было бы лучше), но вы не сказали, что делает этот код по сравнению с тем, что вы ожидаете от него.