Performing create operations on two models via one action - asp.net-mvc-3

I have two models : Category and Picture which refers to two tables, Categories and Pictures respectively. The Category model has a navigation property to Picture model.
Now, I created a controller using Scaffolding feature with CRUD operations for Category. Following is the code :-
public ActionResult Create()
{
ViewBag.ParentCategoryId = new SelectList(db.Categories, "Id", "Name");
ViewBag.PictureId = new SelectList(db.Pictures, "Id", "PictureUrl");
return View();
}
The automatically generated controller actions uses SelectList for listing the available Picture entries in the database and passes it down to dropdownlist for selection. This is not the ideal scenario since what I want is to unable the user to upload the Picture and then the reference is added to Category model. Later, the entries are saved to Categories and Pictures table.

Create model like this:
public class FullCategoryModel
{
public HttpPostedFileBase Picture { get; set; }
public Category CategoryModel {get; set;}
}
In view:
#using (Html.BeginForm("Create", "Category", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.TextBoxFor(model => model.Category.Name) // example, put there all category details
<input type="file" name="Picture" id="Picture" />
<input type="submit" value="Upload" />
}
Then create action:
[ActionName("Create")]
[HttpPost]
public ActionResult Create(FullCategoryModel model)
{
// here you can get image in bytes and save it in db,
// also all category detail are avalliable here
MemoryStream ms = new MemoryStream();
model.Picture.InputStream.CopyTo(ms);
Image picture = System.Drawing.Image.FromStream(ms);
// save in db as separate objects, than redirect
return RedirectToAction("Index", "Category");
}

First of all, I would like to thank #NickLarsen for making me believe that my understanding is good and i can achieve the task myself.
The problem was not that too tough but since i was new to Asp.net MVC, things were bit baffling. From the very start, I had the notion that i will be needing a ViewModel merging Category and Price classes and then a picture uploading API. But, somehow I wasn't able to fit the pieces in right place. Therefore after various regression and research over the internet, I achieved the task in following manner :-
First of all, I created a ViewModel
public class CatPicView
{
public Category Category { get; set; }
public Picture Picture { get; set; }
}
Second, I added the Uploadify javascript API
<script type="text/javascript">
$('#file_upload').uploadify({
'uploader': '#Url.Content("~/uploadify/uploadify.swf")',
'script': '#Url.Action("Upload", "Category")',
'cancelImg': '#Url.Content("~/uploadify/cancel.png")',
'buttonText': 'Upload',
'folder': '#Url.Content("~/content/images")',
'fileDesc': 'Image Files',
'fileExt': '*.jpg;*.jpeg;*.gif;*.png',
'auto': true,
'onComplete': function (event, ID, fileObj, response, data) {
var json = jQuery.parseJSON(response);
$("#pictureImage").html("<img src='"+json+"' alt='"+json+"' height='100px' width='100px'/>");
$("#Picture_PictureUrl").val(json);
$("#pictureRemove").show();
}
});
</script>
Hooked the API to following Server Function for renaming and saving to folder
[HttpPost]
public ActionResult Upload(HttpPostedFileBase fileData)
{
if (fileData != null && fileData.ContentLength > 0)
{
//var fileName = Server.MapPath("~/Content/Images/" + Path.GetFileName(fileData.FileName));
int pictureCount = 800000;
pictureCount += db.Pictures.Count();
string extension = Path.GetExtension(fileData.FileName);
string renamedImage = Server.MapPath("~/Content/Images/Categories/cat" + pictureCount + extension);
fileData.SaveAs(renamedImage);
return Json("/Content/Images/Categories/" + Path.GetFileName(renamedImage));
}
return Json(false);
}
And at last, rewrote the Category create Function as below for saving changes to DB
[HttpPost]
public ActionResult Create(CatPicView catPic)
{
if (ModelState.IsValid)
{
if (!String.IsNullOrEmpty(catPic.Picture.PictureUrl))
{
Picture picture = new Picture();
picture.PictureUrl = catPic.Picture.PictureUrl;
db.Pictures.Add(picture);
catPic.Category.PictureId = picture.Id;
}
db.Categories.Add(catPic.Category);
db.SaveChanges();
return RedirectToAction("Index");
}
return View();
}

