0

I tried every solution and still my List is null.

Can u point me at right direction, I really don't know what is problem... View:

@using (Html.BeginForm("EditProfile", "User", FormMethod.Post, new { @class = "form form-horizontal" }))
{
    <div class="form-actions pb-0" />
    for (int i = 0; i < Model.UserAddress.Count; ++i)
    {
        <input id="btc-limit-buy-total" hidden type="text" class="form-control" value="@Model.UserAddress[i].AddressId" name="ProfileViewModel.UserAddress[@i].AddressId">
        <div class="form-group row">
            <label class="col-md-3 col-form-label" for="btc-limit-buy-total">Shipping address:</label>
            <div class="col-md-9">
                <input id="btc-limit-buy-total" type="text" @(Model.EditMode ? "" : "disabled") value="@Model.UserAddress[i].AddressLine1@(Model.UserAddress[i].AddressLine2 != null ? $", {Model.UserAddress[i].AddressLine2}" : "")" class="form-control" name="ProfileViewModel.UserAddress[@i].AddressLine1">
            </div>
        </div>
        <div class="form-group row">
            <label class="col-md-3 col-form-label" for="btc-limit-buy-total">City:</label>
            <div class="col-md-9">
                <input id="btc-limit-buy-total" type="text" @(Model.EditMode ? "" : "disabled") value="@Model.UserAddress[i].City" class="form-control" name="ProfileViewModel.UserAddress[@i].City">
            </div>
        </div>
        <div class="form-group row" @(Model.UserAddress[i].StateProvinceRegion != null ? "" : "hidden")>
            <label class="col-md-3 col-form-label" for="btc-limit-buy-total">State:</label>
            <div class="col-md-9">
                <input id="btc-limit-buy-total" type="text" @(Model.EditMode ? "" : "disabled") value="@Model.UserAddress[i].StateProvinceRegion" class="form-control" name="ProfileViewModel.UserAddress[@i].StateProvinceRegion">
            </div>
        </div>
        <div class="form-group row">
            <label class="col-md-3 col-form-label" for="btc-limit-buy-total">Country:</label>
            <div class="col-md-9">
                <input id="btc-limit-buy-total" type="text" @(Model.EditMode ? "" : "disabled") value="@Model.UserAddress[i].Country" class="form-control" name="ProfileViewModel.UserAddress[@i].Country">
            </div>
        </div>
        <div class="form-group row" @(Model.UserAddress[i].Zip != null ? "" : "hidden")>
            <label class="col-md-3 col-form-label" for="btc-limit-buy-total">Postal code:</label>
            <div class="col-md-9">
                <input id="btc-limit-buy-total" type="text" @(Model.EditMode ? "" : "disabled") value="@Model.UserAddress[i].Zip" class="form-control" name="ProfileViewModel.UserAddress[@i].Zip">
            </div>
        </div>
        <div class="form-group row" @(Model.UserAddress[i].DeliveryInstructions != null ? "" : "hidden")>
            <label class="col-md-3 col-form-label" for="btc-limit-buy-total">Additional info:</label>
            <div class="col-md-9">
                <input id="btc-limit-buy-total" type="text" @(Model.EditMode ? "" : "disabled") value="@Model.UserAddress[i].DeliveryInstructions" class="form-control" name="ProfileViewModel.UserAddress[@i].DeliveryInstructions">
            </div>
        </div>
        <div class="form-group row">
            <label class="col-md-3 col-form-label" for="btc-limit-buy-total">Phone number:</label>
            <div class="col-md-9">
                <input id="btc-limit-buy-total" type="text" @(Model.EditMode ? "" : "disabled") value="@Model.UserAddress[i].PhoneNumber" class="form-control" name="ProfileViewModel.UserAddress[@i].PhoneNumber">
            </div>
        </div>
        <div class="form-actions pb-0" />
    }
}
<input type="submit" value="Edit profile" class="btn round btn-success btn-block btn-glow" />

I read about posting "name" attribute to right value and I did that with and without ViewModel prefix and still list is null. Also, I read that u can't use foreach, so I am using for. Controller:

[HttpPost]
        public ActionResult EditProfile(List<UserAddress> userAddresses)
        {
            var model = PopulateProfileViewModel();
            model.EditMode = true;

            if (!ModelState.IsValid)
            {
                return View("Profile");
            }

            //model.UserAddress = userAddresses;
            //TODO update db

            return View("Profile", model);
        }

