Создаем проект


Iseseisvad harjutused:
- Tee juhuslike numbrite generaator (või Random rand = new Random() abil) – sisestades otspunktile kaks arvu, tagastab programm juhusliku arvu nende vahel
- Sisesta sünniaasta otspunktile ning programm tagastab sulle lause, mis ütleb: “oled nii või naa aastat vana (arvutuslikult korrektselt), olenevalt kas sellel aastal on sünnipäev juba olnud”
Создаем новый файл PrimitiividController.cs:


И вписываем код в данный контроллер
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace veebMiljukova.Controllers
{
[Route("[controller]")]
[ApiController]
public class PrimitiividController : ControllerBase
{
// GET: primitiivid/hello-world
[HttpGet("hello-world")]
public string HelloWorld()
{
return "Hello world at " + DateTime.Now;
}
// GET: primitiivid/hello-variable/mari
[HttpGet("hello-variable/{nimi}")]
public string HelloVariable(string nimi)
{
return "Hello " + nimi;
}
// GET: primitiivid/add/5/6
[HttpGet("add/{nr1}/{nr2}")]
public int AddNumbers(int nr1, int nr2)
{
return nr1 + nr2;
}
// GET: primitiivid/multiply/5/6
[HttpGet("multiply/{nr1}/{nr2}")]
public int Multiply(int nr1, int nr2)
{
return nr1 * nr2;
}
// GET: primitiivid/do-logs/5
[HttpGet("do-logs/{arv}")]
public void DoLogs(int arv)
{
for (int i = 0; i < arv; i++)
{
Console.WriteLine("See on logi nr " + i);
}
}
// GET: primitiivid/random-number/10/20
[HttpGet("random-number/{min}/{max}")]
public int GetRandomNumber(int min, int max)
{
Random rand = new Random();
return rand.Next(min, max + 1);
}
// GET: primitiivid/vanus/1990
[HttpGet("vanus/{synniaasta}")]
public string GetVanus(int synniaasta)
{
int currentYear = DateTime.Now.Year;
int currentMonth = DateTime.Now.Month;
int currentDay = DateTime.Now.Day;
int vanus = currentYear - synniaasta;
bool synnipaevOnJubaOlnud = currentMonth > 10 || (currentMonth == 10 && currentDay >= 9);
if (!synnipaevOnJubaOlnud)
{
vanus--;
}
return "Oled " + vanus + " aastat vana.";
}
}
}

Рассмотрение функций:

Hello world at
” с датой и временем использовании функции




Создаем папку Models и создаем в ней файл Toode.cs, Kasutaja.cs :
Toode.cs
namespace veebMiljukova.Models
{
public class Toode
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public bool IsActive { get; set; }
public Toode(int id, string name, double price, bool isActive)
{
Id = id;
Name = name;
Price = price;
IsActive = isActive;
}
}
}
Kasutaja.cs
namespace veebMiljukova.Models
{
public class Kasutaja
{
public int Id { get; set; }
public string Kasutajanimi { get; set; }
public string Parool { get; set; }
public string Eesnimi { get; set; }
public string Perenimi { get; set; }
public Kasutaja(int id, string kasutajanimi, string parool, string eesnimi, string perenimi)
{
Id = id;
Kasutajanimi = kasutajanimi;
Parool = parool;
Eesnimi = eesnimi;
Perenimi = perenimi;
}
}
}
Создадим новый контроллер ToodeController.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using veebMiljukova.Models;
namespace veebMiljukova.Controllers
{
[Route("[controller]")]
[ApiController]
public class ToodeController : ControllerBase
{
private static Toode _toode = new Toode(1, "Koola", 1.5, true);
// GET: toode
[HttpGet]
public Toode GetToode()
{
return _toode;
}
// GET: toode/muuda-aktiivsust
[HttpGet("muuda-aktiivsust")]
public Toode MuudaAktiivsust()
{
_toode.IsActive = !_toode.IsActive;
return _toode;
}
// GET: toode/muuda-nime/{uusNimi}
[HttpGet("muuda-nime/{uusNimi}")]
public Toode MuudaNime(string uusNimi)
{
_toode.Name = uusNimi;
return _toode;
}
// GET: toode/muuda-hinda-kordajaga/{kordaja}
[HttpGet("muuda-hinda-kordajaga/{kordaja}")]
public Toode MuudaHindaKordajaga(double kordaja)
{
_toode.Price *= kordaja;
return _toode;
}
}
}