I think MVC scaffolding feature see the relation of two models as "Many to Many". That's why it created two drop down list for you. According to your scenario, you could do "Category" create page without "Picture" model data because "Picture" is the main entity here. So In the picture create action.
[HttpPost]
public ActionResult Create(Picture picture)
{
if (ModelState.IsValid)
{
databaseContext.Pictures.Add(picture);
databaseContext.SaveChanges();
return RedirectToAction("Index");
}
return View(picture);
}
In the view page of create picture
#model YourProjectName.Models.Picture
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Picture</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Url)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Url)
#Html.ValidationMessageFor(model => model.Url)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Categories.CategoryID, "Category")
</div>
<div class="editor-field">
#Html.DropDownList("CategoryID", "Choose Category")
#Html.ValidationMessageFor(model => model.Categories.CategoryID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}

Related

how do I build a composite UI in MVC3?

I understand how to use Partial Views, and I understand Ajax.ActionLink and Ajax.BeginForm when it comes to how to set those up in the view. I'm assuming each partial view has it's own controller. I'm thinking bounded context here, as in each partial view could talk to it's own bounded context via its own controller
I guess the piece I'm missing is:
how to have partial views included in a "master view" (or holding view) and have each of these partial views independently post to a separate controller action, and then return to refresh the partial view WITHOUT loading the "master view" or holding view.
the "master" view or holding view still needs to have its own controller, I want to keep the master controller from reloading its view, and let the view that is produced by an action method of the master controller hold a reference to these two partial views.
There are two approaches it seems I can take, one is to use the "Ajax." functionality of MVC3, the other is to use straight-up jQuery and handle all this interaction by hand from the client side.
Is what I'm trying to do possible both ways, or is one way "better suited" to this type of composite ui construction?
So far, the only things I have seen are trivial examples of composite ui construction like a link via an Ajax.ActionLink that refreshes a single on the page, or a form written as an Ajax.BeginForm that repopulates a div with some content from a partial view.
Okay, so I finally have some working code that I think is the right way to do it. Here is what I went with. I have a two simple "entities"; Customer and BillingCustomer. They're really meant to be in separate "bounded contexts", and the classes are super-simple for demostration purposes.
public class Customer
{
public Guid CustomerId { get; set; }
public string Name { get; set; }
}
public class BillingCustomer
{
public Guid CustomerId { get; set; }
public bool IsOverdueForPayment { get; set; }
}
Note that both classes reference CustomerId, which for the sake of this demo, is a GUID.
I started with a simple HomeController that builds a ViewModel that will be utilized by the Index.cshtml file:
public ActionResult Index()
{
var customer = new Customer {
CustomerId = Guid.Empty,
Name = "Mike McCarthy" };
var billingCustomer = new BillingCustomer {
CustomerId = Guid.Empty,
IsOverdueForPayment = true };
var compositeViewModel = new CompositeViewModel {
Customer = customer,
BillingCustomer = billingCustomer };
return View(compositeViewModel);
}
The CompositeViewModel class is just a dumb DTO with a property for each domain entity, since the partial views I'll be calling into in my Index.cshtml file each need to pass their respective domain model into the partial view:
public class CompositeViewModel
{
public BillingCustomer BillingCustomer { get; set; }
public Customer Customer { get; set; }
}
Here is my resulting Index.cshtml file that uses the Index method on the HomeController
#model CompositeViews.ViewModels.CompositeViewModel
<h2>Index - #DateTime.Now.ToString()</h2>
<div id="customerDiv">
#{Html.RenderPartial("_Customer", Model.Customer);}
</div>
<p></p>
<div id="billingCustomerDiv">
#Html.Partial("_BillingCustomer", Model.BillingCustomer)
</div>
A couple things to note here:
the View is using the CompositeViews.ViewModels.CompositeViewModel ViewModel
Html.RenderPartial is used to render the partial view for each
entity, and passes in the appropriate entity. Careful with the
syntax here for the Html.Partial call!
So, here is the _Customer partial view:
#model CompositeViews.Models.Customer
#using (Ajax.BeginForm("Edit", "Customer", new AjaxOptions {
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "customerDiv" }))
{
<fieldset>
<legend>Customer</legend>
#Html.HiddenFor(model => model.CustomerId)
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
the important part here is the Ajax.BeginForm call. Note that it's explicitly calling the Edit ActionMethod of the CustomerController. Also note that the UpdateTargetId is set to "customerDiv". This div is NOT in the partial view, but rather in the "parent" view, Index.cshtml.
Below is the _BillingCustomer view
#model CompositeViews.Models.BillingCustomer
#using (Ajax.BeginForm("Edit", "BillingCustomer", new AjaxOptions {
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "billingCustomerDiv" }))
{
<fieldset>
<legend>BillingCustomer</legend>
#Html.HiddenFor(model => model.CustomerId)
<div class="editor-label">
#Html.LabelFor(model => model.IsOverdueForPayment)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.IsOverdueForPayment)
#Html.ValidationMessageFor(model => model.IsOverdueForPayment)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
Again, note that UpdateTargetId is set to billingCustomerDiv. This div is located in the Index.cshtml file, not this partial view file.
So, the only thing we haven't looked at yet is the Edit ActionResult on the CustomerController and the BillingCustomerController. Here is the CustomerController
public class CustomerController : Controller
{
[HttpGet]
public PartialViewResult Edit(Guid customerId)
{
var model = new Customer {
CustomerId = Guid.Empty,
Name = "Mike McCarthy"};
return PartialView("_Customer", model);
}
[HttpPost]
public ActionResult Edit(Customer customer)
{
return PartialView("_Customer", customer);
}
}
There is nothing really "happening" in this controller, as the post deals directly with building a composite UI. Notice how we're returning via "PartialView" and specifying the name of the partial view to use, and the required model the view needs to render.
Here is BillingCustomerController
public class BillingCustomerController : Controller
{
[HttpGet]
public PartialViewResult Edit(Guid customerId)
{
var model = new BillingCustomer {
CustomerId = Guid.Empty,
IsOverdueForPayment = true };
return PartialView("_BillingCustomer", model);
}
[HttpPost]
public PartialViewResult Edit(BillingCustomer billingCustomer)
{
return PartialView("_BillingCustomer", billingCustomer);
}
}
Again, the same as CustomerController, except for the fact that it's this controller is dealing with the BillingCustomer entity.
Now when I load up my HomeController's Index ActionResult, I get a screen that looks like this:
Each Save button will do an async postback to the controller the partial view needs to update and talk to in order to get data, all without causing a regular postback for the whole page. You can see the DateTime stamp does NOT change when hitting either save button.
So, that's how I went about building my first composite view using partial views. Since I'm still very new to MVC3, I could still be screwing something up, or doing something in a way that is harder than it needs to be, but this is how I got it working.

MVC3 Postback doesn't have modified data

So I have the following code:
#model Project.Models.ViewModels.SomeViewModel
#using (Html.BeginForm("SomeAction", "SomeController", new { id = Model.Id}))
{
for(int i = 0; i < Model.SomeCollection.Count(); i++)
{
#Html.HiddenFor(x => Model.SomeCollection.ElementAt(i).Id)
<div class="grid_6">
#Html.TextAreaFor(x => Model.SomeCollection.ElementAt(i).Text, new { #style = "height:150px", #class = "grid_6 input" })
</div>
}
<div class="grid_6 alpha omega">
<input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
</div>
}
On the Controller Side I have the following:
[HttpPost]
public ActionResult SomeAction(int id, SomeViewModel model)
{
return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
}
My View Model is set up like this:
public class SomeViewModel
{
public SomeViewModel()
{
}
public IEnumerable<ItemViewModel> SomeCollection { get; set; }
}
public class ItemViewModel{
public ItemViewModel(){}
public int Id {get;set;}
public string Text{get;set;}
}
The SomeCollection is always empty when SomeAction if performed. What do I have to do in order to show the updated values by users. Text Property and Id field.
Use an EditorTemplate
Create an EditorTemplate folder under your Views/YourcontrollerName and create a view with name ItemViewModel.cshtml
And Have this code in that file
#model Project.Models.ViewModels.ItemViewModel
<p>
#Html.EditorFor(x => x.Text)
#Html.HiddenFor(x=>x.Id)
</p>
Now from your Main view, call it like this
#model Project.Models.ViewModels.SomeViewModel
#using (Html.BeginForm("SomeAction", "Home", new { id = Model.Id}))
{
#Html.EditorFor(s=>s.SomeCollection)
<div class="grid_6 alpha omega">
<input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
</div>
}
Now in your HTTPPOST method will be filled with values.
I am not sure what you want to do with the values( returning the partial view ?) So not making any comments about that.
I am not sure you have posted all the code.
Your action method does not do anything, since it returns a partial view (for some reason from a post call, not an ajax request) using a new model object.
Your effectively passing a model back to the action and then discarding it, and returning a new model object. This is the reason your collection is always empty, its never set anywhere.
Well, for one thing, why do you have both the model AND id, a property of model, sent back to the controller? Doesn't that seem a bit redundant? Also, you're using a javascript for loop in the view. It'd be much easier to just use #foreach.
Anyway, your problem is that when you tell an action to accept a model, it looks in the post for values with keys matching the names of each of the properties of the model. So, lets say we have following model:
public class Employee
{
public string Name;
public int ID;
public string Position;
}
and if I'm passing it back like this:
#using(Html.BeginForm("SomeAction", "SomeController"))
{
<input type="text" name = "name" [...] /> //in your case HtmlHelper is doing this for you, but same thing
<input type="number" name = "id" [...] />
<input type="submit" name = "position" [...] />
}
To pass this model back to a controller, I'd have to do this:
Accepting a Model
//MVC matches attribute names to form values
public ActionResult SomethingPosted(Employee emp)
{
//
}
Accepting a collection of values
//MVC matches parameter names to form values
public ActionResult SomethingPosted(string name, int id, string postion)
{
//
}
or this:
Accepting a FormCollection
//same thing as first one, but without a strongly-typed model
public ActionResult SomethingPosted(FormCollection empValues)
{
//
}
So, here's a better version of your code.
Your new view
#model Project.Models.ViewModels.SomeViewModel
#{
using (Html.BeginForm("SomeAction", "SomeController", new { id = Model.Id}))
{
foreach(var item in Model)
{
#Html.HiddenFor(item.Id)
<div class="grid_6">
#Html.TextAreaFor(item.Text, new { #style = "height:150px", #class = "grid_6 input" })
</div>
}
<div class="grid_6 alpha omega">
<input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
</div>
}
}
Your new action
[HttpPost]
public ActionResult SomeAction(int Id, string Text)
{
//do stuff with id and text
return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
}
or
[HttpPost]
public ActionResult SomeAction(IEnumerable<ItemViewModel> SomeCollection) //can't use someviewmodel, because it doesn't (directly) *have* members called "Id" and "Text"
{
//do stuff with id and text
return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
}

