Home > Software design >  Getting ModelState.IsValid == false on passed objects
Getting ModelState.IsValid == false on passed objects

Time:05-24

I'm getting an error saying "Calculations field is required"

here is my Expenditures model:

public class ExpendituresModel : PageModel
    {
        private readonly ISqlData _db;

        public ExpendituresModel(ISqlData db)
        {
            _db = db;
        }

        [BindProperty]
        public Project Project { get; set; }
        public List<Expenditure> Expenditures { get; set; } = null!;

        [BindProperty]
        public WipCommentCalculation WipCommentCalculation { get; set; }

      //  public Calculations Calculations { get; set; } = new Calculations();

        public int ProjectId { get; set; }
        

        public async Task OnGetAsync(int projectId)
        {
            Project = await _db.GetProjectDataAsync(projectId);

            //Expenditures = await _db.GetExpendituresByProjectIdAsync(projectId);

            var calculations = await _db.GetCalculationByProjectIdAsync(projectId);

            WipCommentCalculation = new WipCommentCalculation
            {
                Calculations = calculations,
                Comments = null,
                ProjectId = projectId
            };
        }

        public IActionResult OnPost()
        {
            if (ModelState.IsValid ==false)
            {
                return RedirectToPage("./Expenditures");
            }

            return RedirectToPage("./Expenditures");
        }
    }

and here the view for it:

@page
@using DataAccessLibrary.Models
@model WorkInProgress.Pages.ExpendituresModel
@{
    ViewData["Title"] = "Expenditures";
}


<h1>Project Information</h1>

<div >
    <div >
        <div >
            <div >
                <div >
                    <h5 >Project Number</h5>
                    <p >@Model.Project.ProjectNumber</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >Project Name</h5>
                    <p >@Model.Project.Name</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >Contract Type</h5>
                    <p >@Model.Project.ContractType</p>
                </div>
            </div>
        </div>
        <div >
            <div >
                <div >
                    <h5 >Currency</h5>
                    <p >@Model.Project.ProjFuncCurrencyCode</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >Project Accountant</h5>
                    <p >@Model.Project.PaName</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >Project Manager</h5>
                    <p >@Model.Project.PmName</p>
                </div>
            </div>
        </div>

    </div>
</div>

<h2>Project Summary</h2>

<div >
    <div >
        <div >
            <div >
                <div >
                    <h5 >Fiscal Month</h5>
                    <p >@Model.Project.FiscalMonth</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >Currency</h5>
                    <p >@Model.Project.ProjFuncCurrencyCode</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >Revenue</h5>
                    <p >@($"{Model.Project.PtdRevenue:0,0.00}")</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >Bill Amount</h5>
                    <p >@($"{Model.Project.PtdBilled:0,0.00}")</p>
                </div>
            </div>
        </div>
        <div >
            <div >
                <div >
                    <h5 >Unbilled/Unearned (WIP Amount)</h5>
                    <p >@($"{Model.Project.PtdUnbilled:0,0.00}")</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >POC Amount/Adjustment</h5>
                    <p >@($"{Model.Project.PocAmount:0,0.00}")</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >WIP Figure ( /-)</h5>
                    <p >@($"{Model.Project.WipAmount:0,0.00}")</p>
                </div>
            </div>
            <div >
                <div >
                    <h5 >NB Labor</h5>
                    <p >@($"{Model.Project.NBCostLaborPtd:0,0.00}")</p>
                </div>
            </div>
        </div>
    </div>
</div>

