عايزين نعمل Endpoint تجيبلنا الـ Address بتاع الـ User هنعملها في الـ Account Controller
[Authorize]
[HttpGet("address")] // GET : /api/Account/Address
public async Task<ActionResult<Address>> GetUserAddress()
{
var email = User.FindFirstValue(ClaimType.Email);
var user = await _userManager.FindByEmailAsync(email);
return Ok(user.Address);
}
اللي موجود في الـ Identity
لو عملنا Run كدا الـ Swagger مش هيعمل Documentation وهيطلعلي Error لأن فيه حاجة هو مش عارف يعملها Documentation بس نروح نجرب على الـ Postman فهنلاقي برضو ان هو مش مرجع Content وجايبلي ok بس 204 No Content
الـ User جواه Navigational Property اسمها Address بس لو تفتكر قولنا انها مش بتعمل Include ليها by default فاحنا محتاجين يتعملها Load
هنروح نقلد الـ Function اللي اسمها FindByEmailAsync
وتكون Extension Method
فهنروح لفولدر الـ Extensions اللي في بروجكت الـ Api
هنعمل كلاس نسميه UserManagerExtension
public static class UserManagerExtension
{
public static async Task<AppUser> FindUserWithAddressAsync(this UserManager<AppUser> userManager, ClaimsPrincipal User)
{
var email = User.FindFirstValue(ClaimType.Email);
var user = await userManager.Users.Include(U => U.Address).SingleOrDefaultAsync(U => U.Email == email);
return user;
}
}
// Endpoint
[Authorize]
[HttpGet("address")] // GET : /api/Account/Address
public async Task<ActionResult<Address>> GetUserAddress()
{
var user = await _userManager.FindUserWithAddressAsync(User);
return Ok(user.Address);
}
بس خد بالك احنا برضو هنحتاج نعمل Update للـ UserAddress
فبدل ما اكرر اني اعمل email كل شوية ممكن امرر User لـ FindUserWithAddressByEmailAsync
وجواها اجيب الـ Email منعا للتكرار
بس برضو هيجيبلك No Content لأن باختصار الـ Table مفيهوش Address فاحنا محتاجين نضيفه وممكن نضيفه يدوي في الـ DB
بعد اما نضيف الـ Address برضو هيظهر Error
ودا بسبب اني لو جيت أشوف الـ user اللي راجع من الـ Function هلاقي الـ Address ودا اللي انا عايزة بس لو جيت افتح الـ Address اللي جوا الـ User هلاقي user وهكذا بقا إلى مالا نهاية
ودا في ما معناه ان الـ Maximum Nesting لازم يكون 32 او اقل بس دا مالا نهاية
والايرور دا حصل بسبب ان فيه Navigational Property لكل واحدة في التانية ودي ليها حلين:
- اما أرجع Address DTO: ودا اللي هعمله هنا
- طريقة بـ Package جواها Method معينة كدا (هنعرفها بعدين)
احنا عاملين اصلا AddressDto
بس للـ Order بس النهاردة هنستخدمه للـ User
فمحتاج أعمل Mapping
// Helpers.MappingProfiles
CreateMap<AddressDto, Core.Entities.Order_Aggregate.Address>();
// Return AddressDto -> Address(Order)
CreateMap<Core.Entities.Identity.Address, AddressDto>();
// Alias in the first of the page
using UserAddress = Shary.Core.Entities.Identity.Address;
using OrderAddress = Shary.Core.Entities.Order_Aggregate.Address;
CreateMap<AddressDto, OrderAddress>();
CreateMap<UserAddress, AddressDto>();
فانا محتاج أعمل Alias Name اسهل من دا لو الموضوع بيتكرر كتير
// Inject
private readonly IMapper _mapper;
public AccountController(
UserManager<AppUser> userManager,
SignInManager<AppUser> signInManager,
IAuthService authService,
IMapper mapper
)
{
_mapper = mapper;
}
// Endpoint
[Authorize]
[HttpGet("address")] // GET : /api/Account/Address
public async Task<ActionResult<AddressDto>> GetUserAddress()
{
var user = await _userManager.FindUserWithAddressAsync(User);
var address = _mapper.Map<AddressDto>(user.Address);
return Ok(address);
}