Sending new order back to MVC controller

using the JQuery sortable, and trying to send the new order back to my controller, but not having a whole lot of luck. My view is:
using (Ajax.BeginForm("EditTickerOrder", new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "POST", }))
{
<div id="editableticker">
#Html.HiddenFor(m => m.ProjectGUID)
<ul id="sortablediv">
#foreach (DGI.CoBRA.Tools.BussinessObjects.CollabLibrary.TickerObjects.Ticker t in Model)
{
<li class="ui-state-default" id="#t.pKeyGuid.ToString()">
<p>#Html.CheckBox(t.pKeyGuid.ToString(), t.Display, new { #class = "activechk" })
<span style="font-weight: bold">
#t.Text
</span>
</p>
</li>
}
</ul>
<input type="submit" value="Save New Ticker Order" />
}
and my controller is:
[HttpPost]
public ActionResult EditTickerOrder(Guid ProjectGUID, List<string> items)
{
TickerCollectionModel TickerData = new TickerCollectionModel();
TickerData.ProjectGUID = ProjectGUID;
TickerData.ListAllBySession(ProjectGUID);
return PartialView("TickerList", TickerData);
}
yet the list<string> items is always null. Any ideas?
You are writing foreach loops, most definitely violating the naming conventions for your form input fields that the default model binder expects for working with collections. If you don't respect the established wire format, you cannot expect the default model binder to be able to rehydrate your models in the POST action.
In fact, why don't you use view models and editor templates? They make everything trivial in ASP.NET MVC.
So let's define a view model that will reflect your view requirements (or at least those shown in your question => you could of course enrich it with additional properties that you want to handle):
public class TickerViewModel
{
public Guid Id { get; set; }
public bool IsDisplay { get; set; }
public string Text { get; set; }
}
public class ProjectViewModel
{
public Guid ProjectGUID { get; set; }
public IEnumerable<TickerViewModel> Tickers { get; set; }
}
and then a controller whose responsibility is to query your DAL layer, retrieve a domain model, map the domain model into the view model we defined for this view and pass the view model to the view. Inversely, the POST action receives a view model from the view, maps the view model back into some domain model, passes the domain model to your DAL layer for processing and renders some view or redirects to a success action:
public class HomeController : Controller
{
public ActionResult Index()
{
// TODO: those values come from a data layer of course
var model = new ProjectViewModel
{
ProjectGUID = Guid.NewGuid(),
Tickers = new[]
{
new TickerViewModel { Id = Guid.NewGuid(), Text = "ticker 1" },
new TickerViewModel { Id = Guid.NewGuid(), Text = "ticker 2" },
new TickerViewModel { Id = Guid.NewGuid(), Text = "ticker 3" },
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(ProjectViewModel model)
{
// Everything will be correctly bound here => map the view model
// back into your domain model and pass the domain model to
// your DAL layer for processing ...
return Content("Thanks for submitting");
}
}
a view (it is worth noting that in this example I have used a standard form instead of AJAX but it is trivial to convert it into an AJAX form):
#model ProjectViewModel
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.ProjectGUID)
<div id="editableticker">
<ul id="sortablediv">
#Html.EditorFor(x => x.Tickers)
</ul>
</div>
<button type="submit">OK</button>
}
and finally the corresponding editor template which will automatically be rendered for each element of the Tickers collection (~/Views/Home/EditorTemplates/TickerViewModel.cshtml):
#model TickerViewModel
<li class="ui-state-default">
<p>
#Html.CheckBoxFor(x => x.IsDisplay, new { #class = "activechk" })
#Html.LabelFor(x => x.IsDisplay, Model.Text)
#Html.HiddenFor(x => x.Text)
#Html.HiddenFor(x => x.Id)
</p>
</li>

How to handle Dropdownlist in mvc asp .net

this is my Model1 class
namespace chetan.Models
{
public class Model1
{
public string selectedItem { get; set; }
public IEnumerable<SelectListItem> items { get; set; }
}
}
this is my controller class
public class HomeController : Controller
{
private rikuEntities rk = new rikuEntities();
public ActionResult Index()
{
var model = new Model1
{
items = new[]
{
new SelectListItem { Value = "Theory", Text = "Theory" },
new SelectListItem { Value = "Appliance", Text = "Appliance" },
new SelectListItem { Value = "Lab", Text = "Lab" }
}
}; return View(model);
}
public ActionResult viewToController(Model1 m)
{
string getSelectedName = m.selectedItem;
return Content(getSelectedName);
}
}
this is my view...
#using (Html.BeginForm("viewToController", "Home"))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>emp</legend>
<div class="editor-field">
#Html.DropDownListFor(x => x.selectedItem,
new SelectList(Model.items, "Value", "Text"))
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
i want to add a drop downlist and i want to use selected value in viewToController action of homeController. and there is also one error in View page is "an expression tree may not contain dynamic operation" in (x=>x.selectedItem). Please solve my problem .
I don't understnad what you exactly need. You want to dynamicly add items to the drop down from the database?
I'm big fan of jQuery. You can do everything what you want with HTML using jQuery. So if you are looking how to automaticly add items to the drop down, take look at this: How do I add options to a DropDownList using jQuery?

