0

I am trying to create an entity that has subitems and am having issues with passing the model back and forth.

I have an entity RiskAssessnent that contains a list of Risk entities.

public class RiskAssessment
{
    public int Id { get; set; }

    public DateTime Date { get; set; }

    public ICollection<Risk> Risks { get; set; }

    public int ResidentId { get; set; }

    public Resident Resident { get; set; }

    public int EmployeeId { get; set; }

    public Employee Employee { get; set; }
}

public class Risk
{
    public int Id { get; set; }

    public string Description { get; set; }

    public int RiskAssessmentId { get; set; }

    public RiskAssessment RiskAssessment { get; set; }
}

here is my view for creating a RiskAssessment:

@model CareHomeMvc6.Models.RiskAssessmentViewModels.RiskAssessmentViewModel

@{
    ViewData["Title"] = "Create";
}

<a class="btn btn-default" asp-action="Index" asp-route-residentId="@Model.ResidentId">Back to List</a>

<div class="page-header">
    <h1>Create a Risk Assessment</h1>
</div>

<form asp-action="Create">
<div class="form-horizontal">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    @Html.HiddenFor(m => m.EmployeeId)
    @Html.HiddenFor(m => m.ResidentId)
    <div class="form-group">
        <label asp-for="Date" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            @Html.EditorFor(m => m.Date, new { @class = "form-control" })
            <span asp-validation-for="Date" class="text-danger" />
        </div>
    </div>

    @foreach(var risk in Model.Risks)
    {
        <h3>@risk.Description</h3>
    }

    <p>
        <a class="btn btn-success" asp-action="CreateRisk">Create</a>
    </p>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
</form>

@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

and here is the controller:

    public IActionResult CreateRisk(RiskAssessmentViewModel riskAssessmentViewModel)
    {
        var vm = new CreateRiskViewModel
        {
            RiskAssessment = riskAssessmentViewModel,
            Risk = new Risk()
        };

        return View(vm);
    }

and the ViewModel:

public class RiskAssessmentViewModel
{
    public RiskAssessmentViewModel()
    {
        this.Risks = new List<Risk>();

        this.Risks.Add(new Risk
        {
            Id = 1,
            Description = "blah",
            PotentialRisk = "blah"
        });
    }

    public int Id { get; set; }

    [Display(Name = "Date")]
    [DataType(DataType.Date)]
    [Required]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime Date { get; set; }

    public ICollection<Risk> Risks { get; set; }

    public int ResidentId { get; set; }

    public int EmployeeId { get; set; }
}

Sorry for all the code so far!

I was attempting to keep passing the ViewModel back and forth until all items have been created but within the CreateRisk action the ResidentId and EmployeeId are 0 therefore not being set, although I do get the collection of risks. If I click submit on the form which encapsulates everything then they are set. Is there any reason the hidden items are being sent to the form submit but not the link action?

I realise there are JS solutions to doing dynamic lists but I wanted to stay away from it as the page navigation is acceptable, the form will when finished require a lot of data entry for a Risk.

Any help with this would be greatly appreciated.

Thanks

  • What do you mean _but not the link action_? Are you referring to `Create`? That is just making a GET to your `CreateRisk` method (and its not passing any values to it) –  Oct 14 '16 at 11:44
  • Thanks @StephenMuecke that is correct, should I be instead doing something like a form within a form? I am new to MVC and so far have had no trouble as I have stuck to basic CRUD operations and this is the first problem of this type – user1370257 Oct 14 '16 at 11:53
  • Your code makes no sense. Refer [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) for how to create an item with a collection of sub-items. –  Oct 14 '16 at 11:58
  • But if you do not want to use any javascript. The you need completely separate views to create/edit a `RiskAssessment` and a `Risk`. You create the `RiskAssessment` and get its ID. Then you pass that ID to the view that create its `Risk`. There is no point having a link in the edit page of `RiskAssessment` to create a new `Risk` - a user starts editng it, then clicks the link and all their edits are lost. –  Oct 14 '16 at 12:00
  • It was my intention to create seperate views for each but I did not want to save the assessment until the risks had been added, therefore there would be no id at that point to pass, am I trying to do something that is not possible? – user1370257 Oct 14 '16 at 12:18
  • Not impossible, but crazy. And you would need to use javascript to build build the `href` attribute of the link to pass all the edited values of the `RiskAssessment` to the `CreateRisk()` method so that you can continuously reconstruct it. Dreadful performance, no validation, will almost certainly throw an except because you will exceed the query string limit, and you need javascript anyway. –  Oct 14 '16 at 12:24
  • Thanks @StephenMuecke for taking the time to stop me going further down the rabbit hole, I come from a desktop application background so have never had to worry about this sort of thing before. Is the convention to create the parent item and then once saved add child elements? – user1370257 Oct 14 '16 at 12:30
  • You an do that, or you can create and save them all at once which will give better performance (see the link in my first comment). –  Oct 14 '16 at 21:22

0 Answers0