Reputation: 1763
Since I am rendering 8 items and all of them are being assigned a number, I would like to parse that number to a model and than manipulate that data from the controller. I've tried this so far, but I am getting null reference exception.
@{
int[] myItems = { 1, 2, 3, 4, 5, 6, 7, 8 };
}
@foreach (var item in myItems)
{
<div class="beds col-lg-3 col-md-4 col-sm-6 col-xs-12">
<h4>Bed: @item</h4> //System null reference
<a data-toggle="modal" data-target="#myModal3">
<img src='@Url.Content("~/Images/AWT-Bed.png")' onclick="@Model.ItemNumber = @item" />
</a>
</div>
}
Upvotes: 1
Views: 1630
Reputation: 652
I think you've misunderstood idea behind MVC and Razor templates as well. Flow is as follows:
Server-side
Controller accepts data from View, operates, creates Model (or better called ViewModel/DTO as Model is often more complex idea involving datastorage solutions)
That ViewModel is passed to the View Engine where it's rendered into final View that is passed to Client
Client-side
Client (web browser) displays View
Client sends new data, possibly collected from View, to Controller on the Server
There's no direct link between them and you can't do this:
onclick="@Model.ItemNumber = @item"
Server side and client side are separated via stateless communication chanel (HTTP protocol), without using sophisticated techniques, as websockets etc., there is no direct link between those two. Server renderes View, based on ViewModel's data obtained from Controller, sends it to the Client and forgets about it.
I don't know what you're trying to achieve but try this:
Controller on the server side
public class ViewModel
{
public int? SelectedItem { get; set; }
public int[] MyItems { get; set; }
}
public class MyController : Controller
{
[HttpGet]
public ActionResult MyAction(int? selectedItem = null)
{
// Here you create your ViewModel and pass it to the View Engine to render
ViewModel viewModel = new ViewModel()
{
SelectedItem = selectedItem,
MyItems = { 1, 2, 3, 4, 5, 6, 7, 8 },
};
return View(viewModel);
}
}
View, redenred on the server side but displayed on client's side
@model ViewModel
<h3>Currently selected item is: @(Model.SelectedItem != null ? Model.SelectedItem.Value.ToString() : "none selected yet")</h3>
@foreach (int item in Model.MyItems)
{
<div class="beds col-lg-3 col-md-4 col-sm-6 col-xs-12">
<h4>Bed: @item</h4>
<a data-toggle="modal" data-target="#myModal3">
<a href="@Url.Action('MyAction', new { selectedItem = item })"><img src='@Url.Content("~/Images/AWT-Bed.png")'/></a>
</a>
</div>
}
As you can see controller accepts input parameter "selectedItem" (which is null if action is called without parameters as when user first enters your page). It prepares ViewModel which is passed to the ViewEngine.
There it's rendered. We have loop which creates HTML with links and images. That HTML is then sent to the client's web browser. If user click's on the image the browser calls your controller again, passing input parameter "selectedItem" which is again passed into the View and so on.
Of course it would benefit greatly from AJAX technique but this example shows base rule of web pages - those are static, stateless things. You call action on the server, can pass parameters as input, get rendered result. No magic "assign that value to that model variable when user clicks something". Model (as everything) is temporary and exists only when controller's action is executed and view is rendered inside view engine. After that it's send to the browser and everything is removed from memory.
Upvotes: 4