3 votes

ASP MVC Problème de soumission de clé étrangère

J'ai deux tableaux, Utilisateurs et Dépenses, dans le backend. UserId est une clé étrangère pour la table Expenses. J'ai besoin de faire passer l'UserId du Usercontroller au ExpenseController pour enregistrer les informations de dépenses en fonction de l'identifiant de l'utilisateur. Mais il y a deux problèmes.

  1. Je ne parviens pas à utiliser le paramètre id qui est transmis au contrôleur des dépenses.
  2. D'autre part, pour le formulaire de création de dépenses, je n'ai pas trouvé de champ userId dans le champ le formulaire contre lequel je vais enregistrer la dépense. Donc il y a toujours modelstate.isvalid == false.

Veuillez consulter le code suivant. J'espère que vous pourrez m'aider.

//Contrôleur d'utilisateur

public ActionResult Index()
{
    return View(db.Users.ToList());
}

// Vue Inedx(Utilisateur)

<%= Html.ActionLink("Expenses", "Index", "Expense", new { id=item.Id}, null)%>

// ExpenseController

public ActionResult Index(int id)
{
    ViewData["id"] = id;
    return View(db.Expenses.Where(x => x.Users.Id == id).ToList());
}

// Vue de l'index (dépenses)

<%= Html.ActionLink("Create New", "Create", new { id=ViewData["id"]})%>

// Contrôleur de dépenses (Créer)

    public ActionResult Create(int id)
    {
        //ViewData["id"] = id;
        return View();
    } 

//Créer une vue

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>

        <p>
            <label for="ExpenseTitle">ExpenseTitle:</label>
            <%= Html.TextBox("ExpenseTitle") %>
            <%= Html.ValidationMessage("ExpenseTitle", "*") %>
        </p>
        <p>
            <label for="ExpenseDescription">ExpenseDescription:</label>
            <%= Html.TextBox("ExpenseDescription") %>
            <%= Html.ValidationMessage("ExpenseDescription", "*") %>
        </p>
        <p>
            <label for="Date">Date:</label>
            <%= Html.TextBox("Date") %>
            <%= Html.ValidationMessage("Date", "*") %>
        </p>
        <p>
            <label for="Expense">Expense:</label>
            <%= Html.TextBox("Expense") %>
            <%= Html.ValidationMessage("Expense", "*") %>
        </p>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

<% } %>

//Créer un poste

[AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(FormCollection collection)
    {
        var expense = new Expenses();
        try
        {
            TryUpdateModel(expense, new string[] {"UserId", "ExpenseTitle", "ExpenseDescription", "Date", "Expense" }, collection.ToValueProvider());

                if (ModelState.IsValid)
                {
                    db.AddToExpenses(expense);
                    db.SaveChanges();
                    return RedirectToAction("Index",int.Parse(collection["UserId"]));
                }
                else {
                    return View(expense);
                }

            }
            catch
            {
                return View(expense);
            }
        }

7voto

tvanfosson Points 268301

Je crois que le consensus droite La façon de procéder est de construire des modèles spécifiques pour chaque vue et de remplir ce modèle avec les données nécessaires à la vue, y compris les données qui peuvent être nécessaires pour toute action invoquée par la vue. Ainsi, par exemple, vous disposez d'un modèle de dépenses que votre vue Créer prend en compte. Il contient notamment l'identifiant de l'utilisateur associé à la dépense. L'action Create qui gère le post prendrait un modèle de dépense, au lieu d'un FormCollection, comme paramètre. Dans votre vue de création, vous stockez l'identifiant de l'utilisateur du modèle dans un champ caché afin que sa valeur soit propagée avec le message.

[AcceptVerbs( HttpVerbs.Get )]
public ActionResult Create(int id)
{
    return View( new ExpenseModel { UserId = id } );
}

[AcceptVerbs( HttpVerbs.Post )]
public ActionResult Create( ExpenseModel expense )
{
  ...
}

Voir

... Inherits="System.Mvc.ViewPage<ExpenseModel>" %>

<% using (Html.BeginForm()) { %>

    <%= Html.Hidden( "UserId" ) %>

    ...
<% } %>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X