Создадим новый контроллер ToodedController.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using veebMiljukova.Models;
namespace veebMiljukova.Controllers;
[ApiController]
[Route("[controller]")]
public class TootedController : ControllerBase // Peab pärima ControllerBase
{
private static List<Toode> _tooted = new List<Toode>{
new Toode(1,"Koola", 1.5, true),
new Toode(2,"Fanta", 1.0, false),
new Toode(3,"Sprite", 1.7, true),
new Toode(4,"Vichy", 2.0, true),
new Toode(5,"Vitamin well", 2.5, true)
};
// https://localhost:7052/tooted
[HttpGet]
public List<Toode> Get()
{
return _tooted;
}
// API otspunkt, mis kustutab korraga kõik tooted
[HttpGet("kustuta-koik")]
public List<Toode> KustutaKoik()
{
_tooted.Clear();
return _tooted; // Tagastab tühja nimekirja
}
// API otspunkt, mis muudab kõikide toodete aktiivsuse väära peale
[HttpGet("muuda-koik-inaktiivseks")]
public List<Toode> MuudaKoikInaktiivseks()
{
foreach (var toode in _tooted)
{
toode.IsActive = false;
}
return _tooted; // Tagastab uuendatud nimekirja
}
// API otspunkt, mis tagastab ühe toote vastavalt järjekorranumbrile
[HttpGet("toode/{index}")]
public ActionResult<Toode> GetToodeByIndex(int index)
{
if (index < 0 || index >= _tooted.Count)
{
return NotFound("Toode ei leitud!"); // Kasutab NotFound() meetodit
}
return _tooted[index];
}
// API otspunkt, mis tagastab kõige suurema hinnaga toote
[HttpGet("kalleim-toode")]
public Toode GetKalleimToode()
{
Toode kalleimToode = _tooted.OrderByDescending(t => t.Price).FirstOrDefault();
return kalleimToode;
}
// Varasemad otspunktid
[HttpDelete("kustuta/{index}")]
public List<Toode> Delete(int index)
{
_tooted.RemoveAt(index);
return _tooted;
}
[HttpGet("kustuta2/{index}")]
public string Delete2(int index)
{
_tooted.RemoveAt(index);
return "Kustutatud!";
}
[HttpPost("lisa/{id}/{nimi}/{hind}/{aktiivne}")]
public List<Toode> Add(int id, string nimi, double hind, bool aktiivne)
{
Toode toode = new Toode(id, nimi, hind, aktiivne);
_tooted.Add(toode);
return _tooted;
}
//[HttpGet("lisa")]
//public List<Toode> Add2([FromQuery] int id, [FromQuery] string nimi, [FromQuery] double hind, [FromQuery] bool aktiivne)
//{
// Toode toode = new Toode(id, nimi, hind, aktiivne);
// _tooted.Add(toode);
// return _tooted;
//}
//[HttpPost("lisa")]
//public List<Toode> Add([FromBody] Toode toode)
//{
// _tooted.Add(toode);
// return _tooted;
//}
[HttpGet("hind-dollaritesse/{kurss}")]
public List<Toode> Dollaritesse(double kurss)
{
for (int i = 0; i < _tooted.Count; i++)
{
_tooted[i].Price = _tooted[i].Price * kurss;
}
return _tooted;
}
[HttpGet("hind-dollaritesse2/{kurss}")]
public List<Toode> Dollaritesse2(double kurss)
{
foreach (var t in _tooted)
{
t.Price = t.Price * kurss;
}
return _tooted;
}
}










