1
1
using Catalog . Core . DTO ;
2
2
using Catalog . Core . Entities ;
3
+ using Catalog . Core . Logging ;
3
4
using Catalog . Core . Repositories ;
4
5
using Microsoft . AspNetCore . Mvc ;
5
6
6
- namespace Catalog . API . Controllers ;
7
-
7
+ namespace Catalog . API . Controllers
8
+ {
8
9
[ ApiController ]
9
10
[ Route ( "/[controller]" ) ]
10
11
public class ProductController : ControllerBase
11
12
{
12
-
13
- // TODO: Logging
14
- // TODO: Validations - maybe using FluentValidation
15
13
private readonly IProductRepository _productRepository ;
14
+ private readonly ILogger < ProductController > _logger ;
16
15
17
- public ProductController ( IProductRepository productRepository )
16
+ public ProductController ( IProductRepository productRepository , ILogger < ProductController > logger )
18
17
{
19
18
_productRepository = productRepository ;
19
+ _logger = logger ;
20
20
}
21
21
22
22
[ HttpPost ]
23
23
public async Task < ActionResult < Product > > Post ( [ FromForm ] ProductDtoRequest req )
24
24
{
25
+ _logger . LogInformation ( "POST request received to create a new product." ) ;
26
+
25
27
try
26
28
{
27
- using var ms = new MemoryStream ( ) ;
28
- if ( req . Image != null ) await req . Image . CopyToAsync ( ms ) ;
29
-
30
29
var product = new Product
31
30
{
32
31
Name = req . Name ,
33
32
Description = req . Description ,
34
33
Price = req . Price ,
35
34
Category = req . Category ,
36
- Image = ms . ToArray ( ) ,
35
+ Image = req . Image != null ? await GetImageBytesAsync ( req . Image ) : null ,
37
36
Stock = req . Stock
38
37
} ;
38
+
39
39
await _productRepository . CreateAsync ( product ) ;
40
- return CreatedAtAction ( nameof ( Post ) , new { product . Id } , product ) ;
40
+ _logger . LogInformation ( $ "Product created successfully with ID { product . Id } .") ;
41
+ return CreatedAtAction ( nameof ( GetProduct ) , new { id = product . Id } , product ) ;
41
42
}
42
43
catch ( Exception e )
43
44
{
45
+ CustomLogger . LogFile = true ;
46
+ _logger . LogError ( e , "Error occurred while creating a new product." ) ;
44
47
return BadRequest ( new { ErrorMessage = e . Message } ) ;
45
48
}
46
49
}
47
50
48
51
[ HttpGet ]
49
- public IActionResult Get ( )
52
+ public async Task < IActionResult > Get ( )
50
53
{
51
- IList < ProductDtoResponse > res = new List < ProductDtoResponse > ( ) ;
52
- var products = _productRepository . GetAllAsync ( ) ;
53
- if ( products ? . Result == null )
54
- return NotFound ( ) ;
55
-
56
- foreach ( var product in products . Result )
54
+ _logger . LogInformation ( "GET request received to retrieve all products." ) ;
55
+ try
57
56
{
58
- res . Add ( new ProductDtoResponse
57
+ var products = await _productRepository . GetAllAsync ( ) ;
58
+ if ( products == null || products . Count == 0 )
59
59
{
60
- Id = product . Id ,
61
- Name = product . Name ,
62
- Description = product . Description ,
63
- Price = product . Price ,
64
- Category = product . Category ,
65
- Stock = product . Stock ,
66
- CreatedAt = product . CreatedAt ,
67
- UpdatedAt = product . UpdatedAt
68
- } ) ;
69
- }
60
+ _logger . LogWarning ( "No products found." ) ;
61
+ return NotFound ( ) ;
62
+ }
70
63
71
- return Ok ( res ) ;
64
+ var res = new List < ProductDtoResponse > ( ) ;
65
+ foreach ( var product in products )
66
+ {
67
+ res . Add ( new ProductDtoResponse
68
+ {
69
+ Id = product . Id ,
70
+ Name = product . Name ,
71
+ Description = product . Description ,
72
+ Price = product . Price ,
73
+ Category = product . Category ,
74
+ Stock = product . Stock ,
75
+ CreatedAt = product . CreatedAt ,
76
+ UpdatedAt = product . UpdatedAt
77
+ } ) ;
78
+ }
79
+
80
+ _logger . LogInformation ( "Products retrieved successfully." ) ;
81
+ return Ok ( res ) ;
82
+ }
83
+ catch ( Exception e )
84
+ {
85
+ CustomLogger . LogFile = true ;
86
+ _logger . LogError ( e , "Error occurred while retrieving products." ) ;
87
+ return StatusCode ( 500 , new { ErrorMessage = e . Message } ) ;
88
+ }
72
89
}
73
90
74
91
[ HttpGet ( "GetImage/{productId:int}" ) ]
75
- public IActionResult GetImage ( [ FromRoute ] int productId )
92
+ public async Task < IActionResult > GetImage ( [ FromRoute ] int productId )
76
93
{
77
- var imageBinary = _productRepository . GetImage ( productId ) ;
78
- if ( imageBinary is not null )
79
- return File ( imageBinary , "image/png" ) ;
94
+ _logger . LogInformation ( $ "GET request received to retrieve image for product ID { productId } .") ;
95
+
96
+ try
97
+ {
98
+ var imageBinary = _productRepository . GetImage ( productId ) ;
99
+ if ( imageBinary != null )
100
+ {
101
+ _logger . LogInformation ( $ "Image retrieved successfully for product ID { productId } .") ;
102
+ return File ( imageBinary , "image/png" ) ;
103
+ }
80
104
81
- return NoContent ( ) ;
105
+ _logger . LogWarning ( $ "No image found for product ID { productId } .") ;
106
+ return NoContent ( ) ;
107
+ }
108
+ catch ( Exception e )
109
+ {
110
+ CustomLogger . LogFile = true ;
111
+ _logger . LogError ( e , $ "Error occurred while retrieving image for product ID { productId } .") ;
112
+ return StatusCode ( 500 , new { ErrorMessage = e . Message } ) ;
113
+ }
82
114
}
83
115
84
116
[ HttpGet ( "{id:int}" ) ]
85
117
public async Task < ActionResult < ProductDtoResponse > > GetProduct ( [ FromRoute ] int id )
86
118
{
119
+ _logger . LogInformation ( $ "GET request received to retrieve product with ID { id } .") ;
87
120
try
88
121
{
89
- var res = new ProductDtoResponse ( ) ;
90
122
var product = await _productRepository . GetByIdAsync ( id ) ;
123
+ if ( product == null )
124
+ {
125
+ _logger . LogWarning ( $ "Product with ID { id } not found.") ;
126
+ return NotFound ( ) ;
127
+ }
128
+
129
+ var res = new ProductDtoResponse
130
+ {
131
+ Id = product . Id ,
132
+ Name = product . Name ,
133
+ Description = product . Description ,
134
+ Price = product . Price ,
135
+ Category = product . Category ,
136
+ Stock = product . Stock ,
137
+ CreatedAt = product . CreatedAt ,
138
+ UpdatedAt = product . UpdatedAt
139
+ } ;
91
140
92
- res . Id = product . Id ;
93
- res . Name = product . Name ;
94
- res . Description = product . Description ;
95
- res . Price = product . Price ;
96
- res . Category = product . Category ;
97
- res . Stock = product . Stock ;
98
- res . CreatedAt = product . CreatedAt ;
99
- res . UpdatedAt = product . UpdatedAt ;
100
-
141
+ _logger . LogInformation ( $ "Product with ID { id } retrieved successfully.") ;
101
142
return Ok ( res ) ;
102
143
}
103
144
catch ( Exception e )
104
145
{
105
- return NotFound ( new { ErrorMessage = e . Message } ) ;
146
+ CustomLogger . LogFile = true ;
147
+ _logger . LogError ( e , $ "Error occurred while retrieving product ID { id } .") ;
148
+ return StatusCode ( 500 , new { ErrorMessage = e . Message } ) ;
106
149
}
107
150
}
108
151
109
152
[ HttpPut ( "{id:int}" ) ]
110
153
public async Task < ActionResult > Put ( [ FromRoute ] int id , [ FromBody ] ProductDtoUpdate req )
111
154
{
155
+ _logger . LogInformation ( $ "PUT request received to update product with ID { id } .") ;
156
+
112
157
try
113
158
{
114
159
var product = await _productRepository . GetByIdAsync ( id ) ;
115
-
116
- if ( req . Name != null ) product . Name = req . Name ;
117
- if ( req . Description != null ) product . Description = req . Description ;
118
- if ( req . Price != null ) product . Price = ( decimal ) req . Price ;
119
- if ( req . Category != null ) product . Category = req . Category ;
120
- if ( req . Stock != null ) product . Stock = ( int ) req . Stock ;
160
+ if ( product == null )
161
+ {
162
+ _logger . LogWarning ( $ "Product with ID { id } not found.") ;
163
+ return NotFound ( ) ;
164
+ }
165
+
166
+ product . Name = req . Name ?? product . Name ;
167
+ product . Description = req . Description ?? product . Description ;
168
+ product . Price = req . Price ?? product . Price ;
169
+ product . Category = req . Category ?? product . Category ;
170
+ product . Stock = req . Stock ?? product . Stock ;
121
171
product . UpdatedAt = DateTime . Now ;
122
172
123
173
await _productRepository . UpdateAsync ( product ) ;
174
+ _logger . LogInformation ( $ "Product with ID { id } updated successfully.") ;
124
175
return Ok ( ) ;
125
176
}
126
177
catch ( Exception e )
127
178
{
179
+ CustomLogger . LogFile = true ;
180
+ _logger . LogError ( e , $ "Error occurred while updating product with ID { id } .") ;
128
181
return BadRequest ( new { ErrorMessage = e . Message } ) ;
129
182
}
130
183
}
131
184
132
185
[ HttpDelete ( "{id:int}" ) ]
133
186
public async Task < ActionResult > Delete ( [ FromRoute ] int id )
134
187
{
188
+ _logger . LogInformation ( $ "DELETE request received to delete product with ID { id } .") ;
189
+
135
190
try
136
191
{
137
192
var product = await _productRepository . GetByIdAsync ( id ) ;
193
+ if ( product == null )
194
+ {
195
+ _logger . LogWarning ( $ "Product with ID { id } not found.") ;
196
+ return NotFound ( ) ;
197
+ }
198
+
138
199
await _productRepository . RemoveAsync ( product . Id ) ;
200
+ _logger . LogInformation ( $ "Product with ID { id } deleted successfully.") ;
139
201
return Ok ( ) ;
140
202
}
141
203
catch ( Exception e )
142
204
{
143
- return NotFound ( new { ErrorMessage = e . Message } ) ;
205
+ CustomLogger . LogFile = true ;
206
+ _logger . LogError ( e , $ "Error occurred while deleting product with ID { id } .") ;
207
+ return StatusCode ( 500 , new { ErrorMessage = e . Message } ) ;
144
208
}
145
209
}
146
- }
210
+
211
+ private async Task < byte [ ] > GetImageBytesAsync ( IFormFile image )
212
+ {
213
+ using var ms = new MemoryStream ( ) ;
214
+ await image . CopyToAsync ( ms ) ;
215
+ return ms . ToArray ( ) ;
216
+ }
217
+ }
218
+ }
0 commit comments