locked
Add/Edit/Delete Screens inside a partial View. RRS feed

  • Question

  • User-190697402 posted

    Hi,

    I have a partial view which displays the item added and also a add screen.

    The item list and add screen are given inside two div's. When click on the Create New it will display the add form.

    So how can i handle Edit form with same logic. Please find PartialView code below

    @model Contractor_HRMS.Pages.Staff.Onboarding.IndexModel
    @*
        For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
    *@
        <div id="displayStaffAssets">
    //On Buttonclick it will display the Add Form <p> <input type="button" class="btn-success" id="OnClickCreateStaffAsset" value="Create New" /> </p> @if (Model.ShowStaffAssets != null) { <table class="table" border="1" style="width:750px;"> <thead style="background-color:#DC3545"> <tr> <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].StaffAssetName)</th> <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].IssuedQty)</th> <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].IssuedDate)</th> <th></th> </tr> </thead> <tbody> @foreach (var item in Model.ShowStaffAssets) { <tr> <td>@Html.DisplayFor(modelItem => item.StaffAssetName)</td> <td>@Html.DisplayFor(modelItem => item.IssuedQty)</td> <td>@Html.DisplayFor(modelItem => item.IssuedDate)</td> <td> <img src="~/images/pencil(1).png" alt="Edit"><a>Edit</a> | @*<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |*@ <img src="~/images/icons8-delete-trash-16.png" alt="Delete"><a>Delete</a> </td> </tr> } </tbody> </table> } </div>
    //Div for adding StaffAssets
    <div id="AddStaffAssets" style="display:none;"> <h4>Create New Asset</h4> <form method="post" asp-page-handler="InsertAssetsDetails"> <input asp-for="StaffAssets.StaffID" type="hidden" value='@TempData["StaffID"]' /> <input asp-for="StaffAssets.EmpID" type="hidden" value='@TempData["EmpID"]' /> <!-- Asset Name --> <div class="form-group"> <label asp-for="StaffAssets.StaffAssetName" class="control-label-staff"></label> <select asp-for="StaffAssets.StaffAssetName" asp-items="Model.ShowAssetName" class="form-control-staff"> <option value="">Please Select</option> </select><br /> <span asp-validation-for="StaffAssets.StaffAssetName" class="text-danger" style="margin-left:210px;"></span> </div> <!-- Issued Quantity --> <div class="form-group"> <label asp-for="StaffAssets.IssuedQty" class="control-label-staff"></label> <input asp-for="StaffAssets.IssuedQty" class="form-control-staff" /><br /> <span asp-validation-for="StaffAssets.IssuedQty" class="text-danger" style="margin-left:210px;"></span> </div> <!-- Issued Date--> <div class="form-group"> <label asp-for="StaffAssets.IssuedDate" class="control-label-staff"></label> <input asp-for="StaffAssets.IssuedDate" class="form-control-staff" /><br /> <span asp-validation-for="StaffAssets.IssuedDate" class="text-danger" style="margin-left:210px;"></span> </div> <!-- Return Qty--> <div class="form-group" style="display:none;"> <label asp-for="StaffAssets.ReturnQty" class="control-label-staff"></label> <input asp-for="StaffAssets.ReturnQty" class="form-control-staff" value="NULL" /><br /> <span asp-validation-for="StaffAssets.ReturnQty" class="text-danger" style="margin-left:210px;"></span> </div> <!-- Return Date--> <div class="form-group" style="display:none;"> <label asp-for="StaffAssets.ReturnDate" class="control-label-staff"></label> <input asp-for="StaffAssets.ReturnDate" class="form-control-staff"/><br /> <span asp-validation-for="StaffAssets.ReturnDate" class="text-danger" style="margin-left:210px;"></span> </div> <div class="form-group" style="display:none;"> <label asp-for="StaffAssets.LastModifiedBy" class="control-label"></label> <input asp-for="StaffAssets.LastModifiedBy" class="form-control" value="jteena" /> <span asp-validation-for="StaffAssets.LastModifiedBy" class="text-danger"></span> </div> <div class="form-group" style="display:none;"> <label asp-for="StaffAssets.LastModifiedTimestamp" class="control-label"></label> <input asp-for="StaffAssets.LastModifiedTimestamp" class="form-control"/> <span asp-validation-for="StaffAssets.LastModifiedTimestamp" class="text-danger"></span> </div> <div style="float:right"> <input type='submit' class='btn btn-success' value='Save' /> </div> </form> </div>

    Tuesday, November 24, 2020 8:44 AM