Создадим новый контроллер KasutajadController.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using veebMiljukova.Models;
namespace veebMiljukova.Controllers;
[ApiController]
[Route("[controller]")]
public class KasutajadController : ControllerBase
{
private static List<Kasutaja> _kasutajad = new List<Kasutaja>
{
new Kasutaja(1, "Lisadevil", "1234lisa", "Lisa", "Paulk"),
new Kasutaja(2, "Madler", "adler@234", "Mark", "Adler"),
new Kasutaja(3, "Moon", "lillyhk", "Lilly", "Hikkimo")
};
// https://localhost:7052/kasutajad
[HttpGet]
public List<Kasutaja> Get()
{
return _kasutajad;
}
// API otspunkt, mis kustutab kõik kasutajad
[HttpGet("kustuta-koik")]
public List<Kasutaja> KustutaKoik()
{
_kasutajad.Clear();
return _kasutajad; // Tagastab tühja nimekirja
}
// API otspunkt, mis tagastab ühe kasutaja vastavalt järjekorranumbrile
[HttpGet("kasutaja/{index}")]
public ActionResult<Kasutaja> GetKasutajaByIndex(int index)
{
int adjustedIndex = index - 1;
if (adjustedIndex < 0 || adjustedIndex >= _kasutajad.Count)
{
return NotFound("Kasutaja ei leitud!");
}
return _kasutajad[adjustedIndex];
}
// API otspunkt, mis lisab kasutaja
[HttpPost("lisa")]
public List<Kasutaja> Add([FromBody] Kasutaja kasutaja)
{
_kasutajad.Add(kasutaja);
return _kasutajad;
}
// API otspunkt, mis eemaldab kasutaja järjekорранумбри järgi
[HttpGet("kustuta/{index}")]
public List<Kasutaja> Delete(int index)
{
int adjustedIndex = index - 1;
if (adjustedIndex < 0 || adjustedIndex >= _kasutajad.Count)
{
return _kasutajad;
}
_kasutajad.RemoveAt(adjustedIndex);
return _kasutajad;
}
// API otspunkt, mis muudab kasutaja andmeid
[HttpPost("muuda/{index}")]
public ActionResult<List<Kasutaja>> Muuda(int index, [FromBody] Kasutaja uusKasutaja)
{
int adjustedIndex = index - 1;
if (adjustedIndex < 0 || adjustedIndex >= _kasutajad.Count)
{
return NotFound("Kasutaja ei leitud!");
}
_kasutajad[adjustedIndex] = uusKasutaja;
return _kasutajad;
}
}






Если у вас не установлен Node.js, то устанавливаем
В дальнейшем мы переходим работать в VScode/PHPShtorm (для удобства взяла PHPShtorm)
Заходим в терминал, желательно в одной папке где находится наш проект, должно примерно выглядеть так:



Команды, которые вводились в терминал:
npx create-react-app frontend //создаем папку frontend
cd frontend //переходим в созданную папку
npm start //используется для запуска react
Запускаем проект в PHPShtorm
Переходим в файл App.js и вписываем код ниже
Учитываем, что данную строку
http://localhost:5256/Tooted/kustuta/
Нужно изменить “5256” на свои числа, которые есть в ссылке в backend
import { useEffect, useRef, useState } from 'react';
import './App.css';
function App() {
const [tooted, setTooted] = useState([]);
const idRef = useRef();
const nameRef = useRef();
const priceRef = useRef();
const isActiveRef = useRef();
const [isUsd, setUsd] = useState(false);
useEffect(() => {
fetch("http://localhost:5256/Tooted")
.then(res => res.json())
.then(json => setTooted(json));
}, []);
function kustuta(index) {
fetch("http://localhost:5256/Tooted/kustuta/" + index, {"method": "DELETE"})
.then(res => res.json())
.then(json => setTooted(json));
}
function lisa() {
const uusToode = {
"id": Number(idRef.current.value),
"name": nameRef.current.value,
"price": Number(priceRef.current.value),
"isActive": isActiveRef.current.checked
}
fetch(`http://localhost:5256/Tooted/lisa/${idRef.current.value}/${nameRef.current.value}/${priceRef.current.value}/${isActiveRef.current.checked}`, {"method": "POST", "body": JSON.stringify(uusToode)})
.then(res => res.json())
.then(json => setTooted(json));
}
function dollariteks() {
const kurss = 1.1;
setUsd(true);
fetch("http://localhost:5256/Tooted/hind-dollaritesse/" + kurss, {"method": "PATCH"})
.then(res => res.json())
.then(json => setTooted(json));
}
function eurodeks() {
const kurss = 0.9091;
setUsd(false);
fetch("http://localhost:5256/Tooted/hind-dollaritesse/" + kurss)
.then(res => res.json())
.then(json => setTooted(json));
}
return (
<div className="App">
<label>ID</label> <br />
<input ref={idRef} type="number" /> <br />
<label>Nimi</label> <br />
<input ref={nameRef} type="text" /> <br />
<label>Hind</label> <br />
<input ref={priceRef} type="number" /> <br />
<label>Aktiivne</label> <br />
<input ref={isActiveRef} type="checkbox" /> <br />
<button onClick={() => lisa()}>Lisa</button>
{tooted.map((toode, index) =>
<div>
<div>{toode.id}</div>
<div>{toode.name}</div>
<div>{toode.price}</div>
<button onClick={() => kustuta(index)}>x</button>
</div>)}
{isUsd === false && <button onClick={() => dollariteks()}>Muuda dollariteks</button>}
{isUsd === true && <button onClick={() => eurodeks()}>Muuda eurodeks</button>}
</div>
);
}
export default App;
Чтобы frontend работал полностью, нужно чтобы был запущен проект в visual studio

