public async Task <IViewComponentResult> InvokeAsync() { var baseAPIUrl = $"api/BoardMeetings/GetCurrentBoardMeetingDue"; try { //call the api with a GET request //ensure to set the httpcompletion mode to response headers read //this allows the response to be read as soon as content starts arriving instead of having to wait //until the entire response is read //with this option, we can read the response content into a stream and deserialize it var response = await(await _apiClient.WithGETOnlyAccessAuthorization()).GetAsync(baseAPIUrl, HttpCompletionOption.ResponseHeadersRead); if (response.StatusCode == System.Net.HttpStatusCode.TooManyRequests) { TempData["TooManyRequests"] = "Too many requests. Please slow down with your requests"; return(View(new BoardMeetingViewDto())); } //ensure success status code else throw an exception response.EnsureSuccessStatusCode(); //read the response content into a stream var streamContent = await response.Content.ReadAsStreamAsync(); //deserialize the stream into an object (see StreamExtensions on how this is done) BoardMeetingForView = streamContent.ReadAndDeserializeFromJson <BoardMeetingViewDto>(); if (BoardMeetingForView == null) { return(View(new BoardMeetingViewDto())); } //cut down the size of the message if its longer than 75 characters if (BoardMeetingForView.Description.Length > 75) { BoardMeetingForView.Description = BoardMeetingForView.Description.Substring(0, 75) + "..."; } } catch (HttpRequestException ex) { _logger.LogError($"An error occured accessing the API. Url: {HttpContext.Request.GetDisplayUrl()}" + $" Error Message: {ex.Message}"); //either the API is not running or an error occured on the server TempData["Error"] = "An error occured while processing your request. Please try again later."; return(View(new BoardMeetingViewDto())); } return(View(BoardMeetingForView)); }
public async Task <IActionResult> OnGetFetchEditBoardMeetingPartialAsync(CancellationToken cancellationToken) { //set this value to true as the partial page will include specific //elements in the modal based on this value EditMeeting = true; var baseAPIUrl = $"api/boardmeetings/{Id}"; try { //call the api with a GET request //ensure to set the httpcompletion mode to response headers read //this allows the response to be read as soon as content starts arriving instead of having to wait //until the entire response is read //with this option, we can read the response content into a stream and deserialize it var response = await(await _apiClient.WithAuthorization()).GetAsync(baseAPIUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken); //return the same page with an error message if the user is trying to call the API too many times if (response.StatusCode == HttpStatusCode.TooManyRequests) { TempData["TooManyRequests"] = "Too many requests. Please slow down with your requests"; return(Partial("_CreateEditBoardMeetingPartial", this)); } //ensure success status code else throw an exception response.EnsureSuccessStatusCode(); //read the response content into a stream var streamContent = await response.Content.ReadAsStreamAsync(); //deserialize the stream into an object (see StreamExtensions on how this is done) boardMeeting = streamContent.ReadAndDeserializeFromJson <BoardMeetingViewDto>(); } catch (HttpRequestException ex) { _logger.LogError($"An error occured accessing the API. Url: {HttpContext.Request.GetDisplayUrl()}" + $" Error Message: {ex.Message}"); //either the API is not running or an error occured on the server TempData["Error"] = "An error occured while processing your request. Please try again later."; return(Partial("_CreateEditBoardMeetingPartial", this)); } //see startup in AddMvc for how this partial is fetched //this was an answer found at https://softdevpractice.com/blog/asp-net-core-mvc-ajax-modals/ return(Partial("_CreateEditBoardMeetingPartial", this)); }
private BoardMeetingViewDto GetTestBoardMeetingViewDto() { var boardMeetings = new BoardMeetingViewDto() { Id = new Guid("e77551ba-78e2-4a36-8754-3ea5f12e1619"), Title = "Test1", Description = "Test1", DaysOld = 0, Created = DateTime.Now, ScheduledTime = DateTime.Now, OwnerName = "ABC", OwnerEmail = "*****@*****.**", ScheduledLocation = "a" }; return(boardMeetings); }
public async Task <IActionResult> OnGetICALFile(CancellationToken cancellationToken) { var baseAPIUrl = $"api/boardmeetings/{Id}"; try { //call the api with a GET request //ensure to set the httpcompletion mode to response headers read //this allows the response to be read as soon as content starts arriving instead of having to wait //until the entire response is read //with this option, we can read the response content into a stream and deserialize it var response = await(await _apiClient.WithGETOnlyAccessAuthorization()).GetAsync(baseAPIUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken); //return the same page with an error message if the user is trying to call the API too many times if (response.StatusCode == HttpStatusCode.TooManyRequests) { TempData["TooManyRequests"] = "Too many requests. Please slow down with your requests"; return(RedirectToPage("/Index")); } //ensure success status code else throw an exception response.EnsureSuccessStatusCode(); //read the response content into a stream var streamContent = await response.Content.ReadAsStreamAsync(); //deserialize the stream into an object (see StreamExtensions on how this is done) boardMeeting = streamContent.ReadAndDeserializeFromJson <BoardMeetingViewDto>(); } catch (HttpRequestException ex) { _logger.LogError($"An error occured accessing the API. Url: {HttpContext.Request.GetDisplayUrl()}" + $" Error Message: {ex.Message}"); //either the API is not running or an error occured on the server TempData["Error"] = "An error occured while processing your request. Please try again later."; return(RedirectToPage("/Index")); } StringBuilder sb = new StringBuilder(); string DateFormat = "yyyyMMddTHHmmssZ"; string now = DateTime.Now.ToUniversalTime().ToString(DateFormat); sb.AppendLine("BEGIN:VCALENDAR"); sb.AppendLine("PRODID:-//GENERIC HOA//EN"); sb.AppendLine("VERSION:2.0"); sb.AppendLine("METHOD:PUBLISH"); DateTime dtStart = Convert.ToDateTime(boardMeeting.ScheduledTime); DateTime dtEnd = Convert.ToDateTime(boardMeeting.ScheduledTime.AddHours(1)); sb.AppendLine("BEGIN:VEVENT"); sb.AppendLine("DTSTART:" + dtStart.ToUniversalTime().ToString(DateFormat)); sb.AppendLine("DTEND:" + dtEnd.ToUniversalTime().ToString(DateFormat)); sb.AppendLine("DTSTAMP:" + now); sb.AppendLine("UID:" + Guid.NewGuid()); sb.AppendLine("CREATED:" + now); sb.AppendLine("X-ALT-DESC;FMTTYPE=text/html:" + "HOA Board Meeting"); sb.AppendLine("DESCRIPTION:" + boardMeeting.Description); sb.AppendLine("LAST-MODIFIED:" + now); sb.AppendLine("LOCATION:" + boardMeeting.ScheduledLocation); sb.AppendLine("SEQUENCE:0"); sb.AppendLine("STATUS:CONFIRMED"); sb.AppendLine("SUMMARY:" + boardMeeting.Title); sb.AppendLine("TRANSP:OPAQUE"); sb.AppendLine("END:VEVENT"); sb.AppendLine("END:VCALENDAR"); byte[] calendarBytes = Encoding.UTF8.GetBytes(sb.ToString()); return(File(calendarBytes, "text/calendar", "hoameeting.ics")); }
public async Task <IActionResult> OnPostUploadMeetingMinuteAsync(CancellationToken cancellationToken, [FromForm] RequiredFileDto FileUploaded) { if (!ModelState.IsValid) { //need to manually add this due to a bug in the model binding process for .net core //see issue here https://github.com/JeremySkinner/FluentValidation/issues/1029 ModelState.AddModelError("FileUploaded.FileToUpload", ModelState.Keys.Where(k => k == "FileToUpload").Select(k => ModelState[k].Errors[0].ErrorMessage).First()); //set the pagemodel property to be the values submitted by the user //not doing this will cause all model state errors to be lost this.FileUploaded = FileUploaded; return(Partial("_UploadMeetingMinutePartial", this)); } var baseAPIUrl = $"api/boardmeetings/{Id}"; try { //call the api with a GET request //ensure to set the httpcompletion mode to response headers read //this allows the response to be read as soon as content starts arriving instead of having to wait //until the entire response is read //with this option, we can read the response content into a stream and deserialize it var response = await(await _apiClient.WithAuthorization()).GetAsync(baseAPIUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken); //return the same page with an error message if the user is trying to call the API too many times if (response.StatusCode == HttpStatusCode.TooManyRequests) { TempData["TooManyRequests"] = "Too many requests. Please slow down with your requests"; return(Partial("_UploadMeetingMinutePartial", this)); } //ensure success status code else throw an exception response.EnsureSuccessStatusCode(); //read the response content into a stream var streamContent = await response.Content.ReadAsStreamAsync(); //deserialize the stream into an object (see StreamExtensions on how this is done) boardMeeting = streamContent.ReadAndDeserializeFromJson <BoardMeetingViewDto>(); } catch (HttpRequestException ex) { _logger.LogError($"An error occured accessing the API. Url: {HttpContext.Request.GetDisplayUrl()}" + $" Error Message: {ex.Message}"); //either the API is not running or an error occured on the server TempData["Error"] = "An error occured while processing your request. Please try again later."; return(Partial("_UploadMeetingMinutePartial", this)); } //GetFileTypeExtension returns a tuple that is deconstructed into separate variables var(FileType, FileExtension) = _fileValidate.GetFileTypeExtension(FileUploaded.FileToUpload); try { //if meeting minute id is null, it does not exist so do a post request if (boardMeeting.MeetingMinuteId == null) { baseAPIUrl = $"api/boardmeetings/{Id}/meetingminutes"; //generate the file name instead of letting the user provide one FileName = $"MeetingMinute_{DateTime.Now.ToString("MM-dd-yyyy_HH-mm-ss")}{FileExtension}"; //set the MeetingMinute filename here as otherwise it will be null //this property is generated by the server and not provided by the user var meetingToCreate = new MeetingMinuteInputDto { FileName = this.FileName }; //get the response with authorization as the API endpoint requires an authenticated user var response = await(await _apiClient.WithAuthorization()).PostAsJsonAsync <MeetingMinuteInputDto>(baseAPIUrl, meetingToCreate, cancellationToken); //return the same page with an error message if the user is trying to call the API too many times if (response.StatusCode == HttpStatusCode.TooManyRequests) { TempData["TooManyRequests"] = "Too many requests. Please slow down with your requests"; return(Partial("_UploadMeetingMinutePartial", this)); } //ensure success status code else throw an exception response.EnsureSuccessStatusCode(); } else { //meeting minute already exists so just need to upload the new file //no need to update anything as we will re-use the existing file name FileName = boardMeeting.FileName; } } catch (HttpRequestException ex) { _logger.LogError($"An error occured accessing the API. Url: {HttpContext.Request.GetDisplayUrl()}" + $" Error Message: {ex.Message}"); //either the API is not running or an error occured on the server TempData["Error"] = "An error occured while processing your request. Please try again later."; return(Partial("_UploadMeetingMinutePartial", this)); } //MeetingMinute was created/updated successfully so can upload file to blob storage var blobFileToUpload = _azureBlob.GetAzureBlobFileReference(FileName, AzureBlobFolder); //set the content type of the blob file so that downloads suggest correct file type to save as blobFileToUpload.Properties.ContentType = FileType; //upload the file to Azure await _azureBlob.UploadAzureBlobFileAsync(FileUploaded.FileToUpload, blobFileToUpload); //if successful, return the partial view which will have the IsValid value set to true by default //this is because ajax is used to post the form rather than a submit button return(Partial("_UploadMeetingMinutePartial", this)); }
public async Task <IActionResult> OnPostDeleteMeetingAsync(CancellationToken cancellationToken) { var baseAPIUrl = $"api/boardmeetings/{Id}"; //get the board meeting and verify if a file exists try { //call the api with a GET request //ensure to set the httpcompletion mode to response headers read //this allows the response to be read as soon as content starts arriving instead of having to wait //until the entire response is read //with this option, we can read the response content into a stream and deserialize it var response = await(await _apiClient.WithAuthorization()).GetAsync(baseAPIUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken); //return the same page with an error message if the user is trying to call the API too many times if (response.StatusCode == HttpStatusCode.TooManyRequests) { TempData["TooManyRequests"] = "Too many requests. Please slow down with your requests"; return(Partial("_CreateEditBoardMeetingPartial", this)); } //ensure success status code else throw an exception response.EnsureSuccessStatusCode(); //read the response content into a stream var streamContent = await response.Content.ReadAsStreamAsync(); //deserialize the stream into an object (see StreamExtensions on how this is done) boardMeeting = streamContent.ReadAndDeserializeFromJson <BoardMeetingViewDto>(); //set the file name if its not null if (boardMeeting.FileName != null) { FileName = boardMeeting.FileName; } //get the response with authorization as the API endpoint requires an authenticated user var responseForDelete = await(await _apiClient.WithAuthorization()).DeleteAsync(baseAPIUrl, cancellationToken); //return the same page with an error message if the user is trying to call the API too many times if (responseForDelete.StatusCode == HttpStatusCode.TooManyRequests) { TempData["TooManyRequests"] = "Too many requests. Please slow down with your requests"; return(Content("Error")); } //ensure success status code else throw an exception responseForDelete.EnsureSuccessStatusCode(); } catch (HttpRequestException ex) { _logger.LogError($"An error occured accessing the API. Url: {HttpContext.Request.GetDisplayUrl()}" + $" Error Message: {ex.Message}"); //either the API is not running or an error occured on the server TempData["Error"] = "An error occured while processing your request. Please try again later."; return(Content("Error")); } //after ensuring that the meeting is deleted, delete the file from blob storage if (FileName != null) { var blobToDelete = _azureBlob.GetAzureBlobFileReference(FileName, AzureBlobFolder); await _azureBlob.DeleteAzureBlobFileAsync(blobToDelete); } return(Content("Success")); }