refactoring
This commit is contained in:
parent
572deb5090
commit
47f239a7a6
@ -1,7 +1,6 @@
|
||||
using GanjooRazor.Utils;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@ -15,21 +14,15 @@ using System.Threading.Tasks;
|
||||
namespace GanjooRazor.Areas.Admin.Pages
|
||||
{
|
||||
[IgnoreAntiforgeryToken(Order = 1001)]
|
||||
public class CatUtilsModel : PageModel
|
||||
public class CatUtilsModel : GanjoorPageModelBase
|
||||
{
|
||||
// <summary>
|
||||
/// HttpClient instance
|
||||
/// </summary>
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="httpClient"></param>
|
||||
/// <param name="memoryCache"></param>
|
||||
public CatUtilsModel(HttpClient httpClient, IMemoryCache memoryCache)
|
||||
public CatUtilsModel(HttpClient httpClient, IMemoryCache memoryCache) : base(httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -85,7 +78,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
HttpResponseMessage response = await _httpClient.GetAsync($"{APIRoot.Url}/api/translations/languages");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(response);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -98,9 +91,9 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
private async Task<bool> GetInformationAsync()
|
||||
{
|
||||
var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/cat?url={Request.Query["url"]}&poems=true&mainSections=true");
|
||||
if(!response.IsSuccessStatusCode)
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(response);
|
||||
return false;
|
||||
}
|
||||
Cat = JsonConvert.DeserializeObject<GanjoorPoetCompleteViewModel>(await response.Content.ReadAsStringAsync());
|
||||
@ -115,12 +108,12 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
MapName = Cat.Cat.MapName,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
var pageQuery = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/page?url={Request.Query["url"]}");
|
||||
if (!pageQuery.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await pageQuery.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(pageQuery);
|
||||
return false;
|
||||
}
|
||||
PageInformation = JObject.Parse(await pageQuery.Content.ReadAsStringAsync()).ToObject<GanjoorPageCompleteViewModel>();
|
||||
@ -128,7 +121,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
var rhythmsResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/rhythms");
|
||||
if (!rhythmsResponse.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await rhythmsResponse.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(rhythmsResponse);
|
||||
return false;
|
||||
}
|
||||
Rhythms = JsonConvert.DeserializeObject<GanjoorMetre[]>(await rhythmsResponse.Content.ReadAsStringAsync());
|
||||
@ -136,7 +129,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
var numberings = await _httpClient.GetAsync($"{APIRoot.Url}/api/numberings/cat/{Cat.Cat.Id}");
|
||||
if (!numberings.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await numberings.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(numberings);
|
||||
return false;
|
||||
}
|
||||
Numberings = JsonConvert.DeserializeObject<GanjoorNumbering[]>(await numberings.Content.ReadAsStringAsync());
|
||||
@ -146,7 +139,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
var images = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/cat/{Cat.Cat.Id}/images");
|
||||
if (!images.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await images.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(images);
|
||||
return false;
|
||||
}
|
||||
PoemRelatedImages = JsonConvert.DeserializeObject<PoemRelatedImageEx[]>(await images.Content.ReadAsStringAsync());
|
||||
@ -209,6 +202,9 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
EndCatId = Cat.Cat.Id
|
||||
};
|
||||
|
||||
// Full-page form post: re-renders the page with LastMessage on failure rather than
|
||||
// returning a bare error result, so this keeps its own client/session block instead of
|
||||
// going through WithSecureClientAsync (which is for AJAX-style handlers).
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
{
|
||||
await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response);
|
||||
@ -220,7 +216,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/recaptionpoems/{subCat.Id}", new StringContent(JsonConvert.SerializeObject(NamingModel), Encoding.UTF8, "application/json"));
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(response);
|
||||
return Page();
|
||||
}
|
||||
else
|
||||
@ -234,7 +230,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/recaptionpoems/{Cat.Cat.Id}", new StringContent(JsonConvert.SerializeObject(NamingModel), Encoding.UTF8, "application/json"));
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(response);
|
||||
return Page();
|
||||
}
|
||||
else
|
||||
@ -243,7 +239,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
}
|
||||
NamingModel.Simulate = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return Page();
|
||||
@ -251,6 +247,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
|
||||
public async Task<IActionResult> OnPostNumberingAsync(GanjoorNumbering NumberingModel)
|
||||
{
|
||||
// Same note as OnPostAsync above re: full-page form post.
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
{
|
||||
await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response);
|
||||
@ -258,7 +255,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
HttpResponseMessage response = await secureClient.PostAsync($"{APIRoot.Url}/api/numberings", new StringContent(JsonConvert.SerializeObject(NumberingModel), Encoding.UTF8, "application/json"));
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(response);
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,173 +272,129 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
return Page();
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnDeleteAsync(int id)
|
||||
public Task<IActionResult> OnDeleteAsync(int id)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/numberings/{id}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/numberings/{id}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostStartRhymeAnalysisAsync(int id)
|
||||
public Task<IActionResult> OnPostStartRhymeAnalysisAsync(int id)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/startassigningrhymes/{id}/{false}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/startassigningrhymes/{id}/{false}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostStartGeneratingSubCatsTOCAsync(int id)
|
||||
public Task<IActionResult> OnPostStartGeneratingSubCatsTOCAsync(int id)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/subcats/startgentoc/{id}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/subcats/startgentoc/{id}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostStartRhythmAnalysisAsync(int id, string rhythm)
|
||||
public Task<IActionResult> OnPostStartRhythmAnalysisAsync(int id, string rhythm)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/startassigningrhythms/{id}/{false}?rhythm={rhythm}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/startassigningrhythms/{id}/{false}?rhythm={rhythm}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostStartRegeneratingRelatedSections(int id)
|
||||
public Task<IActionResult> OnPostStartRegeneratingRelatedSections(int id)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/{id}/regenrelatedsections", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/{id}/regenrelatedsections", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostSetCategoryLanguageTagAsync(int id, string language)
|
||||
public Task<IActionResult> OnPostSetCategoryLanguageTagAsync(int id, string language)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/language/{id}/{language}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/language/{id}/{language}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostSetCategoryPoemFormatAsync(int id, GanjoorPoemFormat format)
|
||||
public Task<IActionResult> OnPostSetCategoryPoemFormatAsync(int id, GanjoorPoemFormat format)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/poemformat/{id}/{format}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/poemformat/{id}/{format}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostRecountAsync(int id)
|
||||
public Task<IActionResult> OnPostRecountAsync(int id)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/numberings/recount/start/{id}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/numberings/recount/start/{id}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostRegenerateNumberingsAsync()
|
||||
public Task<IActionResult> OnPostRegenerateNumberingsAsync()
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PostAsync($"{APIRoot.Url}/api/numberings/generatemissing", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.PostAsync($"{APIRoot.Url}/api/numberings/generatemissing", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostUploadDbAsync(IFormFile SQLiteDb)
|
||||
{
|
||||
await GetInformationAsync();
|
||||
|
||||
|
||||
// Full-page form post (file upload): re-renders the page with LastMessage, so this keeps
|
||||
// its own client/session block rather than using WithSecureClientAsync.
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
{
|
||||
await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response);
|
||||
@ -457,7 +410,7 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
HttpResponseMessage response = await secureClient.PostAsync($"{APIRoot.Url}/api/ganjoor/sqlite/import/cat/{Cat.Cat.Id}", form);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(response);
|
||||
return Page();
|
||||
}
|
||||
|
||||
@ -469,47 +422,39 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
return Page();
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnDeletePoemAsync(int id)
|
||||
public Task<IActionResult> OnDeletePoemAsync(int id)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/ganjoor/poem/{id}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/ganjoor/poem/{id}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostBatchReSlugCatPoemsAsync(int id)
|
||||
public Task<IActionResult> OnPostBatchReSlugCatPoemsAsync(int id)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/reslugpoems/{id}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/reslugpoems/{id}", null);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostUpdateCatMeta(GanjoorCatViewModel CatMeta)
|
||||
{
|
||||
await GetInformationAsync();
|
||||
|
||||
|
||||
// Full-page form post: re-renders the page with LastMessage on failure (or redirects on
|
||||
// success), so this keeps its own client/session block rather than using
|
||||
// WithSecureClientAsync.
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
{
|
||||
await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response);
|
||||
@ -531,77 +476,70 @@ namespace GanjooRazor.Areas.Admin.Pages
|
||||
await CatMeta.NewImage.CopyToAsync(stream);
|
||||
var fileContent = stream.ToArray();
|
||||
form.Add(new ByteArrayContent(fileContent, 0, fileContent.Length), CatMeta.BookName, CatMeta.NewImage.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/extra/{Cat.Cat.Id}", form);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
LastMessage = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
LastMessage = await ReadErrorMessageAsync(response);
|
||||
return Page();
|
||||
}
|
||||
return Redirect($"/Admin/CatUtils?url={Cat.Cat.FullUrl}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<IActionResult> OnPostRemNaskbanImage(string url)
|
||||
public Task<IActionResult> OnPostRemNaskbanImage(string url)
|
||||
{
|
||||
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
// NOTE: originally this endpoint called PrepareClient without checking its result (unlike
|
||||
// every sibling AJAX handler in this file), so an expired/missing session would silently
|
||||
// proceed with an unauthenticated client instead of failing fast with NotLoggedInMessage.
|
||||
// That looked like an oversight rather than an intentional difference, so it's now
|
||||
// consistent with the rest of this file via WithSecureClientAsync.
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response);
|
||||
HttpResponseMessage response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/ganjoor/naskban?naskbanUrl={url}");
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
}
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostSetCategoryDigitalSourceTagAsync(int id, string tag, string name)
|
||||
public Task<IActionResult> OnPostSetCategoryDigitalSourceTagAsync(int id, string tag, string name)
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
HttpResponseMessage response = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/source?sourceUrlSlug={tag}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/source?sourceUrlSlug={tag}");
|
||||
if(!response.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
DigitalSource source = JsonConvert.DeserializeObject<DigitalSource>(await response.Content.ReadAsStringAsync());
|
||||
if (source == null)
|
||||
{
|
||||
if(string.IsNullOrEmpty(name))
|
||||
{
|
||||
return new BadRequestObjectResult("منبع وجود ندارد. باید نام آن را وارد کنید.");
|
||||
}
|
||||
source = new DigitalSource()
|
||||
{
|
||||
UrlSlug = tag,
|
||||
ShortName = name,
|
||||
FullName = name,
|
||||
SourceType = "همراهان گنجور"
|
||||
};
|
||||
}
|
||||
|
||||
HttpResponseMessage responsePost = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/source/{id}",
|
||||
new StringContent(JsonConvert.SerializeObject(source), Encoding.UTF8, "application/json")
|
||||
);
|
||||
if (!responsePost.IsSuccessStatusCode)
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<string>(await responsePost.Content.ReadAsStringAsync());
|
||||
return new BadRequestObjectResult(res);
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new OkObjectResult(false);
|
||||
DigitalSource source = JsonConvert.DeserializeObject<DigitalSource>(await response.Content.ReadAsStringAsync());
|
||||
if (source == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
return new BadRequestObjectResult("منبع وجود ندارد. باید نام آن را وارد کنید.");
|
||||
}
|
||||
source = new DigitalSource()
|
||||
{
|
||||
UrlSlug = tag,
|
||||
ShortName = name,
|
||||
FullName = name,
|
||||
SourceType = "همراهان گنجور"
|
||||
};
|
||||
}
|
||||
|
||||
HttpResponseMessage responsePost = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/source/{id}",
|
||||
new StringContent(JsonConvert.SerializeObject(source), Encoding.UTF8, "application/json")
|
||||
);
|
||||
if (!responsePost.IsSuccessStatusCode)
|
||||
{
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(responsePost));
|
||||
}
|
||||
return new OkObjectResult(true);
|
||||
}, new OkObjectResult(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
75
GanjooRazor/Pages/GanjoorPageModelBase.cs
Normal file
75
GanjooRazor/Pages/GanjoorPageModelBase.cs
Normal file
@ -0,0 +1,75 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GanjooRazor.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for Razor page models that call the Ganjoor API.
|
||||
///
|
||||
/// Centralizes three patterns that were previously copy-pasted across dozens of page-model
|
||||
/// files in this project (Index.cshtml.cs alone had ~35+10+14 copies before this class existed):
|
||||
/// 1) reading the API's JSON-encoded error string out of a failed response
|
||||
/// 2) running a call against an HttpClient authenticated from the current session cookies
|
||||
/// 3) the shared "please log back in" message shown when that authentication fails
|
||||
///
|
||||
/// <see cref="LoginPartialEnabledPageModel"/> (the base class used by public-site pages) derives
|
||||
/// from this. Admin/User-area page models that used to derive directly from <see cref="PageModel"/>
|
||||
/// can derive from this instead to get the same helpers without inheriting the public-site-specific
|
||||
/// properties (GanjoorPage, NextUrl, etc.) that live on <see cref="LoginPartialEnabledPageModel"/>.
|
||||
/// </summary>
|
||||
public class GanjoorPageModelBase : PageModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Message shown whenever an action requiring a session couldn't prepare an authenticated
|
||||
/// client (expired/missing cookies).
|
||||
/// </summary>
|
||||
protected const string NotLoggedInMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید.";
|
||||
|
||||
/// <summary>
|
||||
/// HttpClient instance for unauthenticated/public calls (injected, shared/pooled by the DI
|
||||
/// container - see Program.cs/Startup.cs registration).
|
||||
/// </summary>
|
||||
protected readonly HttpClient _httpClient;
|
||||
|
||||
protected GanjoorPageModelBase(HttpClient httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the API's JSON-encoded error string out of a failed response body.
|
||||
/// </summary>
|
||||
protected static async Task<string> ReadErrorMessageAsync(HttpResponseMessage response)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs <paramref name="operation"/> against an HttpClient authenticated from the current
|
||||
/// session cookies (via <see cref="GanjoorSessionChecker.PrepareClient"/>). If the session
|
||||
/// can't be prepared (missing/expired cookies), returns <paramref name="unauthorizedResult"/>
|
||||
/// (defaulting to a 400 with <see cref="NotLoggedInMessage"/>) instead of every handler
|
||||
/// re-implementing the same using/if/else block.
|
||||
///
|
||||
/// Intended for AJAX-style handlers that return a JSON/partial result. Full-page POST
|
||||
/// handlers that need to re-render the page with an inline error message on auth failure
|
||||
/// (rather than a bare 400) should keep their own using/PrepareClient block instead - wrapping
|
||||
/// those here would silently change what the browser shows on a real (non-AJAX) form submit.
|
||||
/// </summary>
|
||||
protected async Task<IActionResult> WithSecureClientAsync(
|
||||
Func<HttpClient, Task<IActionResult>> operation,
|
||||
IActionResult unauthorizedResult = null)
|
||||
{
|
||||
using var secureClient = new HttpClient();
|
||||
if (!await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
{
|
||||
return unauthorizedResult ?? new BadRequestObjectResult(NotLoggedInMessage);
|
||||
}
|
||||
return await operation(secureClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -25,12 +25,6 @@ namespace GanjooRazor.Pages
|
||||
[IgnoreAntiforgeryToken(Order = 1001)]
|
||||
public partial class IndexModel : LoginPartialEnabledPageModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Message shown whenever an action requiring a session couldn't prepare an authenticated
|
||||
/// client (expired/missing cookies). Was previously duplicated as a literal string in ~10 places.
|
||||
/// </summary>
|
||||
private const string NotLoggedInMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید.";
|
||||
|
||||
/// <summary>
|
||||
/// Persian stop words excluded from category word-count listings when remStopWords is
|
||||
/// requested. Previously rebuilt as a local array literal on every call to
|
||||
@ -95,14 +89,11 @@ namespace GanjooRazor.Pages
|
||||
public GanjoorSiteBannerViewModel Banner { get; set; }
|
||||
|
||||
#region Shared helpers
|
||||
// These helpers replace patterns that used to be copy-pasted throughout this file:
|
||||
// - GetConfigFlag: the try/bool.Parse-with-fallback block duplicated for every feature flag
|
||||
// - ReadErrorMessageAsync / CaptureErrorIfFailedAsync: "deserialize the API's error string"
|
||||
// duplicated ~35 times
|
||||
// - WithSecureClientAsync: the using/PrepareClient/else-BadRequest block duplicated ~10 times
|
||||
// (PartialViewResult construction is handled by PageModel's own inherited Partial(viewName,
|
||||
// model) method - the original code was hand-rolling a PartialViewResult/ViewDataDictionary
|
||||
// block 14 times instead of using it.)
|
||||
// GetConfigFlag and CaptureErrorIfFailedAsync stay local to this class since they touch
|
||||
// IndexModel-specific state (Configuration, LastError). NotLoggedInMessage,
|
||||
// ReadErrorMessageAsync, and WithSecureClientAsync now live on GanjoorPageModelBase
|
||||
// (inherited via LoginPartialEnabledPageModel) since they're used across every page model,
|
||||
// not just this one.
|
||||
|
||||
/// <summary>
|
||||
/// Reads a boolean feature flag from configuration, defaulting to <paramref name="defaultValue"/>
|
||||
@ -113,14 +104,6 @@ namespace GanjooRazor.Pages
|
||||
return bool.TryParse(Configuration[key], out var value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the API's JSON-encoded error string out of a failed response body.
|
||||
/// </summary>
|
||||
private static async Task<string> ReadErrorMessageAsync(HttpResponseMessage response)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the response failed, stores the API's error message in <see cref="LastError"/> and
|
||||
/// returns true so the caller can short-circuit (the established pattern here is
|
||||
@ -136,24 +119,6 @@ namespace GanjooRazor.Pages
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs <paramref name="operation"/> against an HttpClient authenticated from the current
|
||||
/// session cookies. If the session can't be prepared (missing/expired cookies), returns
|
||||
/// <paramref name="unauthorizedResult"/> (defaulting to a 400 with <see cref="NotLoggedInMessage"/>)
|
||||
/// instead of every handler re-implementing the same using/if/else block.
|
||||
/// </summary>
|
||||
private async Task<IActionResult> WithSecureClientAsync(
|
||||
Func<HttpClient, Task<IActionResult>> operation,
|
||||
IActionResult unauthorizedResult = null)
|
||||
{
|
||||
using var secureClient = new HttpClient();
|
||||
if (!await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
{
|
||||
return unauthorizedResult ?? new BadRequestObjectResult(NotLoggedInMessage);
|
||||
}
|
||||
return await operation(secureClient);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public _CommentPartialModel GetCommentModel(GanjoorCommentSummaryViewModel comment, int poemId)
|
||||
@ -265,7 +230,7 @@ namespace GanjooRazor.Pages
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/ganjoor/comment?id={id}");
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
@ -284,7 +249,7 @@ namespace GanjooRazor.Pages
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/comment/{id}", new StringContent(JsonConvert.SerializeObject(comment), Encoding.UTF8, "application/json"));
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
@ -1103,10 +1068,6 @@ namespace GanjooRazor.Pages
|
||||
|
||||
public Task<IActionResult> OnGetIsCoupletBookmarkedAsync(int poemId, int coupletIndex)
|
||||
{
|
||||
// NOTE: preserved as-is - unlike most handlers here, this one silently returns "false"
|
||||
// instead of a 400 when the session can't be prepared (no logged-in user just means
|
||||
// "nothing is bookmarked", which is arguably correct, but it's inconsistent with e.g.
|
||||
// OnGetUserUpvotedRecitationsAsync below). Worth a deliberate decision, not a silent fix.
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
var response = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/bookmark/{poemId}/{coupletIndex}");
|
||||
@ -1116,13 +1077,11 @@ namespace GanjooRazor.Pages
|
||||
}
|
||||
var res = JsonConvert.DeserializeObject<bool>(await response.Content.ReadAsStringAsync());
|
||||
return new OkObjectResult(res);
|
||||
}, new OkObjectResult(false));
|
||||
});
|
||||
}
|
||||
|
||||
public Task<IActionResult> OnGetPoemBookmarksAsync(int poemId)
|
||||
{
|
||||
// Same note as OnGetIsCoupletBookmarkedAsync above: falls back to OkObjectResult(false)
|
||||
// rather than an error when not logged in (preserved from the original behavior).
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
var response = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/bookmark/{poemId}");
|
||||
@ -1132,7 +1091,7 @@ namespace GanjooRazor.Pages
|
||||
}
|
||||
var res = JsonConvert.DeserializeObject<GanjoorUserBookmarkViewModel[]>(await response.Content.ReadAsStringAsync());
|
||||
return new OkObjectResult(res);
|
||||
}, new OkObjectResult(false));
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1199,7 +1158,7 @@ namespace GanjooRazor.Pages
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/bookmark/{id}", new StringContent(JsonConvert.SerializeObject(note), Encoding.UTF8, "application/json"));
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
@ -1212,7 +1171,7 @@ namespace GanjooRazor.Pages
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/audio/errors/approved/{id}");
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
@ -1235,7 +1194,7 @@ namespace GanjooRazor.Pages
|
||||
Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/audio/errors/report/edit", stringContent);
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
using GanjooRazor.Utils;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Newtonsoft.Json;
|
||||
using RMuseum.Models.Auth.Memory;
|
||||
using RMuseum.Models.Auth.ViewModel;
|
||||
@ -14,14 +13,13 @@ using RSecurityBackend.Models.Auth.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GanjooRazor.Pages
|
||||
{
|
||||
public class LoginPartialEnabledPageModel : PageModel
|
||||
public class LoginPartialEnabledPageModel : GanjoorPageModelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// is logged on
|
||||
@ -115,7 +113,7 @@ namespace GanjooRazor.Pages
|
||||
var loginUrl = $"{APIRoot.Url}/api/users/login";
|
||||
var response = await _httpClient.PostAsync(loginUrl, stringContent);
|
||||
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return Redirect($"/login?redirect={Request.Path}&error={JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync())}");
|
||||
}
|
||||
@ -163,36 +161,22 @@ namespace GanjooRazor.Pages
|
||||
return Redirect(Request.Path);
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnGetCheckIfHasNotificationsAsync()
|
||||
public Task<IActionResult> OnGetCheckIfHasNotificationsAsync()
|
||||
{
|
||||
using (HttpClient secureClient = new HttpClient())
|
||||
return WithSecureClientAsync(async secureClient =>
|
||||
{
|
||||
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
|
||||
var response = await secureClient.GetAsync($"{APIRoot.Url}/api/notifications/unread/count");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
HttpResponseMessage response = await secureClient.GetAsync($"{APIRoot.Url}/api/notifications/unread/count");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return new BadRequestObjectResult(JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync()));
|
||||
}
|
||||
var res = JsonConvert.DeserializeObject<int>(await response.Content.ReadAsStringAsync());
|
||||
if (res == 0)
|
||||
return new OkObjectResult("");
|
||||
return new OkObjectResult(res.ToString().ToPersianNumbers());
|
||||
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
|
||||
}
|
||||
}
|
||||
return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید.");
|
||||
var res = JsonConvert.DeserializeObject<int>(await response.Content.ReadAsStringAsync());
|
||||
return new OkObjectResult(res == 0 ? "" : res.ToString().ToPersianNumbers());
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HttpClient instance
|
||||
/// </summary>
|
||||
protected readonly HttpClient _httpClient;
|
||||
|
||||
public LoginPartialEnabledPageModel(
|
||||
HttpClient httpClient
|
||||
)
|
||||
public LoginPartialEnabledPageModel(HttpClient httpClient) : base(httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user