Home > Software engineering >  How to insert multiple values from .net 5.0 razor pages in SQL Server?
How to insert multiple values from .net 5.0 razor pages in SQL Server?

Time:01-24

I want to select multiple services for a client and save them to database, on single click.

When i click save, it stores only the first service. So far, on the backend side (OnPost), i have tried with: .add() , addrange(), foreach(), for(), but still no luck. I cant understand what i am doing wrong!

My frontend code is as below:

 <form method="post">
                <div >
                        @for (int i = 18; i < 40; i  )
                        {
                            <input asp-for="ClientServices.CliId"  value="@Model.CliIdOk" hidden />
                            <input  asp-for="ClientServices.ServId" value="@i" hidden />
                            <div  style="width: 6%; height: 150px; min-width: 30px; float: left; ">
                                <div  style="position:relative;left:-15px;">
                                    <label  style="border-radius:16px;">
                                        <input asp-for="ClientServices.Active"
                                       style="border-radius:16px;position:relative;" />
                                        <br />
                                        @i
                                    </label>
                                </div>
                            </div>
                        }
            </div>
             <button  type="submit" name="id"
        style="font-size: 120%;float:unset;min-width:120px;">
            Save
        </button>
        </form>

My backend "OnPost" code is:

 public async Task<IActionResult> OnPostAsync()
    {
        try
        {
            //if (!ModelState.IsValid)
            //{
            //    return Page();
            //}

            _context.ClientServices.AddRange(ClientService);

            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
        catch (Exception e)
        {
            e.ToString();
            return RedirectToPage("./Index");
        }
    }

CodePudding user response:

When i click save, it stores only the first service. So far, on the backend side (OnPost), i have tried with: .add() , addrange(), foreach(), for(), but still no luck. I cant understand what i am doing wrong!

Well, couple of mistake has been found on your code.

Mistake: 1:

Getting only the first object while submitting list is pretty obvious as per your shared code snippet. You cannot save all list following this way because, your post method model doesn't aware of your list. As you are sending the flat object like this asp-for="ClientServices.CliId" so only the first object will be evaluated instead you outght to send like this way asp-for="@Model.clientServices[i].CliId". So that model binding can map the object list with your backed.

Mistake: 2:

On OnPostAsync() you supposed to send list of object not sure how you are passsing it AddRange(ClientService);. I think here in ClientService you are not getting the list as well.

Solution:

cshtml:

Your view should be modified as following:

@page
@model RazorPageDemoApp.Pages.AddMultipleDataModel



<form method="post">
    <div >
        @for (int i = 0; i <Model.clientServices.Count(); i  )
        {
            <input asp-for="@Model.clientServices[i].CliId"  value="@Model.clientServices[i].CliId" hidden />
            <input  asp-for="@Model.clientServices[i].ServId" value="@Model.clientServices[i].ServId" hidden />
            <div  style="width: 6%; height: 150px; min-width: 30px; float: left; ">
                <div  style="position:relative;left:-15px;">
                    <label  style="border-radius:16px;">
                        <input asp-for="@Model.clientServices[i].Active" value="@Model.clientServices[i].CliId"
                           style="border-radius:16px;position:relative;" />
                        <br />
                        @i
                    </label>
                </div>
            </div>
           
        }
       
    </div>

    <div>

        <button  type="submit" name="id"
                style="font-size: 120%;float:unset;min-width:120px; margin-top:100px">
            Save
        </button>
    </div>

</form>

Note: The crucial part are Model.clientServices.Count() and asp-for="@Model.clientServices[i].CliId" if doesn't map your model this way, your model binding wouldn't be mapped accordingly.

cshtml.cs:

public class AddMultipleDataModel : PageModel
    {
        private readonly AppDbContext _context;

        public AddMultipleDataModel(AppDbContext context)
        {
            _context = context;
        }
       
        public List<ClientService> clientServices { get; set; }
        public void OnGet()
        {
            var clientServiceList = new List<ClientService>()
            {
                new ClientService(){ CliId ="CliId:1",ServId = "ServId-A",Active = false},
                new ClientService(){ CliId ="CliId:2",ServId = "ServId-B",Active = false},
                new ClientService(){ CliId ="CliId:3",ServId = "ServId-C",Active = true},
                new ClientService(){ CliId ="CliId:4",ServId = "ServId-D",Active = true},
                new ClientService(){ CliId ="CliId:5",ServId = "ServId-E",Active = false},
               
            };
            clientServices = clientServiceList;

        }
        [HttpPost]
        public async Task<IActionResult> OnPostAsync(List<ClientService> clientServices)
        {
            try
            {
                //if (!ModelState.IsValid)
                //{
                //    return Page();
                //}

                _context.clientServices.AddRange(clientServices);

                await _context.SaveChangesAsync();

                return RedirectToPage("./AddMultipleData");
            }
            catch (Exception e)
            {
                e.ToString();
                return RedirectToPage("./Index");
            }
        }
    }

Note: As you might notice, I have constructed post method as OnPostAsync(List<ClientService> clientServices) means it will accept list of object from your view.

Output:

enter image description here

Note: If you are interested to know more about Razor page post list and other stuff, please have a look our official document here.

  • Related