EDIT:

UserAddress class:

public class UserAddress
    {
        public short AddressId { get; set; }
        public string FullName { get; set; }
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string StateProvinceRegion { get; set; }
        public string Zip { get; set; }
        public string PhoneNumber { get; set; }
        public string DeliveryInstructions { get; set; }
        public bool Active { get; set; }
    }
Serlok
  • 432
  • 1
  • 10
  • 24
  • Change your name's to be `name="userAddresses[x].SomeProperty"`. You don't need to place the name of the model at the front of the name property unless you are passing the model back to the View. Otherwise, the name property should match the corresponding parameter name in your Controller – Ryan Wilson Nov 29 '18 at 13:10
  • You have to use `IEnumerable` or `array[]` instead of `List` – Markiian Benovskyi Nov 29 '18 at 13:10
  • @RyanWilson I did, that was my first try, before this, still nothing – Serlok Nov 29 '18 at 13:12
  • @MarkiianBenovskyi Tried, still null... – Serlok Nov 29 '18 at 13:13
  • @Serlok Also, your submit button needs to be contained in the form brackets. – Ryan Wilson Nov 29 '18 at 13:13
  • @RyanWilson My bad, I placed it inside now, but still the same. – Serlok Nov 29 '18 at 13:15
  • @Serlok Some of the Razor stuff you are doing in there seems a bit suspect, like this for instance: `
    ` Make sure you don't have any malformed HTML in there or that can mess up the form submission. One other thing to check also is, are all of the properties of object `UserAddress` declared as `public` with `sets` and `gets`?
    – Ryan Wilson Nov 29 '18 at 13:17
  • Yep, properties are: `public List UserAddress { get; set; } public bool EditMode { get; set; } ` And about that code, I checked inside html if it is working, and it is working, it is hidding when it needs to, but if it's not supposed to be used like that, then I am not sure – Serlok Nov 29 '18 at 13:19
  • 1
    @Serlok Could you post your `UserAddress` class please? Also, why aren't you using `HTML helpers` for your form inputs, like `@Html.TextBoxFor` etc.? – Ryan Wilson Nov 29 '18 at 13:20
  • @Serlok Ok. Your class looks good, thanks for adding that. – Ryan Wilson Nov 29 '18 at 13:22
  • @RyanWilson I got this HTML for my project, so it was easier for me to add little code inside it, then to change it. – Serlok Nov 29 '18 at 13:22
  • @Serlok I think your HTML may be malformed, like this line for instance `` see how the word "hidden" is just there outside of quotations? – Ryan Wilson Nov 29 '18 at 13:24
  • 1
    @Serlok Another thing I'd like to point out, the `id` property of an element should always be unique, you have multiple inputs with the same `id` of ` – Ryan Wilson Nov 29 '18 at 13:27
  • @RyanWilson I commented out all div hidden attributes, still same... Yes, u r right, I just copy/ pasted inputs, I will change that also. – Serlok Nov 29 '18 at 13:29
  • @Serlok I am putting together a test project in visual studio now which I will try to re-create your form and model list and see if I can get it to submit correctly. – Ryan Wilson Nov 29 '18 at 13:30
  • @Serlok What is `EditMode` set to when you pass the model to the view? If it is false, it will add disabled to all your form inputs, which if a form input is set to disabled, it will not submit to the controller. If you need to do something like disabled, you can make your inputs `readonly` which will submit to your controller. – Ryan Wilson Nov 29 '18 at 13:40
  • 1
    I got it working in a test project. I changed your controller method to accept a model of the type which contains the list of UserAddress objects, then changed all the names to parameter name in controller .ListName[x].PropertyName – Ryan Wilson Nov 29 '18 at 13:57
  • @RyanWilson U sir are legend! Ty so much, this worked like a charm. If u wish, post respond to this question, I will check it as right answer. – Serlok Nov 30 '18 at 07:49
  • @Serlok Glad I could help and that your project is working correctly. I posted an answer below as you requested. – Ryan Wilson Nov 30 '18 at 13:02

1 Answers1

1

I got it working in a test project. I changed your controller method to accept a model of the type which contains the list of UserAddress objects, then changed all the names to parameter name in controller .ListName[x].PropertyName

Ryan Wilson
  • 10,223
  • 2
  • 21
  • 40