Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
113 views
in Technique[技术] by (71.8m points)

entity framework - Insert into DB from ASP.Net form

I have an issue when I want to insert an object into the database.

My model is Colis class which has a foreign key to ZoneReserve (ZoneReserveId), which has a foreign key on Reserve (ReserveId).

In my form I choose an existing ZoneReserve and Reserve, but when I post my form, new lines are created in DB, in table ZoneReserve and Reserve. Entity framework do not retrieve the existing line or I don't know...

I don't know if I'm clear enough, sorry for my english ;)

Do you have any advice ? I'm stuck et I tried everything :(

Thank you guys

Colis Model Class :

   public class Colis
    {
        public int ColisId { get; set; }

        [Display(Name = "Code barre du colis")]
        public string CodeBarreColis { get; set; }

        public bool IndAVendreColis { get; set; }


        public virtual TypeColis TypeColis  { get; set; }


        [Display(Name = "Type de colis")]
        public int TypeColisId { get; set; }


        public ZoneReserve ZoneReserve { get; set; }

        [Display(Name = "Emplacement du colis")]
        public int ZoneReserveId { get; set; 
    }

ZoneReserve Model Class :

public class ZoneReserve
    {
        public int Id { get; set; }
        public string NomZoneReserve { get; set; }

        public Reserve Reserve { get; set; }
        public int ReserveId { get; set; }
    }

Reserve Model Class :

    public class Reserve
    {
        [Display(Name = "Réserve")]
        public int Id { get; set; }
        public string NomReserve { get; set; }

    }

My Action in ColisController :

        [HttpPost]
        public ActionResult CreerColis(Colis colis)
        {
            _context.Colis.Add(colis);
            _context.SaveChanges();

            return RedirectToAction("ListeColis");
        }

My Form in the view :

@using (Html.BeginForm("CreerColis", "Colis"))
{
    <div class="form-group">
        @Html.LabelFor(m => m.Colis.CodeBarreColis)
        @Html.TextBoxFor(m => m.Colis.CodeBarreColis, new { @class = "form-control" })
    </div>
    <div class="checkbox">
        <label>
            @Html.CheckBoxFor(m => m.Colis.IndAVendreColis) A vendre ?
        </label>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Colis.TypeColisId)
        @Html.DropDownListFor(m => m.Colis.TypeColisId, new SelectList(Model.TypeColis, "Id", "NomTypeColis"), "Selectionner un type", new { @class = "form -control" })
    </div>


    <div class="form-group">
        @Html.LabelFor(m => m.Colis.ZoneReserve.Reserve.Id)
        @Html.DropDownListFor(m => m.Colis.ZoneReserve.Reserve.Id, new SelectList(Model.Reserve, "Id", "NomReserve"), "Selectionner une zone", new { @class = "form -control" })

    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.Colis.ZoneReserveId)
        @Html.DropDownListFor(m => m.Colis.ZoneReserve.Id, new SelectList(Model.ZoneReserve, "Id", "NomZoneReserve"), "Selectionner une zone", new { @class = "form -control" })

    </div>


    <button type="submit" class="bt, btn-primary">Enregistrer</button>



}

<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script>
    $(document).ready(function () {
        $("#Colis_ZoneReserve_Reserve_Id").change(function () {
            $.get("/ZoneReserve/ListeZoneReserveParReserve", { ReserveId: $("#Colis_ZoneReserve_Reserve_Id").val() }, function (data) {
                $("#Colis_ZoneReserve_Id").empty();
                $.each(data, function (index, row) {
                    $("#Colis_ZoneReserve_Id").append("<option value='" + row.Id + "'>" + row.NomZoneReserve+ "</option>")
                });
            });
        })
    });
</script>

question from:https://stackoverflow.com/questions/65942236/insert-into-db-from-asp-net-form

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It looks like your razor page is posting info about navigation properties of the Colis object to the controller and creating the full objects instead of creating a new Colis object with just the int foreign key specified.

As is, when posted, '''colis.ZoneReserve''' is not null nor is '''colis.ZoneReserve.Reserve''' reference which tells entity framework to create those related object as well when you .Add(colis) to the context.

[HttpPost]
public ActionResult CreerColis(Colis colis)
{
    _context.Colis.Add(colis);
    _context.SaveChanges();

    return RedirectToAction("ListeColis");
}

You are POSTing unintended parameters to your controller, specifically '''Colis.ZoneReserve.Id''' and '''Colis.ZoneReserve.Reserve.Id''' as you BOUND TO in your razor page (see comments in code):

<div class="form-group">
    @Html.LabelFor(m => m.Colis.ZoneReserve.Reserve.Id)
    <!-- DropDownListFor m.Colis.ZoneReserve.ReserveId will send that (navigation path) value to the server. //-->
    @Html.DropDownListFor(m => m.Colis.ZoneReserve.Reserve.Id, new SelectList(Model.Reserve, "Id", "NomReserve"), "Selectionner une zone", new { @class = "form -control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.Colis.ZoneReserveId)
    <!-- DropDownListFor m.Colis.ZoneResearch.Id will send that navigation property to the server //-->
    @Html.DropDownListFor(m => m.Colis.ZoneReserve.Id, new SelectList(Model.ZoneReserve, "Id", "NomZoneReserve"), "Selectionner une zone", new { @class = "form -control" })
</div>

To fix your razor page (and not send unintended values to the server)

  1. change the first drop down list for Reserve to NOT be for anything it'll bind to on the server (you don't even need to POST it's value if you can strip it before submit), one way is to change it's name to something meaningless such as "UnnecessaryData" that won't map in the controller when posted (pseudo-code, not tested)
<div class="form-group">
    @Html.LabelFor(m => m.Colis.ZoneReserve.Reserve.Id)
    @Html.DropDownList(new SelectList(Model.Reserve, "Id", "NomReserve"), 
        "Selectionner une zone", 
        new { @class = "form-control", name = "UnnecessaryData" })
</div>
  1. Change the second drop-down-list to map to the correct property on the Colis object, notice all I did was change m => m.Colis.ZoneReserve.Id to the FK property of Colis m => m.Colis.ZoneReserveId:
<div class="form-group">
    @Html.LabelFor(m => m.Colis.ZoneReserveId)
    @Html.DropDownListFor(m => m.Colis.ZoneReserveId, new SelectList(Model.ZoneReserve, "Id", "NomZoneReserve"), "Selectionner une zone", new { @class = "form -control" })
</div>  

When you POST the form, your Colis object in the controller should have a NULL ZoneReserve property and a non-zero ZoneReserveId property - this will prevent the other data records from being created by entity framework.

Note: You can also simply strip the data from the Colis in the POST controller - but that doesn't correct your implementation on the client razor page that's sending unintended structure to the server in the POST method.

Also note: Because you don't validate that the navigation properties of Colis are NULL in the controller, a malicious user COULD create a lot of crap data on the server by POSTing full object tree data that'll be added with the controller method as implemented.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...