generated from karsten.jeppesen/KAJE-Template
Quizzer-8: Migrating to .NET 10
This commit is contained in:
338
Quizzer-8/Quizzer/Pages/Questions.cshtml.cs
Normal file
338
Quizzer-8/Quizzer/Pages/Questions.cshtml.cs
Normal file
@@ -0,0 +1,338 @@
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Newtonsoft.Json;
|
||||
using Quizzer.Extensions;
|
||||
using Quizzer.Models;
|
||||
using Quizzer.OpenIDConnect;
|
||||
using Quizzer.Persistens;
|
||||
using System.Diagnostics;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Text;
|
||||
|
||||
namespace Quizzer.Pages
|
||||
{
|
||||
public class QuestionsModel : PageModel
|
||||
{
|
||||
[BindProperty]
|
||||
public OpenIDUCNData ucnData { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public string UserID { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public string CatMenu { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public bool isSubmittable { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public List<Question> questionsInCat { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public List<MCQuestion> mcQuestionsInCat { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public MCQuestion questionCookie { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public IFormFile Upload { get; set; }
|
||||
|
||||
[BindProperty]
|
||||
public string myFullName { get; set; }
|
||||
|
||||
|
||||
private bool isDebug;
|
||||
private string KCUserID { get; set; }
|
||||
|
||||
private DbOps qManager = new DbOps();
|
||||
|
||||
private OpenIDConnectUtils OpenIDUtils = new();
|
||||
|
||||
private const string cookieName = "QuestionCookie";
|
||||
|
||||
private void GetMyCookie()
|
||||
{
|
||||
string jsonString = HttpContext.Request.Cookies[cookieName];
|
||||
if (jsonString != null)
|
||||
{
|
||||
questionCookie = JsonConvert.DeserializeObject<MCQuestion>(jsonString);
|
||||
return;
|
||||
}
|
||||
// Here if no cookie found
|
||||
questionCookie = new MCQuestion
|
||||
{
|
||||
QuestionText = "",
|
||||
AList = new List<Alternative> { new Alternative
|
||||
{
|
||||
Aok = false,
|
||||
Atxt = "",
|
||||
Counter = 0
|
||||
}
|
||||
}
|
||||
};
|
||||
// Save the new cookie
|
||||
SetMyCookie();
|
||||
}
|
||||
|
||||
private void SetMyCookie()
|
||||
{
|
||||
string jsonResult = JsonConvert.SerializeObject(questionCookie);
|
||||
Response.Cookies.Append(cookieName, jsonResult, new Microsoft.AspNetCore.Http.CookieOptions
|
||||
{
|
||||
Secure = true,
|
||||
HttpOnly = true,
|
||||
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None,
|
||||
});
|
||||
}
|
||||
|
||||
private void RemoveMyCookie()
|
||||
{
|
||||
Response.Cookies.Delete(cookieName);
|
||||
}
|
||||
|
||||
|
||||
public void AlwaysIn()
|
||||
{
|
||||
isDebug = MyConfiguration.Get()["DEBUG"] == "Y";
|
||||
string? ucnDataJson = OpenIDUtils.GetJwtClaim(HttpContext, "ucn");
|
||||
|
||||
KCUserID = OpenIDUtils.GetJwtClaim(HttpContext, "sub");
|
||||
ucnData = JsonConvert.DeserializeObject<OpenIDUCNData>(ucnDataJson);
|
||||
UserID = OpenIDUtils.GetJwtClaim(HttpContext, "email").HashSHA256();
|
||||
myFullName = OpenIDUtils.GetJwtClaim(HttpContext, "name");
|
||||
GetMyCookie();
|
||||
}
|
||||
|
||||
public void AlwaysOut()
|
||||
{
|
||||
CatMenu = qManager.MakeCList(UserID, "DropDown", questionCookie.Category);
|
||||
isSubmittable = true;
|
||||
if (questionCookie.Category == "" || questionCookie.Category == null)
|
||||
{
|
||||
isSubmittable = false;
|
||||
questionsInCat = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
questionsInCat = qManager.GetQuestions(questionCookie.Category);
|
||||
mcQuestionsInCat = new();
|
||||
foreach ( var item in questionsInCat )
|
||||
{
|
||||
MCQuestion newQ= new MCQuestion();
|
||||
newQ.QuestionID = item.QuestionID;
|
||||
newQ.QuestionText = item.QuestionText;
|
||||
newQ.AList = JsonConvert.DeserializeObject<List<Alternative>>(item.ContentJson);
|
||||
mcQuestionsInCat.Add(newQ);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
isSubmittable = questionCookie.QuestionText != "" && questionCookie.AList.Where(x => x.Aok == true).Count() == 1 && questionCookie.Category != null;
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
RemoveMyCookie();
|
||||
GetMyCookie();
|
||||
isSubmittable = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will attempt to extract questions encoded in the Eiken format.
|
||||
/// The answer letters (A,B,C etc.) and the word "ANSWER" must be capitalised as shown below, otherwise the import will fail.
|
||||
/// What is True?
|
||||
/// A. True
|
||||
/// B. False
|
||||
/// ANSWER: A
|
||||
///
|
||||
/// What is True?
|
||||
/// A) True
|
||||
/// B) False
|
||||
/// ANSWER: A
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="theFile">
|
||||
/// A byte array of the uploaded text file
|
||||
/// </param>
|
||||
private void EikenDecode(byte[] theFile)
|
||||
{
|
||||
string[] lines = System.Text.Encoding.Default.GetString(theFile).Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
|
||||
char state = 'q'; // state: looking for question text
|
||||
MCQuestion theQuestion = new(); ;
|
||||
foreach (string theLine in lines)
|
||||
{
|
||||
if (state == 'q')
|
||||
{
|
||||
if (theLine.Length == 0) continue;
|
||||
// something here
|
||||
theQuestion = new();
|
||||
theQuestion.QuestionText = theLine;
|
||||
state = 'A'; // looking for first alternative
|
||||
continue;
|
||||
}
|
||||
if (theLine[0] == state && (theLine[1] == '.' || theLine[1] == ')'))
|
||||
{ // alternative
|
||||
theQuestion.AList.Add(new Alternative
|
||||
{
|
||||
Aok = false,
|
||||
Atxt = theLine.Substring(3, theLine.Length - 3),
|
||||
});
|
||||
state++;
|
||||
continue;
|
||||
}
|
||||
if (theLine.StartsWith("ANSWER: "))
|
||||
{
|
||||
int correct = theLine[8] - 'A';
|
||||
theQuestion.AList[correct].Aok = true;
|
||||
theQuestion.Category = questionCookie.Category;
|
||||
theQuestion.QuestionType = questionCookie.QuestionType;
|
||||
qManager.InsertMCQuestion(theQuestion);
|
||||
state = 'q';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IActionResult OnGet()
|
||||
{
|
||||
AlwaysIn();
|
||||
AlwaysOut();
|
||||
if (ucnData.theRole != "teacher" && ucnData.theRole != "developer") return Redirect("/");
|
||||
return Page();
|
||||
}
|
||||
|
||||
|
||||
// Will also accept ChatGPT/CoPilot format
|
||||
//What is the main difference between IPv4 and IPv6?
|
||||
//
|
||||
//A) IPv4 uses 32-bit addresses, IPv6 uses 128-bit addresses
|
||||
//B) IPv4 supports multicast, IPv6 does not
|
||||
//C) IPv4 is used for local networks, IPv6 is used for the internet
|
||||
//D) IPv4 uses hexadecimal notation, IPv6 uses binary notation
|
||||
//E) IPv4 is faster than IPv6
|
||||
|
||||
private void OnPostScan(string qText)
|
||||
{
|
||||
char[] delim = { '\r', '\n' };
|
||||
string[] myStrings = qText.Split(delim);
|
||||
int counter = 0;
|
||||
// Identify the Question part
|
||||
while (counter < myStrings.Length)
|
||||
{
|
||||
if (myStrings[counter] != "")
|
||||
{
|
||||
questionCookie.QuestionText = myStrings[counter];
|
||||
counter++;
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
if (counter >= myStrings.Length) return;
|
||||
// start from scratch
|
||||
questionCookie.AList.Clear();
|
||||
while (counter < myStrings.Length)
|
||||
{
|
||||
if (myStrings[counter] != "")
|
||||
{
|
||||
string alt = myStrings[counter].Trim();
|
||||
if (alt.Length > 3)
|
||||
if (alt[1] == ')' || alt[1] == '.')
|
||||
alt = alt.Remove(0, 3);
|
||||
questionCookie.AList.Add(new Alternative
|
||||
{
|
||||
Atxt = alt,
|
||||
Aok = false
|
||||
});
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
questionCookie.AList.Add(new Alternative
|
||||
{
|
||||
Atxt = "",
|
||||
Aok = false
|
||||
});
|
||||
}
|
||||
|
||||
public IActionResult OnPost(string action = "NA", string tochange = "", string changeTo = "", string newCategory = "")
|
||||
{
|
||||
AlwaysIn();
|
||||
if (ucnData.theRole != "teacher" && ucnData.theRole != "developer") return Redirect("/");
|
||||
switch (action)
|
||||
{
|
||||
case "changeCategory":
|
||||
questionCookie.Category = newCategory;
|
||||
break;
|
||||
case "changeQText":
|
||||
questionCookie.QuestionText = changeTo;
|
||||
break;
|
||||
case "changeAText":
|
||||
questionCookie.AList[int.Parse(tochange)].Atxt = changeTo;
|
||||
if (int.Parse(tochange) == questionCookie.AList.Count - 1)
|
||||
{
|
||||
questionCookie.AList.Add(new Alternative
|
||||
{
|
||||
Atxt = "",
|
||||
Aok = false
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "changeAOk":
|
||||
// tochange: "0" changeTo: on
|
||||
questionCookie.AList[int.Parse(tochange)].Aok = (changeTo == "on");
|
||||
break;
|
||||
|
||||
case "create":
|
||||
qManager.InsertMCQuestion(questionCookie);
|
||||
questionCookie.QuestionText = "";
|
||||
questionCookie.QuestionID = "";
|
||||
questionCookie.AList.Clear();
|
||||
break;
|
||||
case "scan":
|
||||
OnPostScan(tochange);
|
||||
break;
|
||||
case "delete":
|
||||
if (tochange != "") qManager.DeleteQuestion(tochange);
|
||||
break;
|
||||
case "download":
|
||||
Cat cat = qManager.GetCat(questionCookie.Category);
|
||||
string output = qManager.ExportQuestionsEiken(questionCookie.Category);
|
||||
string fileName = cat.Txt + "-Eiken.txt";
|
||||
/* Not such good an idea. just keep as subjects */
|
||||
/*
|
||||
while (cat.CParentId != "/")
|
||||
{
|
||||
cat = qManager.GetCat(cat.CParentId);
|
||||
fileName = cat.Txt + "-" + fileName;
|
||||
}
|
||||
*/
|
||||
var contentType = "text/plain";
|
||||
var bytes = Encoding.UTF8.GetBytes(output);
|
||||
var result = new FileContentResult(bytes, contentType);
|
||||
result.FileDownloadName = fileName;
|
||||
SetMyCookie();
|
||||
return result;
|
||||
break;
|
||||
case "upload": // https://www.learnrazorpages.com/razor-pages/forms/file-upload may benefit from async
|
||||
if (Upload != null)
|
||||
{
|
||||
Stream myStream = Upload.OpenReadStream();
|
||||
byte[] myBuffer = new byte[myStream.Length];
|
||||
myStream.Position = 0;
|
||||
myStream.Read(myBuffer, 0, myBuffer.Length);
|
||||
myStream.Close();
|
||||
EikenDecode(myBuffer);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CatMenu = qManager.MakeCList(UserID, "DropDown", questionCookie.Category);
|
||||
isSubmittable = questionCookie.AList.Where(x => x.Aok == true).Count() == 1 && questionCookie.Category != null;
|
||||
SetMyCookie();
|
||||
AlwaysOut();
|
||||
return Page();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user