Im writing a small web app to organise some file. Each document is represented by:
public class Document
{
public Guid Id { get; set; }
[Required]
[Display(Name = "Document Name:")]
public string Name { get; set; }
[Required]
[Display(Name = "Type:")]
[EnumDataType(typeof(DocumentTypeEnum))]
public DocumentTypeEnum DocType { get; set; }
public DateTime? CreatedDate { get; set; }
public string? Description { get; set; }
public virtual ICollection<DocumentVersion>? Versions { get; set; }
[Required]
[Display(Name = "Document Category")]
public virtual DocumentCategory Category { get; set; }
}
I plan to use 'DocumentCategory' as a folder location - I.e House-->Bills etc. This is represented by the following class:
public class DocumentCategory
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public virtual DocumentCategory Parent { get; set; }
public virtual ICollection<DocumentCategory> Children { get; set; }
}
I have a simple web form to create a new document to store in the database, and use a view model below as I want to display a list of categories (using JsTree) to select the correct filing location.
public class NewDocumentViewModel
{
public Document NewDocument { get; set;}
public IEnumerable<DocumentCategory>? Categories { get; set; }
}
However, when I go to save my form, the view-model is invalid, and fails on the document category part of the model.
Using JStree I output a <ul> and set the id to the Category.ID (INT), and store this in a input field using the OnSelectedChange event of the JSTree.
<h3>Document Category:</h3>
<div class="form-floating">
<div class="col-md-4" id="CatTreeContainer">
<ul class="CatTree">
<li class="DocumentCategory" id="0">
Please Select . . .
<ul>
@{ShowTree(Model.Categories);}
</ul>
</li>
</ul>
</div>
<input asp-for="NewDocument.Category.Id" readonly class="form-control" id="DocumentCategoryInput" />
<span asp-validation-for="NewDocument.Category.Id" class="text-danger"></span>
</div>
My controller POST method looks like this:
[HttpPost]
[ValidateAntiForgeryToken]
[ActionName("New-Document")]
public async Task<ActionResult> NewDocument(NewDocumentViewModel viewModel)
{
if (!ModelState.IsValid)
{
return View(viewModel);
}
var newDocument = new Document();
var DateNow = new DateTime();
DateNow = DateTime.Now;
newDocument.Id = Guid.NewGuid();
newDocument.Name = viewModel.NewDocument.Name;
newDocument.Description = viewModel.NewDocument.Description;
newDocument.CreatedDate = DateNow;
newDocument.DocType = DocumentTypeEnum.File;//Hardcode file as type initially. TODO: Update to link option.
_documentDbContext.Documents.Add(newDocument);
await _documentDbContext.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
When I POST the form, the view model is not valid and then throws an exception.
My question is, how do I set the document.category using the category.id?
Ive really ran a ground here and can't work out what to try next. Some pointers would be helpful.
Thanks James