Далее мы переходим работать в postman
При отправке тела в Postman используйте http://localhost:4444/lisa в качестве конечной точки API, нажмите «body» -> «raw» -> «json» и введите тело запроса в следующей форме:
{
"id": 321,
"name": "Red bull",
"price": 7,
"isActive": true
}

Нажимаем на send и получаем результат добавления

Создаем новый контроллер ParcelMachineController.cs и прописываем данный код
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace veebMiljukova.Controllers
{
[Route("[controller]")]
[ApiController]
public class ParcelMachineController : ControllerBase
{
private readonly HttpClient _httpClient;
public ParcelMachineController(HttpClient httpClient)
{
_httpClient = httpClient;
}
[HttpGet("Omniva")]
public async Task<IActionResult> GetParcelMachinesOmniva()
{
var response = await _httpClient.GetAsync("https://www.omniva.ee/locations.json");
var responseBody = await response.Content.ReadAsStringAsync();
return Content(responseBody, "application/json");
}
//не работает сайт с расположениями
[HttpGet("Smartpost")]
public async Task<IActionResult> GetParcelMachinesSmartPost()
{
var response = await _httpClient.GetAsync("https://www.smartpost.ee/places.json");
var responseBody = await response.Content.ReadAsStringAsync();
return Content(responseBody, "application/json");
}
}
}
Дополняем Program.cs
builder.Services.AddHttpClient();
В App.js вставляем код, вместо нашего кода и тоже меняем порт
import { useEffect, useState } from 'react';
import './App.css';
function App() {
const [pakiautomaadid, setPakiautomaadid] = useState([]);
useEffect(() => {
fetch("http://localhost:5256/parcelmachine")
.then(res => res.json())
.then(json => setPakiautomaadid(json));
}, []);
return (
<div className="App">
<select>
{pakiautomaadid.map(automaat =>
<option>
{automaat.NAME}
</option>)}
</select>
</div>
);
}
export default App;

Создаем новый контроллер NordpoolController.cs
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace veebMiljukova.Controllers
{
[Route("[controller]")]
[ApiController]
public class NordpoolController : ControllerBase
{
private readonly HttpClient _httpClient;
public NordpoolController(HttpClient httpClient)
{
_httpClient = httpClient;
}
[HttpGet("{country}/{start}/{end}")]
public async Task<IActionResult> GetNordPoolPrices(
string country,
string start,
string end)
{
var response = await _httpClient.GetAsync(
$"https://dashboard.elering.ee/api/nps/price?start={start}&end={end}");
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
var jsonDoc = JsonDocument.Parse(responseBody);
var dataProperty = jsonDoc.RootElement.GetProperty("data");
string prices;
switch (country)
{
case "ee":
prices = dataProperty.GetProperty("ee").ToString();
Console.WriteLine(responseBody);
return Content(prices, "application/json");
case "lv":
prices = dataProperty.GetProperty("lv").ToString();
return Content(prices, "application/json");
case "lt":
prices = dataProperty.GetProperty("lt").ToString();
return Content(prices, "application/json");
case "fi":
prices = dataProperty.GetProperty("fi").ToString();
return Content(prices, "application/json");
default:
return BadRequest("Invalid country code.");
}
}
}
}
Прописываем новый код в frontend App.js
import { useRef } from 'react';
import { useEffect, useState } from 'react';
import './App.css';
function App() {
const [prices, setPrices] = useState([]);
const [chosenCountry, setChosenCountry] = useState("ee");
const [start, setStart] = useState("");
const [end, setEnd] = useState("");
const startRef = useRef();
const endRef = useRef();
useEffect(() => {
if (start !== "" && end !== "") {
fetch("http://localhost:5256/nordpool/" + chosenCountry + "/" + start + "/" + end)
.then(res => res.json())
.then(json => {
setPrices(json);
});
}
}, [chosenCountry, start, end]);
function updateStart() {
const startIso = new Date(startRef.current.value).toISOString();
setStart(startIso);
}
function updateEnd() {
const endIso = new Date(endRef.current.value).toISOString();
setEnd(endIso);
}
return (
<div>
<button onClick={() => setChosenCountry("fi")}>Soome</button>
<button onClick={() => setChosenCountry("ee")}>Eesti</button>
<button onClick={() => setChosenCountry("lv")}>Läti</button>
<button onClick={() => setChosenCountry("lt")}>Leedu</button>
<input ref={startRef} onChange={updateStart} type="datetime-local" />
<input ref={endRef} onChange={updateEnd} type="datetime-local" />
{prices.length > 0 &&
<table style={{marginLeft: "100px"}}>
<thead>
<th style={{border: "1px solid #ddd", padding: "12px", backgroundColor: "#04AA6D"}}>Ajatempel</th>
<th style={{border: "1px solid #ddd", padding: "12px", backgroundColor: "#04AA6D"}}>Hind</th>
</thead>
<tbody>
<td style={{position: "absolute", left: "30px"}}>{chosenCountry}</td>
{prices.map(data =>
<tr key={data.timestamp}>
<td style={{border: "1px solid #ddd", padding: "8px"}}>{new Date(data.timestamp * 1000).toISOString()}</td>
<td style={{border: "1px solid #ddd", padding: "8px"}}>{data.price}</td>
</tr>)}
</tbody>
</table>}
</div>
);
}
export default App;

