ASP.NET MVC logika w modelu?

0

Witam, miałem za zadanie zrobić prostą aplikację webową która miała wypisywać odpowiednie komunikaty, zależne od wartości wprowadzonej w formularzu. Instrukcje warunkowe które sprawdzają co trzeba wypisać napisałem w kontrolerze, lecz dowiedziałem się że "logikę" pisze się w modelu. Czy to prawda? Jeśli tak, to w jaki sposób mam w modelu sprawdzać co wypisać?

Index.cshtml

@model Zadanie1CEZ.Models.Wartosc

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    @using (Html.BeginForm())
    {
        <p>Podaj liczbę: @Html.TextBoxFor(x => x.tekst)</p>

        <input type="submit" value="Wyślij liczbę" />
    }

</body>
</html>

Wartosc.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Zadanie1CEZ.Models
{
    public class Wartosc
    {
        public string tekst { get; set; }
    }
}

FizzBuzzControler.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Zadanie1CEZ.Models;

namespace Zadanie1CEZ.Controllers
{
    public class FizzBuzzController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public string Index(Wartosc wartosc)
        {

            

           

            if (Convert.ToInt32(wartosc.tekst) > 100 || Convert.ToInt32(wartosc.tekst) < 1)
            {
                return "Liczba nie jest z określonego przedziału, czyli <1,100>";
            }

            if ((Convert.ToInt32(wartosc.tekst) % 3) == 0 && (Convert.ToInt32(wartosc.tekst) % 5) == 0)
            {
                return "FizzBuzz";
            }

            if ((Convert.ToInt32(wartosc.tekst) % 3) == 0)
            {
                return "Fizz";
            }

            if ((Convert.ToInt32(wartosc.tekst) % 5) == 0)
            {
                return "Buzz";
            }




            return wartosc.tekst + " (Czyli niepodzielna ani przez 3 ani 5)";

        }
    }
}
1

Możesz od razu przesłać inta lub int?, aby uniknąć tego Converta lub chociaż zrobić go raz, a nie w 30 miejscach.

Jeżeli chodzi o walidacje formularzy to zainteresuj się FluentValidation

0

Zmieniłem na coś takiego, całą logikę dałem do modelu:

Wartosc.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Zadanie1CEZ.Models
{
    public class Wartosc
    {
        public string tekst { get; set; }

        public string wypisz()
        {
            int result;
            bool succes = Int32.TryParse(tekst, out result);

            if (!succes)
            {
                return "Wprowadzono nieprawidłowy format danych. Podaj liczbę całkowitą";
            }

            int liczba = Convert.ToInt32(tekst);

            if (liczba > 100 || liczba < 1)
            {
                return "Liczba nie jest z określonego przedziału, czyli <1,100>";
            }

            if ((liczba % 3) == 0 && (liczba % 5) == 0)
            {
                return "FizzBuzz";
            }

            if ((liczba % 3) == 0)
            {
                return "Fizz";
            }

            if ((liczba % 5) == 0)
            {
                return "Buzz";
            }




            return tekst + " (Czyli niepodzielna ani przez 3 ani 5)";
        }
    }
}

kontroler:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Zadanie1CEZ.Models;

namespace Zadanie1CEZ.Controllers
{
    public class FizzBuzzController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public string Index(Wartosc wartosc)
        {

            return wartosc.wypisz();

        }
    }
}
1

Już prędzej poszedłbym w wydzielenie jakiejś klasy MyBusinessLogic, która byłaby podawana do kontrolera przez Dependency Injection i w niej wykonywał tego typu operacje, a rezultat zwracał do kontrolera, a następnie do usera.

1

Ustalmy fakty. Model danych czy model domenowy to zupełnie coś innego niż model w rozumieniu MVC. W kontekście MVC model jest domeną aplikacji i to tam rzeczywiście powinna się znajdować logika. Zadaniem kontrolera jest wykonanie odpowiedniej logiki i zwrócenie widoku. Zatem twoja klasa Wartosc to zwykłe DTO i nie powinno tam być logiki. Stwórz klasę odpowiedzialną za tę konkretną operację biznesową, w parametrze przekazuj czego potrzebujesz i zwracaj DTO.

3

Trochę się pogubiłem. Mógłbyś to na jakimś przykładzie wyjaśnić?

Na początek zdefiniuj DTO, które będzie reprezentować twój request oraz response.

public class FizzBuzzRequestDTO
{
	public string Text { get; set; }
}

public class FizzBuzzResultDTO
{
	public FizzBuzzResultDTO(string text)
	{
		Text = text;
	}

	public string Text { get; }
}

Opisz swoją logikę w jakimś serwisie.

public class FizzBuzzService
{
	public FizzBuzzResultDTO Validate(FizzBuzzRequestDTO request)
	{
		// tutaj walidacja i twoja logika

		return new FizzBuzzResultDTO("Wynik operacji");
	}
}

W kontrolerze wykorzystaj nowo utworzony serwis.

public class FizzBuzzController : Controller
{
	[HttpPost]
	public string Index(FizzBuzzRequestDTO request)
	{
		var service = new FizzBuzzService();

		FizzBuzzResultDTO result = service.Validate(request);

		return View(result);
	}
}

Tak w uproszczeniu. W kontekście MVC twoim modelem teraz jest cała domena odpowiedzialna za wykonanie tej operacji czyli FizzBuzzService, FizzBuzzRequestDTO oraz FizzBuzzResultDTO. Zadaniem kontrolera jest tylko i wyłącznie przesterowanie do odpowiedniej logiki, pobranie wyniku i zwrócenie widoku do klienta.

1 użytkowników online, w tym zalogowanych: 0, gości: 1