All replies

  • User475983607 posted

    I've explained the problem and what to do in your other thread.  If you have not changed the code then there is still have a timing issue where the edit form is populate on the server.  The "Create New" toggles the edit form on the client which is too late because the data is already populated.

    If you want to use the same form then, as recommend previously, you have to decide where to put the logic; server or client.  Once you make that decision then you'll know what code to move.  Another option is to creating a separate insert partial. 

    I think it is important to mention that I warned you about this design approach.  I clearly explained you need to write a lot of code...  Using standard Razor Page patterns would result in far less code and  complexity. 

    Tuesday, November 24, 2020 2:38 PM
  • User1312693872 posted

    Hi,teenajohn1989

    I'm not sure why you create two assets that have the same keys, one staffname often have it's specific id. So that it will be easy to locate and edit it.

    May be you have other specific keys to locate? 

    To edit or delete, you can use ajax, refer to the samples in this link, if you have any problem, welcome to share it.

    http://binaryintellect.net/articles/16ecfe49-98df-4305-b53f-2438d836f0d0.aspx

    A simple example:

    <td>
    <button type="button" id="edit1">edit</button> |
    <a asp-page="./Delete">Delete</a>
    </td>
    ....
    <input asp-for="StaffAssets.StaffID" type="hidden" value='@TempData["StaffID"]' />

    Ajax in main razor view:

     $("#edit1").click(function () {
    
                $.ajax({
                    type: "Get",
                    url: "/?handler=EditAssets",
                    dataType: "json",
                    data: { "StaffID": $("#StaffAssets_StaffID").val() },
                    contentType: "application/json; charset=utf-8",
                    success: function () {
                    }
                })
            });

    Best Regards,

    Jerry Cai

    Wednesday, November 25, 2020 3:33 AM
  • User-190697402 posted

    Hi Jerry Cai,

    Thanks for the response.

    I'm not sure why you create two assets that have the same keys, one staffname often have it's specific id. So that it will be easy to locate and edit it.

    Im using StaffID,EmpID and SatffAssetsName as Primary Keys.So that i can insert it as a seperate records,since i may have more than 10 assets to add for an employee. Hope this method is correct.Correct me if im wrong.

    And Can i use another div for Edit action so that on clicking on the edit link it should display the edit div and will hide the other two div's.

    <td>
                                <img src="~/images/pencil(1).png" alt="Edit"><a href="#" title="Edit" id="OnClickEditStaffAsset">Edit</a> |
                               
                                <img src="~/images/icons8-delete-trash-16.png" alt="Delete"><a asp-page="./Delete">Delete</a>
                            </td>

    _validationscriptspartial.cshtml

    $("#OnClickEditStaffAsset").click(function () {
                //alert("button"); // Remove this line if it worked
                $("#displayStaffAssets").hide();
                $("#AddStaffAssets").hide();
                $("#EditStaffAssets").show();
    
            });

    but im unable to click on the other records.When i click on the first record listed,its displaying correctly.  im finding some difficulties in passing StaffID. Could you please let me know,the method im following is correct or not.

    Wednesday, November 25, 2020 9:34 AM
  • User-190697402 posted

    Hi Jerry Cai,

    I'm using this method now,but when clicking on the link it redirect to blank page. Not displaying the edit screen as intended.

    Ajax in main razor view:

     $("#edit1").click(function () {
    
                $.ajax({
                    type: "Get",
                    url: "/?handler=EditAssets",
                    dataType: "json",
                    data: { "StaffID": $("#StaffAssets_StaffID").val() },
                    contentType: "application/json; charset=utf-8",
                    success: function () {
                    }
                })
            });

    Im quite unsure how to display the edit screen. Please help me to figure it out.

    Thursday, November 26, 2020 3:33 AM
  • User-821857111 posted

    If I understand correctly, you are trying to manage all the CRUD operations for an entity in the same page? If that is the case, you are fighting against the nature of Razor Pages and trying to replicate the way that an MVC application is structured, with one central controller for all operations related to an entity. It's not a good approach. You should have separate pages for Add, Edit and Displaying details. 

    Thursday, November 26, 2020 6:05 AM
  • User-190697402 posted

    Hi MikesDotNetting,

    Since im using Partial View for displaying this listing,im quite unaware how to use add,edit,delete in separate pages.

    Thanks for the reply.

    Thursday, November 26, 2020 6:18 AM
  • User-821857111 posted

    You can use the scaffolding tool in a Razor Pages application to generate the pages. Then look at the generated code to get an idea of how they are constructed. 

    Thursday, November 26, 2020 6:35 AM
  • User-190697402 posted

    Hi MikesDotnetting,

    Im already using it, The Scaffoded Razor Pages will have a pagemodel class.

    And for adding a new item, the page wont pass any id.

    For Editing,the page will have hidden field which stores the id of the record.

    In my case i need to pass StaffID and EmpID for adding New StaffAssets. Its because of that my add page is prepopulating the datas in input fields.

    Is there any other way to handle this in partialview - Basically there will be a listing,add,edit and delete actions need to perform.

    Thursday, November 26, 2020 6:42 AM
  • User-190697402 posted

    Hi Jerry cai,

    Could you please let me know how to display Edit Screen using this Ajax method. Thanks 

    Thursday, November 26, 2020 8:03 AM
  • User475983607 posted

    You are not following standard Razor Pages programming patterns.   It is like being given a blueprint that you crumbly up and throw in the corner. 

    Thursday, November 26, 2020 11:40 AM
  • User1312693872 posted

    Hi,teenajohn1989

    Sorry for the delay, you can use modal to finish the edit or delete, it will be more clear:

    <div id="displayStaffAssets">
        <p>
            <input type="button" class="btn-success" id="OnClickCreateStaffAsset" value="Create New" />
        </p>
        @if (Model.ShowStaffAssets != null)
        {
            <table class="table" border="1" style="width:750px;">
                <thead style="background-color:#DC3545">
                    <tr>
                        <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].StaffAssetName)</th>
                        <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].IssuedQty)</th>
                        <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].IssuedDate)</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model.ShowStaffAssets)
                    {
                        <tr>
                            <td>@Html.DisplayFor(modelItem => item.StaffAssetName)</td>
                            <td>@Html.DisplayFor(modelItem => item.IssuedQty)</td>
                            <td>@Html.DisplayFor(modelItem => item.IssuedDate)</td>
                            <td>                          
                                <a data-toggle="modal" data-target="#myModal_@item.StaffAssetName">|Edit</a>
                                <a asp-page="./Delete">Delete</a>
                                <div id="myModal_@item.StaffAssetName" class="modal fade" role="dialog">
                                    <div class="modal-dialog">
                                        <!-- Modal content-->
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <button type="button" class="close" data-dismiss="modal">&times;</button>
                                            </div>
                                            <div class="modal-body">
                                                <form method="post" asp-page-handler="EditAssetsDetails">
                                                        <input asp-for="StaffAssets.StaffID" type="hidden" value='@TempData["StaffID"]' />
                                                        <input asp-for="StaffAssets.EmpID" type="hidden" value='@TempData["EmpID"]' />
                                                        <!-- Asset Name -->
                                                        <div class="form-group">
                                                            <label asp-for="StaffAssets.StaffAssetName" class="control-label-staff"></label>
                                                            <input asp-for="StaffAssets.StaffAssetName" value="@item.StaffAssetName" class="form-control-staff"/>
                                                            <br />
                                                            <span asp-validation-for="StaffAssets.StaffAssetName" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>
    
                                                        <!-- Issued Quantity -->
                                                        <div class="form-group">
                                                            <label asp-for="StaffAssets.IssuedQty" class="control-label-staff"></label>
                                                            <input asp-for="StaffAssets.IssuedQty" value="@item.IssuedQty" class="form-control-staff" /><br />
                                                            <span asp-validation-for="StaffAssets.IssuedQty" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>
    
                                                        <!-- Issued Date-->
                                                        <div class="form-group">
                                                            <label asp-for="StaffAssets.IssuedDate" class="control-label-staff"></label>
                                                            <input asp-for="StaffAssets.IssuedDate" value="@item.IssuedDate" class="form-control-staff" /><br />
                                                            <span asp-validation-for="StaffAssets.IssuedDate" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>
    
                                                        <div style="float:right">
                                                            <input type='submit' class='btn btn-success' value='Edit' />
                                                        </div>
                                                    </form>
                                            </div>                                     
                                        </div>
                                    </div>
                                </div>
                            </td>
                        </tr>
                    }
                </tbody>
            </table>
        }
    </div>

    And the Edit method:

    public async Task<IActionResult> OnPostEditAssetsDetailsAsync(int current = 3)
            {
                ShowAssetName = new SelectList(_context.Assets, "assetname", "assetname");
                if (ModelState.GetFieldValidationState("StaffAssets") == ModelValidationState.Valid)
                {
                    var staffassets = await _context.StaffAssets.FindAsync(StaffAssets.StaffID, StaffAssets.EmpID, StaffAssets.StaffAssetName);
                    if (await TryUpdateModelAsync<StaffAssets>(
                    staffassets,
                    "StaffAssets",
                    s => s.StaffAssetName, s => s.IssuedQty, s => s.IssuedDate))
                    {
                        await _context.SaveChangesAsync();
    
                    }
                    await _context.SaveChangesAsync();
                    //when add works, then +1 ,means next tab
                    currentTab = current;
                    TempData["EmpID"] = StaffAssets.EmpID;
                    TempData["StaffID"] = StaffAssets.StaffID;
                    ShowStaffAssets = _context.StaffAssets.Where(c => c.StaffID == StaffAssets.StaffID).OrderBy(c => c.StaffAssetName).AsNoTracking().ToList();
                    return Page();
                }
                else
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors);
                    return Page();
                }
            }

    Result:

    Best Regards,

    Jerry Cai

    Friday, November 27, 2020 3:09 AM
  • User-190697402 posted

    Hi Jerry Cai,

    Thank you so much for explaining me this clearly.

    I have few issue with this method also.

    1)In the modal Asset name should be displayed in a selectlist

    2)Date is not displaying in the modal.

    3)when im submitting the form,its throwing following error.

    In my table,these three fields are defined as PK,But not in my model class,i have not specified it using [Key] annotation.Is that the problem.

    4)And if there are more than two records, the modal for third one is not popping up.

    Could you please help me .

    Friday, November 27, 2020 5:00 AM
  • User1312693872 posted

    Hi,teenajohn1989

    Answer for the four questions:

    1,2):Try this instead:

    <form method="post" asp-page-handler="EditAssetsDetails">
                                                        <input asp-for="StaffAssets.StaffID" type="hidden" value='@TempData["StaffID"]' />
                                                        <input asp-for="StaffAssets.EmpID" type="hidden" value='@TempData["EmpID"]' />
                                                        <!-- Asset Name -->
                                                        <div class="form-group">
                                                            <label asp-for="StaffAssets.StaffAssetName" class="control-label-staff"></label>
                                                            <select asp-for="@item.StaffAssetName"  asp-items="Model.ShowAssetName"  class="form-control-staff">
                                                                <option value="">Please Select</option>
                                                            </select><br />
                                                            <br />
                                                            <span asp-validation-for="StaffAssets.StaffAssetName" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>
    
                                                        <!-- Issued Quantity -->
                                                        <div class="form-group">
                                                            <label asp-for="StaffAssets.IssuedQty" class="control-label-staff"></label>
                                                            <input asp-for="@item.IssuedQty" class="form-control-staff" /><br />
                                                            <span asp-validation-for="StaffAssets.IssuedQty" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>
    
                                                        <!-- Issued Date-->
                                                        <div class="form-group">
                                                            <label asp-for="StaffAssets.IssuedDate" class="control-label-staff"></label>
                                                            <input asp-for="@item.IssuedDate"   class="form-control-staff" /><br />
                                                            <span asp-validation-for="StaffAssets.IssuedDate" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>
    
                                                        <div style="float:right">
                                                            <input type='submit' class='btn btn-success' value='Edit' />
                                                        </div>
                                                    </form>

    3),You said you have three keys in the model so I created three keys to do it. So you can try to put your key to 'FindAsync', debug your code and

    adjust my codes to your style.

    4),My code can add more modals, so I guess the problem is lies on the 

    <div id="myModal_@item.StaffAssetName" class="modal fade" role="dialog">

    You should make the staffAssetName be different so it can locate the related Model. Sure, you can change the name to id, etc. Just make sure

    that the code can find the related modal.

    Best Regards,

    Jerry Cai

    Friday, November 27, 2020 5:38 AM
  • User-190697402 posted

    Hi Jerry Cai,

    I ran into to new issue just now.I dont know why its suddenly showing this.

    The type or namespace name 'Exists' doesnot exists in the namespace Contractor_HRMS_Pages.Staff.Directory(Are you missing any assembly or reference)
    var foldername = StaffDetails.EmpID.ToString();
                    var DirectoryPath = Path.Combine(_env.WebRootPath, "Documents", "OnBoardingAttachments", foldername);
                    if (!Directory.Exists(DirectoryPath))
                    {
                        Directory.CreateDirectory(DirectoryPath);
                    }

    It was working fine till now.Dont know what happend suddenly.

    Friday, November 27, 2020 5:58 AM
  • User1312693872 posted

    Hi,teenajohn1989

    You mean you do not have this error before adding my code?

    I don't know what you want to do, my demo doesn't including file part, how do you add the file?

    Best Regards,

    Jerry Cai

    Friday, November 27, 2020 6:07 AM
  • User-190697402 posted

    Hi Jerry Cai,

    When submitting the staffdetails form,it will create a folder with name as StaffId in my webroot folder.

    So in the pagehandler method for inserting staffdetails i write this code.

    if (ModelState.GetFieldValidationState("StaffDetails") == ModelValidationState.Valid)
                {                
                    await _context.StaffDetails.AddAsync(StaffDetails);
                    await _context.SaveChangesAsync();
                    current++;                //when add works, then +1 ,means next tab
                    currentTab = current;
                    TempData["Success"] = "Success";
                    int StaffID = StaffDetails.StaffID;
                    TempData["EmpID"] = StaffDetails.EmpID;
                    TempData["StaffID"] = StaffID;                
                    var foldername = StaffDetails.EmpID.ToString();
                    var DirectoryPath = Path.Combine(_env.WebRootPath, "Documents", "OnBoardingAttachments", foldername);
                    if (!Directory.Exists(DirectoryPath))
                    {
                        Directory.CreateDirectory(DirectoryPath);
                    }
                    return Page();
                }
                else
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors);
                    return Page();
                }

    The highlighted code will create a directory in my webroot directory with staffid as folder name.

    The previously mentioned error is not showing for file upload.

    Friday, November 27, 2020 6:15 AM
  • User1312693872 posted

    Hi,teenajohn1989

    I copied your code and everything works well:

    And this could be a new problem, I suggest you try to open a new thread and attach related details, because I can't reproduce your problem now. 

    Best Regards,

    Jerry Cai

    Friday, November 27, 2020 6:29 AM
  • User-190697402 posted

    Hi Jerry Cai,

    when i change to this modelstate validation is returning false.StaffAssetsname,Issued Qty is showing invalid.

    <div class="form-group">
                                                            <label asp-for="StaffAssets.StaffAssetName" class="control-label-staff"></label>
                                                            <select asp-for="@item.StaffAssetName"  asp-items="Model.ShowAssetName"  class="form-control-staff">
                                                                <option value="">Please Select</option>
                                                            </select><br />
                                                            <br />
                                                            <span asp-validation-for="StaffAssets.StaffAssetName" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>

    Still Issued Date is not displaying.I have to select the date.

    <div class="form-group">
                                                            <label asp-for="StaffAssets.IssuedDate" class="control-label-staff"></label>
                                                            <input asp-for="@item.IssuedDate"   class="form-control-staff" /><br />
                                                            <span asp-validation-for="StaffAssets.IssuedDate" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>

    <!-- Issued Quantity -->
                                                        <div class="form-group">
                                                            <label asp-for="StaffAssets.IssuedQty" class="control-label-staff"></label>
                                                            <input asp-for="@item.IssuedQty" class="form-control-staff" /><br />
                                                            <span asp-validation-for="StaffAssets.IssuedQty" class="text-danger" style="margin-left:210px;"></span>
                                                        </div>

    One doubt also, is it not possible to define more than one key in Model Class.because when im using [Key] annotation in model class(StaffAssets) its showing Composite Key is not allowed 

    Friday, November 27, 2020 7:05 AM
  • User1312693872 posted

    Hi,teenajohn1989

    You should compare with my working demo and judge why the error occurs, I can't locate your problem when nothing shared from you. You can

    check whether your required properties have been passed to the edit action, problem may lie there.

    And about the three keys, you do not need to add three keys like me (but why you told me that you have three keys in last post? ), you just need

    to make sure the key can locate your specific data. And yes, [Key] can only be one but you can define multiple keys in OnModelCreating().

    Best Regards,

    Jerry Cai

    Friday, November 27, 2020 7:53 AM
  • User-190697402 posted

    Hi Jerry Cai,

    Sorry to bother you again regarding this.

    I could figure out why the modal for my third item is not popping up. There is some space in the assetname. So as you said earlier the div id/name should not have space,i could relate it .

    But the edit screen,still not displaying the date in the input field and  and also the model validation state ia always returning false for assetname and issuedqty. But both input fields have value in the field. Here is my code

    _StaffAssets.cshtml

    @model Contractor_HRMS.Pages.Staff.Onboarding.IndexModel
    @*
        For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
    *@
    <div id="displayStaffAssets">
        <p>
            <input type="button" class="btn-success" id="OnClickCreateStaffAsset" value="Create New" />
        </p>
        @if (Model.ShowStaffAssets != null)
        {
            <table class="table" border="1" style="width:750px;">
                <thead style="background-color:#DC3545">
                    <tr>
                        <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].StaffAssetName)</th>
                        <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].IssuedQty)</th>
                        <th>@Html.DisplayNameFor(model => model.ShowStaffAssets[0].IssuedDate)</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model.ShowStaffAssets)
                    {
                        <tr>
                            <td>@Html.DisplayFor(modelItem => item.StaffAssetName)</td>
                            <td>@Html.DisplayFor(modelItem => item.IssuedQty)</td>
                            <td>@Html.DisplayFor(modelItem => item.IssuedDate)</td>
                            <td>
                                <img src="~/images/pencil(1).png" alt="Edit">&nbsp;<a data-toggle="modal" data-target="#myModal_@item.StaffAssetName">Edit</a> |
                                <img src="~/images/icons8-delete-trash-16.png" alt="Delete">&nbsp;<a asp-page="./Delete">Delete</a>
    
                                <!--EDIT MODAL-->
                                <div id="myModal_@item.StaffAssetName" class="modal fade" role="dialog">
                                    <div class="modal-dialog">
                                        <!-- Modal content-->
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <button type="button" class="close" data-dismiss="modal">&times;</button>
                                            </div>
                                            <div class="modal-body">
                                                <form method="post" asp-page-handler="EditAssetsDetails">
                                                    <input asp-for="StaffAssets.StaffID" type="hidden" value='@TempData["StaffID"]' />
                                                    <input asp-for="StaffAssets.EmpID" type="hidden" value='@TempData["EmpID"]' />
    
                                                    <!-- Asset Name -->
                                                    <div class="form-group">
                                                        <label asp-for="StaffAssets.StaffAssetName" class="control-label-staff"></label>
                                                        @*<input asp-for="StaffAssets.StaffAssetName" value="@item.StaffAssetName" class="form-control-staff" />*@
                                                        <select asp-for="@item.StaffAssetName" asp-items="Model.ShowAssetName" class="form-control-staff">
                                                            <option value="">Please Select</option>
                                                        </select>
                                                        <br />
                                                        <span asp-validation-for="StaffAssets.StaffAssetName" class="text-danger" style="margin-left:210px;"></span>
                                                    </div>
    
                                                    <!-- Issued Quantity -->
                                                    <div class="form-group">
                                                        <label asp-for="StaffAssets.IssuedQty" class="control-label-staff"></label>
                                                        <input asp-for="@item.IssuedQty" class="form-control-staff" /><br />
                                                        <span asp-validation-for="StaffAssets.IssuedQty" class="text-danger" style="margin-left:210px;"></span>
                                                    </div>
    
                                                    <!-- Issued Date-->
                                                    <div class="form-group">
                                                        <label asp-for="StaffAssets.IssuedDate" class="control-label-staff"></label>
                                                        <input asp-for="@item.IssuedDate" class="form-control-staff" /><br />
                                                        <span asp-validation-for="StaffAssets.IssuedDate" class="text-danger" style="margin-left:210px;"></span>
                                                    </div>
    
                                                    <!-- Return Qty-->
                                                    <div class="form-group" style="display:none;">
                                                        <label asp-for="StaffAssets.ReturnQty" class="control-label-staff"></label>
                                                        <input asp-for="StaffAssets.ReturnQty" class="form-control-staff" value="NULL" /><br />
                                                        <span asp-validation-for="StaffAssets.ReturnQty" class="text-danger" style="margin-left:210px;"></span>
                                                    </div>
    
                                                    <div>
                                                        <input type='submit' class='btn btn-success' value='Save' />
                                                    </div>
                                                </form>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </td>
                        </tr>
                    }
                </tbody>
            </table>
        }
    </div>
    
    //Div for Adding Asset
    <div id="AddStaffAssets" style="display:none;">
        <h4>Create New Asset</h4>
        <form method="post" asp-page-handler="InsertAssetsDetails">
            <input asp-for="StaffAssets.StaffID" type="hidden" value='@TempData["StaffID"]' />
            <input asp-for="StaffAssets.EmpID" type="hidden" value='@TempData["EmpID"]' />
            <!-- Asset Name -->
            <div class="form-group">
                <label asp-for="StaffAssets.StaffAssetName" class="control-label-staff"></label>
                <select asp-for="StaffAssets.StaffAssetName" asp-items="Model.ShowAssetName" class="form-control-staff">
                    <option value="">Please Select</option>
                </select><br />
                <span asp-validation-for="StaffAssets.StaffAssetName" class="text-danger" style="margin-left:210px;"></span>
            </div>
    
            <!-- Issued Quantity -->
            <div class="form-group">
                <label asp-for="StaffAssets.IssuedQty" class="control-label-staff"></label>
                <input asp-for="StaffAssets.IssuedQty" class="form-control-staff" /><br />
                <span asp-validation-for="StaffAssets.IssuedQty" class="text-danger" style="margin-left:210px;"></span>
            </div>
    
            <!-- Issued Date-->
            <div class="form-group">
                <label asp-for="StaffAssets.IssuedDate" class="control-label-staff"></label>
                <input asp-for="StaffAssets.IssuedDate" class="form-control-staff" /><br />
                <span asp-validation-for="StaffAssets.IssuedDate" class="text-danger" style="margin-left:210px;"></span>
            </div>
    
            <!-- Return Qty-->
            <div class="form-group" style="display:none;">
                <label asp-for="StaffAssets.ReturnQty" class="control-label-staff"></label>
                <input asp-for="StaffAssets.ReturnQty" class="form-control-staff" value="NULL" /><br />
                <span asp-validation-for="StaffAssets.ReturnQty" class="text-danger" style="margin-left:210px;"></span>
            </div>
    
            <!-- Return Date-->
            <div class="form-group" style="display:none;">
                <label asp-for="StaffAssets.ReturnDate" class="control-label-staff"></label>
                <input asp-for="StaffAssets.ReturnDate" class="form-control-staff" /><br />
                <span asp-validation-for="StaffAssets.ReturnDate" class="text-danger" style="margin-left:210px;"></span>
            </div>
    
            <div class="form-group" style="display:none;">
                <label asp-for="StaffAssets.LastModifiedBy" class="control-label"></label>
                <input asp-for="StaffAssets.LastModifiedBy" class="form-control" value="jteena" />
                <span asp-validation-for="StaffAssets.LastModifiedBy" class="text-danger"></span>
            </div>
            <div class="form-group" style="display:none;">
                <label asp-for="StaffAssets.LastModifiedTimestamp" class="control-label"></label>
                <input asp-for="StaffAssets.LastModifiedTimestamp" class="form-control" />
                <span asp-validation-for="StaffAssets.LastModifiedTimestamp" class="text-danger"></span>
            </div>
    
            <div style="float:right">
                <input type='submit' class='btn btn-success' value='Save' />
            </div>
        </form>
    </div>

    StaffAssets.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace Contractor_HRMS.Models
    {
        public class StaffAssets
        {
    		//--- Staff Id ---//
    		[Key]
    		public int StaffID { get; set; }
    
    		//--- Emp Id ---//	
    		
    		[Display(Name = "Employee ID*"), StringLength(100)]
    		public string EmpID { get; set; }
    
    		//--- Asset Name ---//
    		
    		[Required(ErrorMessage = "Please select Asset")]
    		[Display(Name = "Asset Name *"), StringLength(100)]
    		public string StaffAssetName { get; set; }
    
    		//--Issued Quantity ---//
    		[Required(ErrorMessage = "Please enter Issued Quantity")]
    		[Display(Name = "Issued Quantity*"), StringLength(10)]
    		public string IssuedQty { get; set; }
    
    		//--Issued Date ---//
    		[Required(ErrorMessage = "Please select Issued Date")]
    		[Display(Name = "Issued Date*")]
    		[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    		[DataType(DataType.Date)]
    		public DateTime IssuedDate { get; set; }
    
    		//--Return Quantity ---//
    		[Required(ErrorMessage = "Please enter Return Quantity")]
    		[Display(Name = "Return Quantity*"), StringLength(10)]
    		public string ReturnQty { get; set; }
    
    		//--Return Date ---//
    		//[Required(ErrorMessage = "Please enter Return Date")]
    		[Display(Name = "Return Date*")]
    		[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    		[DataType(DataType.Date)]
    		public DateTime? ReturnDate { get; set; }
    
    		[Display(Name = "Last Modified By")]
    		public string LastModifiedBy { get; set; }
    
    		[Display(Name = "Last Modified TimeStamp")]
    		[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    		[DataType(DataType.Date)]
    		public DateTime? LastModifiedTimestamp { get; set; }
    	}
    }
    

    onModelCreating functionlity

    modelBuilder.Entity("Contractor_HRMS.Models.StaffAssets", b =>
                    {
                        b.Property<int>("StaffID")
                            .ValueGeneratedOnAdd()
                            .HasColumnType("int")
                            .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
    
                        b.Property<string>("EmpID")
                            .HasColumnType("nvarchar(100)")
                            .HasMaxLength(100);
    
                        b.Property<DateTime>("IssuedDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("IssuedQty")
                            .IsRequired()
                            .HasColumnType("nvarchar(10)")
                            .HasMaxLength(10);
    
                        b.Property<string>("LastModifiedBy")
                            .HasColumnType("nvarchar(max)");
    
                        b.Property<DateTime?>("LastModifiedTimestamp")
                            .HasColumnType("datetime2");
    
                        b.Property<DateTime?>("ReturnDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("ReturnQty")
                            .IsRequired()
                            .HasColumnType("nvarchar(10)")
                            .HasMaxLength(10);
    
                        b.Property<string>("StaffAssetName")
                            .IsRequired()
                            .HasColumnType("nvarchar(100)")
                            .HasMaxLength(100);
    
                        b.HasKey("StaffID,EmpID,StaffAssetsName");
    
                        b.ToTable("StaffAssets");
                    });

    Index.cshtml.cs

    public async Task<IActionResult> OnPostEditAssetsDetailsAsync(int current = 4)
            {
                ShowAssetName = new SelectList(_context.Assets, "assetname", "assetname");
                if (ModelState.GetFieldValidationState("StaffAssets") == ModelValidationState.Valid)
                {
                    var staffassets = await _context.StaffAssets.FindAsync(StaffAssets.StaffID,StaffAssets.EmpID,StaffAssets.StaffAssetName);
                    if (await TryUpdateModelAsync<StaffAssets>(
                    staffassets,
                    "StaffAssets",
                    s => s.StaffAssetName, s => s.IssuedQty, s => s.IssuedDate))
                    {
                        await _context.SaveChangesAsync();
    
                    }
                    await _context.SaveChangesAsync();
                    //when add works, then +1 ,means next tab
                    currentTab = current;
                    TempData["EmpID"] = StaffAssets.EmpID;
                    TempData["StaffID"] = StaffAssets.StaffID;
                    ShowStaffAssets = _context.StaffAssets.Where(c => c.StaffID == StaffAssets.StaffID).OrderBy(c => c.StaffAssetName).AsNoTracking().ToList();
                    return Page();
                }
                else
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors);
                    currentTab = current;
                    return Page();
                }
            }

    I have compared you code and mine. Everything looks similar. Could you please revert me?

    Monday, November 30, 2020 3:09 AM
  • User1312693872 posted

    Hi,teenajohn1989

    But the edit screen,still not displaying the date in the input field

    After I checked your model, I found I haven't add DateFormat, then you can try using

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

    and also the model validation state ia always returning false for assetname and issuedqty

    Use F12 to check why they can't be passed, you may lost the name (sorry I haven't update it in my last post)

     <div class="form-group">
               <label asp-for="StaffAssets.StaffAssetName" class="control-label-staff"></label>
               <select asp-for="@item.StaffAssetName" name="StaffAssets.StaffAssetName"  asp-items="Model.ShowAssetName"  class="form-control-staff">
                   option value="">Please Select</option>
               </select><br />
               <br />
               <span asp-validation-for="StaffAssets.StaffAssetName" class="text-danger" style="margin-left:210px;"></span>
    </div>

    If you have any questions, feel free to share it, I'm happy to assist you.

    Best Regards,

    Jerry Cai

    Monday, November 30, 2020 5:34 AM
  • User-190697402 posted

    Hi Jerry Cai,

    Jerry Cai

    If you have any questions, feel free to share it, I'm happy to assist you.

    Thank you so much for the kind response.

    I have changed the dateformat in my model class as you said.

    Now my date format in Add Asset is showing like this.

    and when i click on Add the following error is getting

    when i revert the dateformat to dd/MM/yyyy,it wont show up the date in edit screen.I choose one date and try to update it,but its throwing error

    As you said earlier i have changed my modelbuilder function,copying my code here

    modelBuilder.Entity("Contractor_HRMS.Models.StaffAssets", b =>
                    {
                        b.Property<int>("StaffID")
                            .ValueGeneratedOnAdd()
                            .HasColumnType("int")
                            .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
    
                        b.Property<string>("EmpID")
                            .HasColumnType("nvarchar(100)")
                            .HasMaxLength(100);
    
                        b.Property<DateTime>("IssuedDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("IssuedQty")
                            .IsRequired()
                            .HasColumnType("nvarchar(10)")
                            .HasMaxLength(10);
    
                        b.Property<string>("LastModifiedBy")
                            .HasColumnType("nvarchar(max)");
    
                        b.Property<DateTime?>("LastModifiedTimestamp")
                            .HasColumnType("datetime2");
    
                        b.Property<DateTime?>("ReturnDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("ReturnQty")
                            .IsRequired()
                            .HasColumnType("nvarchar(10)")
                            .HasMaxLength(10);
    
                        b.Property<string>("StaffAssetName")
                            .IsRequired()
                            .HasColumnType("nvarchar(100)")
                            .HasMaxLength(100);
    
                        b.HasKey("StaffID,EmpID,StaffAssetName");
    
                        b.ToTable("StaffAssets");
                    });

    And my StaffAssets Table structure is

    CREATE TABLE StaffAssets
    (	
    	StaffID INT NOT NULL,
    	EmpID	VARCHAR(100) NOT NULL,
    	StaffAssetName varchar(100) NOT NULL,
    	IssuedQty varchar(10),
    	IssuedDate datetime,
    	ReturnQty varchar(10),
    	ReturnDate datetime,
    	LastModifiedBy  varchar(255),
    	LastModifiedTimestamp  datetime	
    )
    ALTER TABLE StaffAssets ADD PRIMARY KEY (StaffID,EmpID,StaffAssetName);

    Could you please revert me on this.

    Tuesday, December 1, 2020 6:33 AM
  • User-190697402 posted

    Hi Jerry Cai,

    Could you please let me know should i need to declare the Keys somewhere else other than this?

    Wednesday, December 2, 2020 5:09 AM
  • User1312693872 posted

    Hi,teenajohn1989

    Sorry,  If I used your modelbuilder, I can not even create the database..After I fixed my problem, everything works again but I can't

    reproduce your problem at the same time.

    Now you can test whether the problem lies in the modelbuilder, just automatically creating StaffAssets entity like my original post and try again.

     modelBuilder.Entity<StaffAssets>()
                    .HasKey(c => new { c.StaffID, c.EmpID, c.StaffAssetName });

    Best Regards,

    Jerry Cai

    Wednesday, December 2, 2020 8:48 AM
  • User-190697402 posted

    Hi Jerry Cai,

    i have updated my ApplicationDbContextModelSnapshot.cs file like this

    modelBuilder.Entity("Contractor_HRMS.Models.StaffAssets", b =>
                    {
                        b.Property<int>("StaffID")
                            .ValueGeneratedOnAdd()
                            .HasColumnType("int")
                            .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
    
                        b.Property<string>("EmpID")
                            .HasColumnType("nvarchar(100)")
                            .HasMaxLength(100);
    
                        b.Property<DateTime>("IssuedDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("IssuedQty")
                            .IsRequired()
                            .HasColumnType("nvarchar(10)")
                            .HasMaxLength(10);
    
                        b.Property<string>("LastModifiedBy")
                            .HasColumnType("nvarchar(max)");
    
                        b.Property<DateTime?>("LastModifiedTimestamp")
                            .HasColumnType("datetime2");
    
                        b.Property<DateTime?>("ReturnDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("ReturnQty")
                            .IsRequired()
                            .HasColumnType("nvarchar(10)")
                            .HasMaxLength(10);
    
                        b.Property<string>("StaffAssetName")
                            .IsRequired()
                            .HasColumnType("nvarchar(100)")
                            .HasMaxLength(100);
    
                        b.HasKey("StaffID,EmpID,StaffAssetName");
    
                        b.ToTable("StaffAssets");
                    });
    
                modelBuilder.Entity<StaffAssets>()
                    .HasKey(c => new { c.StaffID, c.EmpID, c.StaffAssetName });

    But still im getting the error, ' three values were passed'.

    Wednesday, December 2, 2020 9:23 AM
  • User1312693872 posted

    Hi,teenajon1989

    No, delete the above part and just use mine, like

    protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity<StaffDetails>().ToTable("StaffDetails");
                modelBuilder.Entity<TypeOfEmployee>().ToTable("TypeOfEmployee");
                modelBuilder.Entity<EmploymentType>().ToTable("EmploymentType");
                modelBuilder.Entity<StaffBioData>().ToTable("StaffBioData");
                modelBuilder.Entity<TypeofBio>().ToTable("TypeofBio");
                modelBuilder.Entity<Asset>().ToTable("Asset");
                modelBuilder.Entity<StaffAssets>()
                    .HasKey(c => new { c.StaffID, c.EmpID, c.StaffAssetName });
            }

    Best Regards,

    Jerry Cai

    Wednesday, December 2, 2020 9:25 AM
  • User-190697402 posted

    Hi Jerry Cai,

    I did the same, i commented it out and checked, still got the same issue and this is my function name for modelbuilder

    protected override void BuildModel(ModelBuilder modelBuilder){
    
    }

    I have one doubt,can you see the highlighted code,do we need to pass the Key as an array of values.

    Wednesday, December 2, 2020 9:39 AM
  • User1312693872 posted

    Hi,teenajohn1989

    You said you 'updated my ApplicationDbContextModelSnapshot.cs file like this', but how do you update the database by changing the code

    in 'ApplicationDbContextModelSnapshot.cs '? IMHO, any changes in snapshot will not be applied, it just used for checking. You can click

    'View->SQL Server Object Exploer->...->dbo.StaffAssets->View Designer' to check your table design, this is mine:

    And my code in DbContext, to generate the database:

    public class ApplicationDbContext : DbContext
        {
    
            public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
            {
            }
    
            public DbSet<StaffDetails> StaffDetails { get; set; }
            public DbSet<TypeOfEmployee> TypeOfEmployees { get; set; }
            public DbSet<EmploymentType> EmploymentTypes { get; set; }
            public DbSet<StaffBioData> StaffBioDatas { get; set; }
            public DbSet<TypeofBio> TypeofBios { get; set; }
            public DbSet<StaffAssets> StaffAssets { get; set; }
            public DbSet<Asset> Assets { get; set; }
    
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity<StaffDetails>().ToTable("StaffDetails");
                modelBuilder.Entity<TypeOfEmployee>().ToTable("TypeOfEmployee");
                modelBuilder.Entity<EmploymentType>().ToTable("EmploymentType");
                modelBuilder.Entity<StaffBioData>().ToTable("StaffBioData");
                modelBuilder.Entity<TypeofBio>().ToTable("TypeofBio");
                modelBuilder.Entity<Asset>().ToTable("Asset");
                modelBuilder.Entity<StaffAssets>()
                    .HasKey(c => new { c.StaffID, c.EmpID, c.StaffAssetName }); // to create three keys
            }         
        }

    After Add-Migration, Update-Database:

    Then my snapshots will be generated, you can't change the code in it if you want to modify your database, it will not be applied:

     modelBuilder.Entity("Case11101.Models.StaffAssets", b =>
                    {
                        b.Property<int>("StaffID")
                            .HasColumnType("int");
    
                        b.Property<string>("EmpID")
                            .HasMaxLength(100)
                            .HasColumnType("nvarchar(100)");
    
                        b.Property<string>("StaffAssetName")
                            .HasMaxLength(100)
                            .HasColumnType("nvarchar(100)");
    
                        b.Property<DateTime>("IssuedDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("IssuedQty")
                            .IsRequired()
                            .HasMaxLength(10)
                            .HasColumnType("nvarchar(10)");
    
                        b.Property<string>("LastModifiedBy")
                            .HasColumnType("nvarchar(max)");
    
                        b.Property<DateTime?>("LastModifiedTimestamp")
                            .HasColumnType("datetime2");
    
                        b.Property<DateTime?>("ReturnDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("ReturnQty")
                            .HasMaxLength(10)
                            .HasColumnType("nvarchar(10)");
    
                        b.HasKey("StaffID", "EmpID", "StaffAssetName"); // this is the difference, in yours, it will not be three keys.
    
                        b.ToTable("StaffAssets");
                    });

    Try to modify your database as mine, and I believe any error will disappear.

    Best Regards,

    Jerry Cai

    Thursday, December 3, 2020 2:19 AM
  • User-190697402 posted

    Hi Jerry Cai,

    Thanks for the reply.

    I have created the StaffAssets table manually by running this code in the sql management studio

    CREATE TABLE StaffAssets
    (	
    	StaffID INT NOT NULL,
    	EmpID	VARCHAR(100) NOT NULL,
    	StaffAssetName VARCHAR(100) NOT NULL,
    	IssuedQty VARCHAR(10),
    	IssuedDate DATETIME,
    	ReturnQty VARCHAR(10),
    	ReturnDate DATETIME,
    	LastModifiedBy  VARCHAR(255),
    	LastModifiedTimestamp  DATETIME	
    )
    ALTER TABLE StaffAssets ADD CONSTRAINT PK_StaffAssets PRIMARY KEY (StaffID,EmpID,StaffAssetName);

    After that i run the commands Add-Migration and Update-Database in Nuget Package Manager Console.

    But Still the code ModelBuilder functionality looks like this.

    modelBuilder.Entity("Contractor_HRMS.Models.StaffAssets", b =>
                    {
                        b.Property<int>("StaffID")
                            .ValueGeneratedOnAdd()
                            .HasColumnType("int")
                            .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
    
                        b.Property<string>("EmpID")
                            .HasColumnType("nvarchar(100)")
                            .HasMaxLength(100);
    
                        b.Property<DateTime>("IssuedDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("IssuedQty")
                            .IsRequired()
                            .HasColumnType("nvarchar(10)")
                            .HasMaxLength(10);
    
                        b.Property<string>("LastModifiedBy")
                            .HasColumnType("nvarchar(max)");
    
                        b.Property<DateTime?>("LastModifiedTimestamp")
                            .HasColumnType("datetime2");
    
                        b.Property<DateTime?>("ReturnDate")
                            .HasColumnType("datetime2");
    
                        b.Property<string>("ReturnQty")
                            .IsRequired()
                            .HasColumnType("nvarchar(10)")
                            .HasMaxLength(10);
    
                        b.Property<string>("StaffAssetName")
                            .IsRequired()
                            .HasColumnType("nvarchar(100)")
                            .HasMaxLength(100);
    
                        b.HasKey("StaffID");
    
                        b.ToTable("StaffAssets");
                    });

    I checked the table through sql explorer ,Its like

    But Still its showing the same error

    Thursday, December 3, 2020 6:19 AM
  • User-190697402 posted

    Hi Jerry Cai,

    I managed to fix this issue

    Entity type ' ' is defined with a single key property, but 3 values were passed to the 'DbSet.Find' method
    

    changed code snippet to

    var staffassets = await _context.StaffAssets.FirstOrDefaultAsync(c => c.StaffID == StaffAssets.StaffID && c.EmpID == StaffAssets.EmpID && c.StaffAssetName == StaffAssets.StaffAssetName);

    But my TryUpdateModelAsync method is not working,it is not updating the values. This is the code

    if(await TryUpdateModelAsync<StaffAssets>
                        (staffassets,
                        "StaffAssets",
                        s => s.StaffAssetName, 
                        s => s.IssuedQty, 
                        s => s.IssuedDate)
                      )
                    {
                        await _context.SaveChangesAsync();
    
                    }

    Could you please explain me how this work.

    Thursday, December 3, 2020 12:16 PM
  • User-190697402 posted

    Hi Jerry Cai,

    Can you please help me to figure out the issue? Thanks!

    Friday, December 4, 2020 4:07 AM
  • User1312693872 posted

    Hi,teenajohn1989

    It seems your way to create the database is different from mine, this should be the reason why you always can't run the code that works

    normally at my side. You still have just one key even you modified the designer because in snapshoot , it tells you it just has one key named

    staffid. But Now I'm glad to see you have solved this problem.

    My method just give you a reference, you should modify your code according to your design.

    About the new problem, you may missed 'await _context.SaveChangesAsync();'

    public async Task<IActionResult> OnPostEditAssetsDetailsAsync(int current = 3)
            {
                ShowAssetName = new SelectList(_context.Assets, "assetname", "assetname");
                if (ModelState.GetFieldValidationState("StaffAssets") == ModelValidationState.Valid)
                {
                    var staffassets = await _context.StaffAssets.FirstOrDefaultAsync(c => c.StaffID == StaffAssets.StaffID && c.EmpID == StaffAssets.EmpID && c.StaffAssetName == StaffAssets.StaffAssetName);
                    if (await TryUpdateModelAsync<StaffAssets>(
                    staffassets,
                    "StaffAssets",
                    s => s.StaffAssetName, s => s.IssuedQty, s => s.IssuedDate))
                    {
                        await _context.SaveChangesAsync();
                    }
                    await _context.SaveChangesAsync(); // this line will be used to save when worked.
                    //when add works, then +1 ,means next tab
                    currentTab = current;
                    TempData["EmpID"] = StaffAssets.EmpID;
                    TempData["StaffID"] = StaffAssets.StaffID;
                    ShowStaffAssets = _context.StaffAssets.Where(c => c.StaffID == StaffAssets.StaffID).OrderBy(c => c.StaffAssetName).AsNoTracking().ToList();
                    return Page();
                }
                else
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors);
                    return Page();
                }
            }

    Result:

    Best Regards,

    Jerry Cai

    Friday, December 4, 2020 7:57 AM
  • User-190697402 posted

    Hi Jerry Cai,

    Thanks for the response.

    When i include this

    await _context.SaveChangesAsync();

    code, im getting this error

    DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 2 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.

    Correct me if im wrong, this code snippet await _context.SaveChangesAsync();  is used to save the data to database .ryt? why do we need to call that twice?because inside the if condition we are already calling that.

    public async Task<IActionResult> OnPostEditAssetsDetailsAsync(int current = 4)
            {
                ShowAssetName = new SelectList(_context.Assets, "assetname", "assetname");
                if (ModelState.GetFieldValidationState("StaffAssets") == ModelValidationState.Valid)
                {
                    var staffassets = await _context.StaffAssets.FirstOrDefaultAsync(c => c.StaffID == StaffAssets.StaffID && c.EmpID == StaffAssets.EmpID && c.StaffAssetName == StaffAssets.StaffAssetName);
                    //var staffassets = await _context.StaffAssets.FindAsync(StaffAssets.StaffID,StaffAssets.EmpID,StaffAssets.StaffAssetName);
                    if(await TryUpdateModelAsync<StaffAssets>
                        (staffassets,
                        "StaffAssets",
                        s => s.StaffAssetName, 
                        s => s.IssuedQty, 
                        s => s.IssuedDate)
                      )
                    {
                        await _context.SaveChangesAsync();
    
                    }
                    await _context.SaveChangesAsync();
                    //when add works, then +1 ,means next tab
                    currentTab = current;
                    TempData["EmpID"] = StaffAssets.EmpID;
                    TempData["StaffID"] = StaffAssets.StaffID;
                    ShowStaffAssets = _context.StaffAssets.Where(c => c.StaffID == StaffAssets.StaffID).OrderBy(c => c.StaffAssetName).AsNoTracking().ToList();
                    return Page();
                }
                else
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors);
                    currentTab = current;
                    return Page();
                }
            }
    

    Friday, December 4, 2020 8:16 AM
  • User1312693872 posted

    Hi,teenajohn1989

    Set a break point to check

    var staffassets = await _context.StaffAssets.FirstOrDefaultAsync(c => c.StaffID == StaffAssets.StaffID && c.EmpID == StaffAssets.EmpID && c.StaffAssetName == StaffAssets.StaffAssetName);

    whether the staffassets find the row you want to change, that must be your database issue.

    And about

    await _context.SaveChangesAsync();

    in 'if', actually the saveChanges code in it won't be executed ,you can just delete the 'if', use 

    await TryUpdateModelAsync<StaffAssets>
                        (staffassets,
                        "StaffAssets",
                        s => s.StaffAssetName,
                        s => s.IssuedQty,
                        s => s.IssuedDate); // modify the three properties you want to change, that is the point
                    await _context.SaveChangesAsync();//then,update

    will be the same.

    Best Regards,

    Jerry Cai

    Friday, December 4, 2020 9:55 AM
  • User-190697402 posted

    Hi Jerry Cai,

    Set a break point to check

    var staffassets = await _context.StaffAssets.FirstOrDefaultAsync(c => c.StaffID == StaffAssets.StaffID && c.EmpID == StaffAssets.EmpID && c.StaffAssetName == StaffAssets.StaffAssetName);

    My Select query works as expected

    SELECT TOP(1) [s].[StaffID], [s].[EmpID], [s].[IssuedDate], [s].[IssuedQty], [s].[LastModifiedBy], [s].[LastModifiedTimestamp], [s].[ReturnDate], [s].[ReturnQty], [s].[StaffAssetName]
    FROM [StaffAssets] AS [s]
    WHERE (([s].[StaffID] = @__StaffAssets_StaffID_0) AND ([s].[EmpID] = @__StaffAssets_EmpID_1)) AND ([s].[StaffAssetName] = @__StaffAssets_StaffAssetName_2)

    But my update query is like this

    UPDATE [StaffAssets] SET [IssuedDate] = @p0, [IssuedQty] = @p1
    WHERE [StaffID] = @p2;

    this is causing the issue.Can i use direct query to update the field

    Friday, December 4, 2020 3:15 PM
  • User475983607 posted

    Are you sure StaffID is unique in StaffAssests?  Don't you need at least EmpID too?

    Friday, December 4, 2020 6:53 PM
  • User-190697402 posted

    Hi Jerry Cai,

    Is there a way to update the table using direct query,because currently my update query is showing like this,

    UPDATE [StaffAssets] SET [IssuedDate] = @p0, [IssuedQty] = @p1
    WHERE [StaffID] = @p2;

    Monday, December 7, 2020 7:36 AM