Pobranie danych z tabeli widoku ASP mvc

0

Witam.
Uczę się dopiero ASP dlatego pozwalam sobie zadać takie pytanie:
Zdefiniowałem sobie klasę modelu, w którym oprócz pól mam także listę. Na widoku wyświetlam pola do edycji oraz wspomnianą listę standardowo w tabeli html'owej. W każdej z linii chciałem umieścić klawisz lub link usuwający wiersz na którym się znajduje z listy modelu.
I tu mam problem: jak mam przekazać do kontrolera wiersz który chcę skasować? Jeżeli używam @html.ActionLink to mogę bez problemu podać w wywołaniu wiersz listy ale nie mam wtedy w kontrolerze aktualnego stanu Modelu, czyli jeżeli coś zmienię w polach edycyjnych to nie widzę tych zmian w kontrolerze. Próbowałem użyć kontrolki "input" w typie "submit" gdyż wtedy mam w kontrolerze przekazany aktualny stan modelu ale nie wiem jak w takim wywołaniu przekazać wiersz, który chce usunąć. Znajdowałem już rozwiązania, w których wywoływane były metody [HttpPost] z różnymi parametrami (poprzez input - submit) ale nie wiem jak w submicie przekazać takie parametry.
Czy możecie podpowiedzieć jak coś takiego się obsługuje? Na pewno ktoś już coś takiego obsługiwał ale mnie nie udało się znaleźć tego w googlach.
Poniżej moja strona:

@model SimpleFamily.Models.UserAccount

@{
    ViewBag.Title = "Edycja użytkownika";
}

<h2>@ViewBag.Title</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Modyfikuj dane użytkownika</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @if (ViewBag.Message != null)
    {
        <div class="form-group">
            <div class="col-md-10">@ViewBag.Message</div>
        </div>
    }
    <div class="form-group">
        @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.Label("Login", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.UserName, "", new { @class = "text-danger" })
        </div>
    </div>

    <h4>Połączenia do lokali</h4>
    <table class="table">
        <tr>
            <th/>
            <th>
                <p>Nazwa lokalu</p>
            </th>
            <th/>
        </tr>

        @foreach (var item in Model.Connections)
        {
            <tr>
                <td>
                    @Html.HiddenFor(modelItem => item.LocalID);
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.LocalName)
                </td>
                <td>
                    @Html.ActionLink("Usuń", "DeleteConnection", new { item })
                    
                    <input type="submit" value="Usuń" class="btn" title="Usuń lokal" formaction="DelConnection" name="@Html.IdForModel()"/>
                </td>
            </tr>
        }

    </table>

    <div>
        <input type="submit" value="Dodaj" class="btn" title="Dodaj nowy lokal" formaction="AddNewConnection"/>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Zapisz" class="btn btn-default" title="Zapisz użytkownika" />
            <p class="btn btn-default">@Html.ActionLink("Anuluj", "Index")</p>
        </div>
    </div>

</div>
}

I kod części kontrolera:


        public ActionResult EditUser()
        {
            UserAccount user = Session["EditedUser"] as UserAccount;
            return View("EditUser", GetLayoutName(), user);
        }

        [HttpPost]
        public ActionResult DelConnection(UserAccount user, LocalConnection connection)
        {
            UserAccountNew addedUser = Session["AddedUser"] as UserAccountNew;
            if (addedUser != null)
            {
                addedUser.Connections.Remove(connection);
                Session["Addeduser"] = addedUser;
                ModelState.Clear();
                return RedirectToAction("Register");
            }

            UserAccount editedUser = Session["Editeduser"] as UserAccount;
            if (editedUser != null)
            {
                editedUser.Connections.Remove(connection);
                Session["Editeduser"] = editedUser;
                ModelState.Clear();
                return RedirectToAction("EditUser");
            }
            
            return null;
        }

oczywiście w wywołaniu metody DelConnection(UserAccount user, LocalConnection connection) parametr connection jest null'owy a gdyby był wypełniony to rozwiązałoby to mój problem.

I jeszcze definicja modelu:

public class UserAccount : ICloneable
    {
        public UserAccount()
        {
            Connections = new List<LocalConnection>();
        }

        [Key]
        public int UserID { get; set; }

        [Required(ErrorMessage = "Email jest wymagany.")]
        [MaxLength(50)]
        public string Email { get; set; }

        [Required(ErrorMessage = "Login jest wymagany.")]
        [MaxLength(50)]
        public string UserName { get; set; }

        [Required(ErrorMessage = "Hasło jest wymagane.")]
        [DataType(DataType.Password)]
        [MaxLength(50)]
        public string Password { get; set; }

        [Compare("Password", ErrorMessage = "Proszę powtórzyć hasło.")]
        [DataType(DataType.Password)]
        public string ConfirmPassword { get; set; }

        [Required(ErrorMessage = "Aktualne hasło jest wymagane.")]
        [DataType(DataType.Password)]
        public string OldPassword { get; set; }

        [DataType(DataType.Password)]
        public string ActualPassword { get; set; }

        public List<LocalConnection> Connections { get; set; }

        public object Clone()
        {
            UserAccount result = new UserAccount()
            {
                UserID = this.UserID,
                Email = this.Email,
                UserName = this.UserName,
                Password = this.Password,
                ConfirmPassword = this.ConfirmPassword,
                OldPassword = this.OldPassword
            };
            foreach (var item in Connections)
            {
                result.Connections.Add((LocalConnection)item.Clone());
            }

            return result;
        }
    }