UpdateModel not updating the model via ViewModel and property from DropDownListFor

I am trying to set up an Edit view on which I have a text box and DropDownListFor. I have figured out a way to populate the DDLF, and the rendered and posted values are correct, but i cant seem to get the model to update properly.
The object i am trying to update is generated from LINQtoSQL, and in database it has foreign key column. In LINQtoSQL class that resulted in "Contains" relationship. I can get to ID property that represents the column in DB, and also the object that it represents.
zupanija = new Zupanija(); //object that needs to be updated
zupanija.Drzava; //object that i want to change to make the update
zupanija.DrzavaID; //Property linked to object that should change
Only way i have figured out to do the update is to get the value from DDLF and use it to get the object that i want to change like this:
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var zupanija = repo.ZupanijaById(id);
var drzava = new repoDrzava().DrzavaById(Convert.ToInt32(collection["Zupanija.DrzavaID"]));
zupanija.Drzava = drzava;
}
Also when i try to update the ID field like this, then i get the folowing error:
zupanija.DrzavaID = Convert.ToInt32(collection["Zupanija.DrzavaID"]);
Error: throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
This seems to me that it is very lousy way to do this, and i am trying to get UpdateModel to work.
I have found the solution while looking for something else, in blog by Joe Stevens:
Using Controller UpdateModel when using ViewModel
The catch is in following: When view model is used then to correctly bind the properties it is necessary to "instruct" the UpdateModel helper how to find the actual class we wish to update.
My solution required to modify
UpdateModel(zupanija); to UpdateModel(zupanija,"Zupanija");
Because i was using a ViewModel class that contained couple properties along with the main data class i wanted to update.
Here is the code, i hope it helps to understand:
public class ZupanijaFVM
{
public IEnumerable<SelectListItem> Drzave { get; private set; }
public Zupanija Zupanija { get; private set; }
...
}
// From Controller
//
// GET: /Admin/Zupanije/Edit/5
public ActionResult Edit(int id)
{
var zupanija = repo.ZupanijaById(id);
return zupanija == null ? View("Error") : View(new ZupanijaFVM(repo.ZupanijaById(id)));
}
//
// POST: /Admin/Zupanije/Edit/5
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var zupanija = repo.ZupanijaById(id);
if (TryUpdateModel(zupanija, "Zupanija"))
{
repo.Save();
return RedirectToAction("Details", new { id = zupanija.ZupanijaID });
}
return View(new ZupanijaFVM(zupanija));
}
//From View:
#model VozniRed.Areas.Admin.Models.ZupanijeFVM
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Zupanija</legend>
#Html.HiddenFor(model => model.Zupanija.ZupanijaID)
<div class="editor-label">
#Html.LabelFor(model => model.Zupanija.Naziv)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Zupanija.Naziv)
#Html.ValidationMessageFor(model => model.Zupanija.Naziv)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Zupanija.Drzava)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Zupanija.DrzavaID, Model.Drzave)
#Html.ValidationMessageFor(model => model.Zupanija.DrzavaID)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
A dropdown list is represented by a <select> tag in an HTML form. A <select> contains a list of <option> tags each containing an ID and a text. When the user selects an option and submits the form the corresponding ID of this options is POSTed to the server. And only the ID. So all you can expect to get in your Edit POST action is the ID of the selected option. And all that UpdateModel does is use the request parameters that are sent and convert them to a strongly typed object. But because all that is a POSTed is a simple ID that's all you can get. From there on you have to query the datastore using this ID if you want to obtain the corresponding model. So you cannot get something that is not existing.

Resources