<form method="post">
    <div >
        <h2>Expenditures</h2>
        <table >
            <thead>
            <tr>
                <th></th>
                <th>Billable</th>
                <th>Unbilled</th>
                <th>Billing Hold</th>
                <th>Project Accountant explanation</th>
                <th>Project Accounting Manager comments</th>
            </tr>
            </thead>
            <tbody>
            
            <tr>
                <div >
                    <td>Labor</td>
                    <td>@($"{Model.WipCommentCalculation.Calculations.BillableLabor:0,0.00}")</td>
                    <td>@($"{Model.WipCommentCalculation.Calculations.UnbilledLabor:0,0.00}")</td>
                    <td>@($"{Model.WipCommentCalculation.Calculations.BillingHoldLabor:0,0.00}")</td>
                    @*<td><textarea  asp-for="WipCommentCalculation.Comments.PALaborComment" id="exampleFormControlTextarea1" rows="1"></textarea></td>*@

                    <td><input asp-for="WipCommentCalculation.Comments.PALaborComment"/></td>
                    <td><input asp-for="WipCommentCalculation.Comments.PMLaborComment"/></td>
                </div>
            </tr>
            
            <tr>
                <td>Non-Labor</td>
                <td>@($"{Model.WipCommentCalculation.Calculations.BillableNonLabor:0,0.00}")</td>
                <td>@($"{Model.WipCommentCalculation.Calculations.UnbilledNonLabor:0,0.00}")</td>
                <td>@($"{Model.WipCommentCalculation.Calculations.BillingHoldNonLabor:0,0.00}")</td>
                <td><input asp-for="WipCommentCalculation.Comments.PANonLaborComment"/></td>
                <td><input asp-for="WipCommentCalculation.Comments.PMNonLaborComment"/></td>
            </tr>
            <tr>
                <td>SubContractor</td>
                <td>@($"{Model.WipCommentCalculation.Calculations.BillableSubcontractor:0,0.00}")</td>
                <td>@($"{Model.WipCommentCalculation.Calculations.UnbilledSubcontractor:0,0.00}")</td>
                <td>@($"{Model.WipCommentCalculation.Calculations.BillingHoldSubcontractor:0,0.00}")</td>
                <td><input asp-for="WipCommentCalculation.Comments.PASubContractorComment"/></td>
                <td><input asp-for="WipCommentCalculation.Comments.PMSubcontractorComment"/></td>
            </tr>
            <tr>
                <td>Totals</td>
                <td>@($"{(Model.WipCommentCalculation.Calculations.BillableLabor   Model.WipCommentCalculation.Calculations.BillableNonLabor   Model.WipCommentCalculation.Calculations.BillableSubcontractor):0,0.00}")</td>
                <td>@($"{(Model.WipCommentCalculation.Calculations.UnbilledLabor   Model.WipCommentCalculation.Calculations.UnbilledNonLabor   Model.WipCommentCalculation.Calculations.UnbilledSubcontractor):0,0.00}")</td>
                <td>@($"{(Model.WipCommentCalculation.Calculations.BillingHoldLabor   Model.WipCommentCalculation.Calculations.BillingHoldNonLabor   Model.WipCommentCalculation.Calculations.BillingHoldSubcontractor):0,0.00}")</td>
                <td></td>
                <td></td>
            </tr>
            </tbody>
        </table>
    </div>
    <div >
        <input type="submit" value="Save" />
    </div>
</form>
@section Scripts
{
    @{ await Html.RenderPartialAsync("Shared/_ValidationScriptsPartial");}
}

I'm not sure if I should do in a different way the setup of the objects,

I have a calculations but is coming as null in the object when calling the OnPost enter image description here

I want to later save this object with the comments in the database, but the model state from the form is coming as not valid.

CodePudding user response:

I don't know how to explain it well. For example, I copied your code in my side and I create a model class like below:

namespace WebApp.Model
{
    public class WipCommentCalculation
    {
        public int ProjectId { get; set; }
        public Calculations Calculations { get; set; }
    }

    public class Calculations {
        public decimal BillableLabor { get; set; }
        public decimal UnbilledLabor { get; set; }
        public decimal BillingHoldLabor { get; set; }
        public decimal UnbilledSubcontractor { get; set; }
        public decimal BillingHoldSubcontractor { get; set; }
        public decimal BillableNonLabor { get; set; }
        public decimal UnbilledNonLabor { get; set; }
        public decimal BillingHoldNonLabor { get; set; }
        public decimal BillableSubcontractor { get; set; }
    }

    public class Project {
        public string FiscalMonth { get; set; }
        public string PtdBilled { get; set; }
    }
}

Then when I keep your code in my view, I will also get it invalid, but if I used form dom like this, then it can be valid:

<form method="post">
   <div>
        <div>
            <label for="BillableLabor">BillableLabor:</label>
            <input type="text" asp-for="@Model.WipCommentCalculation.Calculations.BillableLabor" value=""  />
        </div>
        <div>
            <label for="UnbilledLabor">UnbilledLabor:</label>
            <input type="text" asp-for="@Model.WipCommentCalculation.Calculations.UnbilledLabor" value=""  />
        </div>
    </div>
    <div >
        <input type="submit" value="Save" />
    </div>
</form>

I think you used ModelState.IsValid then you should obey the submit rule. Using tag helper asp-for="@Model.WipCommentCalculation.Calculations.BillableLabor" for the elements.

enter image description here

  • Related