public class LocalConnection : ICloneable
    {
        /// <summary>
        /// Konstrutkor
        /// </summary>
        public LocalConnection()
        {
            LocalID = 0;
        }

        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="localId"></param>
        public LocalConnection(int localId)
        {
            LocalID = localId;
        }

        [Key]
        public int LocalID { get; set; }

        public string LocalName { get; set; }

        public string SqlIP { get; set; }

        public int SqlPort { get; set; }

        public string SqlUser { get; set; }

        public string SqlPassword { get; set; }

        public string DBName { get; set; }

        public object Clone()
        {
            LocalConnection result = new LocalConnection()
            {
                LocalID = this.LocalID,
                LocalName = this.LocalName,
                SqlIP = this.SqlIP,
                SqlPort = this.SqlPort,
                SqlUser = this.SqlUser,
                SqlPassword = this.SqlPassword,
                DBName = this.DBName
            };

            return result;
        }

    }
0
  1. Dlaczego chcesz przekazać cały obiekt, a nie tylko jego ID?
  2. Przekazujesz do metody DelConnection(UserAccount user, LocalConnection connection) obiekt UserAccount ale go nie używasz w tej metodzie.
    Idąc tym tokiem rozumowania potrzebne ci jest tylko ID, aby wiedzieć który element z bazy usunać.

Nie mam jak sprawdzić, ale chyba będzie coś w ten deseń:

@Html.ActionLink("Usuń", "DeleteConnection", new { item.LocallD })
public ActionResult DelConnection(int LocalID)
{
   //Wyszukujesz w bazie obiektu Connection o ID = LocalID i usuwasz ;)
}
0

Masz rację, mogę użyć @html.ActionLink i w nim przekazać cały obiekt lub jego ID z tym nie mam problemu. Ale przy takie konstrukcji w kontrolerze nie mam zmian, które wcześniej wprowadził użytkownik na pozostałych polach modelu. Czyli np. użytkownik zmienia zawartość pola UserName a potem wciska klawisz usunięcia pozycji. Do kontrolera trafia mi odniesienie do usuwania pozycji ale w Modelu ma UserName z przed zmiany. I jak już wykonam usunięcie pozycji to ponownie wyświetlam stronę ale z zawartością pola UserName z przed zmiany a chciałbym wyświetlić stronę z wprowadzonymi zmianami. Z tego co do tej pory czytałem to jedyną metodą przesłania zmian w modelu z widoku do kontrolera jest wywołanie metody Submit. I tak do tej pory robiłem z innymi przykładami (np. gdy chciałem dodać nową pozycję). Ale nie wiem jak w metodzie Submit przekazać dodatkowe parametry (w tym przypadku indeks usuwanej pozycji). I to jest problem, którego nie mogę rozwiązać.
Może jest jakaś inna metoda, która pozwoli zmienić zawartość modelu bez zamykania strony (jakiś skrypt, Ajax czy coś podobnego)?

0

@WojtexProgramista:

Jeżeli chcesz to robić dynamicznie, to możesz wysłać np. posta z danymi javaskryptem, ale później również musisz podmienić te dane na stronie. Albo zmieniasz ręcznie tabelkę, albo przeładowujesz ją (pobierasz i rysujesz). Zawsze możesz sobie ułatwić i skorzystać z jakiegoś frameworka jsowego.

Ale w ogóle wypadałoby się zastanowić, czy nie lepiej usunąć to co już masz w tym widoku i zrobić tak, aby w całości bazował o wysyłania żądań jsem.

0
WeiXiao napisał(a):

@WojtexProgramista:

Jeżeli chcesz to robić dynamicznie, to możesz wysłać np. posta z danymi javaskryptem, ale później również musisz podmienić te dane na stronie. Albo zmieniasz ręcznie tabelkę, albo przeładowujesz ją (pobierasz i rysujesz). Zawsze możesz sobie ułatwić i skorzystać z jakiegoś frameworka jsowego.

Ale w ogóle wypadałoby się zastanowić, czy nie lepiej usunąć to co już masz w tym widoku i zrobić tak, aby w całości bazował o wysyłania żądań jsem.

Dzięki za podpowiedź ale możesz przytoczyć tu jakiś przykład? Np. posta z danymi javaskryptem?

1 użytkowników online, w tym zalogowanych: 0, gości: 1