I have a C# ASP.Net Core MVC Web-Application and I want to make two forms, where I can input a Model. My problem is, one of both work and the other one don't, and I don't understand why.
When I'm saying it doesn't work, I mean, that I get a null value in my LogInWordForm method and the one who works gets the value from the input of the form. (To add [HTTPPOST] in the controller and method="post" in the cshtml I already tried)
First of all my controller for both [GameController.cs -> C#]:
public class GameController : Controller
{
// ToDo: Aus Singleton es machen, dass es auf User session bezogen ist.
private readonly ILogger<HomeController> _logger;
private Wheelchair instance;
public SimpleGameUser sgu;
public static string moneySession = "_money";
public static string questionSession = "_qanda";
// true : false
public IActionResult LogInWord()
{
if (!CheckSession()) return RedirectToAction("Index", "Home");
return View();
}
public IActionResult LogInWordForm(Word word)
{
if (!CheckSession()) return RedirectToAction("Index", "Home");
if (ModelState.IsValid)
{
string solution = this.sgu.wheelchair.word;
solution = solution.Replace("[", string.Empty);
solution = solution.Replace("]", string.Empty);
solution = solution.Replace("_", " ");
if (word.word.Equals(solution))
return View("GameOver", this.sgu);
else
{
ViewBag.Fail = "Word wasn't guessed.";
return View("WheelSpin", this.instance);
}
}
return View("LogInWord", word);
}
public IActionResult QuestionAndAnswer()
{
return CheckSession() ? View() : RedirectToAction("Home", "Index");
}
public IActionResult QAnswered(QandA qanda)
{
if (!CheckSession()) return RedirectToAction("Index", "Home");
if (sgu.money < qanda.risk)
{
ModelState.AddModelError("risk", "You haven't enough money to risk this!");
}
if (ModelState.IsValid)
{
if(qanda.userAnswer.Equals(qanda.variant))
{
this.sgu.money += qanda.risk;
} else
{
this.sgu.money -= qanda.risk;
}
HttpContext.Session.SaveObject<SimpleGameUser>(sgu, HomeController.userNow);
return WheelSpin();
}
return View("QuestionAndAnswer", qanda);
}
private bool CheckSession()
{
this.sgu = HttpContext.Session.GetObject<SimpleGameUser>(sessionName: HomeController.userNow);
this.instance = sgu.wheelchair;
return sgu != default;
}
Model of the first one who's not working [Word.cs -> C#]:
public class Word : IValidatableObject
{
[Required(ErrorMessage = "This field is required!")]
[Display(Name = "Your word to Log In")]
public string word { get; set; }
public string errors { get; set; } = ";";
public Word()
{
}
public Word(string word)
{
this.word = word;
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<ValidationResult> errors = new List<ValidationResult>();
List<Char> letters = Consonant.consonants;
letters.AddRange(Consonant.vocals);
letters.Add(',');
letters.Add('.');
letters.Add('_');
if (!letters.Any(s => this.word.Contains(s)))
errors.Add(new ValidationResult("There was an illegal character"));
return errors;
}
}
if someone wants to know: the validation should be testing if there are only characters and some allowed letters used, what I couldn't test yet.
View [LongInWord.cshtml]:
@model Word;
@{
}
<div id="layoutAuthentication_content">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-5">
<div class="card shadow-lg border-0 rounded-lg mt-5">
<div class="card-header"><h3 class="text-center font-weight-light my-4">Login</h3></div>
<div class="card-body">
<form asp-action="LogInWordForm" asp-controller="Game">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-floating mb-3">
<input asp-for="word" type="text" />
<label asp-for="word"></label>
<span asp-validation-for="word" class="text-danger"></span>
</div>
<br />
<input class="btn btn-primary" type="submit" />
</form>
</div>
</div>
</div>
</div>
</div>
</div>
Now of the one which is working:
Model [QandA.cs -> C#]:
public class QandA
{
public int ID { get; set; }
[BindProperty, Required(ErrorMessage = "This field can't be empty!")]
[Range(0, 1, ErrorMessage = "This wasn't one of the two given answers...")]
public bool userAnswer { get; set; }
public string question { get; set; }
public string answer0 { get; set; }
public string answer1 { get; set; }
public bool variant { get; set; }
[Required(ErrorMessage = "This field can't be empty!")]
[Range(0, int.MaxValue, ErrorMessage = "Please enter valid positiv integer Number above 0")]
[Display(Name = "Select your risk")]
public int risk { get; set; }
public QandA(string question, string answer0, string answer1, bool variant)
{
this.question = question;
this.answer0 = answer0;
this.answer1 = answer1;
this.variant = variant;
}
public QandA()
{
}
public bool correctAnswered()
{
return this.variant == this.userAnswer;
}
}
View [QuestionAndAnswer.cshtml]:
@model QandA;
@{
}
<div id="layoutAuthentication_content">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-5">
<div class="card shadow-lg border-0 rounded-lg mt-5">
<div class="card-header"><h3 class="text-center font-weight-light my-4">Login</h3></div>
<div class="card-body">
<form asp-action="QAnswered" asp-controller="Game">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<h3>@Model.question </h3>
<div class="form-group">
<label asp-for="userAnswer">Example select</label>
<div class="form-control">
<input asp-for="userAnswer" type="radio" class="btn-check" name="options-outlined" id="success-outlined" autocomplete="off" value="0" checked>
<label class="btn btn-outline-success form-control" for="success-outlined">@Model.answer0</label>
<input asp-for="userAnswer" type="radio" class="btn-check" name="options-outlined" id="danger-outlined" autocomplete="off" value="1">
<label class="btn btn-outline-danger form-control" for="danger-outlined">@Model.answer1</label>
</div>
</div>
<br />
<div class="form-group">
<label asp-for="risk"></label>
<input type="number" min="0" class="form-control" />
<span asp-validation-for="risk" class="text-danger"></span>
</div>
<input class="btn btn-primary" type="submit" />
</form>
</div>
</div>
</div>
</div>
</div>
</div>