Создаем новый контроллер PaymentController.cs
using Microsoft.AspNetCore.Mvc;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text;
namespace veebMiljukova.Controllers
{
[Route(“[controller]”)]
[ApiController]
public class PaymentController : ControllerBase
{
private readonly HttpClient _httpClient;
public PaymentController(HttpClient httpClient)
{
_httpClient = httpClient;
}
[HttpGet("{sum}")]
public async Task<IActionResult> MakePayment(string sum)
{
var paymentData = new
{
api_username = "e36eb40f5ec87fa2",
account_name = "EUR3D1",
amount = sum,
order_reference = Math.Ceiling(new Random().NextDouble() * 999999),
nonce = $"a9b7f7e7as{DateTime.Now}{new Random().NextDouble() * 999999}",
timestamp = DateTime.Now,
customer_url = "https://maksmine.web.app/makse"
};
var json = JsonSerializer.Serialize(paymentData);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "ZTM2ZWI0MGY1ZWM4N2ZhMjo3YjkxYTNiOWUxYjc0NTI0YzJlOWZjMjgyZjhhYzhjZA==");
var response = await client.PostAsync("https://igw-demo.every-pay.com/api/v4/payments/oneoff", content);
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
var jsonDoc = JsonDocument.Parse(responseContent);
var paymentLink = jsonDoc.RootElement.GetProperty("payment_link");
return Ok(paymentLink);
}
else
{
return BadRequest("Payment failed.");
}
}
}
}
Прописываем новый код в frontend App.js
import React, { useState } from 'react';
import './App.css';
function App() {
const [amount, setAmount] = useState('');
const [paymentLink, setPaymentLink] = useState(null);
const [error, setError] = useState(null);
const makePayment = async () => {
setError(null);
try {
const response = await fetch(`http://localhost:5256/Payment/${amount}`);
if (!response.ok) {
throw new Error(`Error Fetching: ${response.status}`);
}
const data = await response.json();
setPaymentLink(data);
} catch (err) {
setError(err.message);
}
};
const handleSubmit = (event) => {
event.preventDefault();
makePayment();
};
return (
<div className="App">
<h1>Make a Payment</h1>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="amount">Enter Amount: </label>
<input
id="amount"
type="number"
value={amount}
onChange={e => setAmount(e.target.value)}
required
min="0.01"
step="0.01"
placeholder="Enter amount in EUR"
/>
</div>
<button type="submit">Pay</button>
</form>
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
{paymentLink ? (
<div>
<h2>Payment Link:</h2>
<a href={paymentLink} target="_blank" rel="noopener noreferrer">
Complete Payment
</a>
</div>
) : (
<p>No payment link available</p>
)}
</div>
);
}
export default App;





