I have two tables Users and Expenses in the backend. UserId is a foreignKey for the Expenses table. I need to pass the UserId from the Usercontroller to the ExpenseController to save expense info against the user id. But there are two problems.
- I am unable to use the id parameter that is passed to the expense controller
- Another is for the create expense form, i could not find any userId field in the
the form against which i am going to save the expense. So there is always modelstate.isvalid == false.
Please look at the following code. Hope you can help me.
//UserController
public ActionResult Index()
{
return View(db.Users.ToList());
}
// Inedx View(User)
<%= 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());
}
// Index view(Expense)
<%= Html.ActionLink("Create New", "Create", new { id=ViewData["id"]})%>
// Expense Controller(Create)
public ActionResult Create(int id)
{
//ViewData["id"] = id;
return View();
}
//Create View
<% 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>
<% } %>
//Create Post
[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);
}
}
I believe that the consensus right way to do this is to construct specific models for each view and populate that model with the data necessary for the view, including data that may be necessary for any actions that the view invokes. So, for instance, you’d have an expense model that your Create view would take, one of the things it would contain would be the associated user id for the expense. The Create action that handles the post would take an expense model, instead of a FormCollection, as it’s parameter. In your Create View you would store the user id from the model in a hidden field so that it’s value gets propagated back with the post.
View