I have a View that contains n number of input fields (the number will vary based on different criteria). the value of each input field needs to be inserted in the database in their own row.
My problem is that only the first input field is inserted into the database. The controller looks like this:
public ActionResult Create([Bind(Include = "Id,MemberId,Rated,Rating")] Rating rating)
{
if (ModelState.IsValid)
{
db.Ratings.Add(rating);
db.SaveChanges();
}
The value of MemberId is the same for each row, but Rated and Rating will be different.
My model looks like this:
[Table("Rating")]
public partial class Rating
{
public int Id { get; set; }
public int? MemberId { get; set; }
public int Rated { get; set; }
[Column("Rating")]
public int Rating { get; set; }
public virtual TeamMember TeamMember { get; set; }
}
The view looks like this:
#model Teamer.Models.Rating
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Rating</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#{
int count = 0;
foreach (var item in ViewBag.MemberId)
{
string rater = Request.Cookies["rater"]["name"].ToString();
string raterId = Request.Cookies["rater"]["raterId"];
if (item.Name.ToLower() != rater.ToLower())
{
if (ViewBag.raterId != null)
{
foreach (var raterid in ViewBag.raterId)
{
<input type="hidden" name="MemberId" value="#raterid" />
}
}
<div class="col-md-10">
<label class="control-label col-md-2" for="#item.Name">#item.Name</label>
<input type="number" name="Rating-#count" value="0" />
<input type="hidden" name="Rated" value="#item.Id" />
</div>
count++;
}
}
}
</div>
<input type="hidden" name="count" value="#count" />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
I'm guessing, I need to loop through the values one by one, but I can't get that to work, so maybe I'm way off on that.
EDIT
OK, so I got it working now with at simple, although maybe a bit ugly, solution.
My controller now looks like this:
public ActionResult Create(Rating rating)
{
int count = int.Parse(Request.Form["count"]);
for (int i = 0; i < count; i++)
{
string test = Request.Form["MemberId"];
rating.MemberId = int.Parse(test);
rating.Rated = int.Parse(Request.Form["Rated-" + i]);
rating.Rating1 = int.Parse(Request.Form["Rating1-" + i]);
db.Ratings.Add(rating);
if (ModelState.IsValid)
{
db.SaveChanges();
}
}
return RedirectToAction("Index");
}
And my View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Rating</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#{
int count = 0;
string raterId = Request.Cookies["rater"]["raterId"];
foreach (var item in ViewBag.MemberId)
{
string rater = Request.Cookies["rater"]["name"].ToString();
if (item.Name.ToLower() != rater.ToLower())
{
<div class="col-md-10">
<label class="control-label col-md-2" for="#item.Name">#item.Name</label>
<input type="number" name="Rating1-#count" value="0" />
<input type="hidden" name="Rated-#count" value="#item.Id" />
</div>
count++;
}
}
}
</div>
<input type="hidden" name="MemberId" value="#raterId" />
<input type="hidden" name="count" value="#count" />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
It's simple enough, but I get the feeling there's a better, cleaner way. Any suggestions?
I can see a couple of problems, but it the end, you're not posting what is expected by your controller. Your controller is expecting to get a Rating (so Id, MemberId, Rated, and Rating), but you're actually posting something like
MemberId=raterId (repeated by as many ViewBag.raterId you have)
Rating-0=0
Rated=memberX_Id
Rating-1=0
Rated=memberY_Id
Rating-2=0
Rated=memberZ_Id
(...)
Rating-n=0
Rated=memberM_Id
count=(n+1)
If you check your posted data, you should have only MemberId and Rated filled.
In order to achieve what you want, you'll need to have a list of Rating or a different structure on your controller side. Bear in mind, if you want to post an array, it should be something like
MemberId[0]=
Rated[0]=
Rating[0]=
MemberId[1]=
Rated[1]=
Rating[1]=
(...)
MemberId[n]=
Rated[n]=
Rating[n]=
Also, note that MemberId and Rated get overridden in your loops.
The Client is sending an array to controller, binding modification is required. The controller should accept an array or collection of Rating:
public ActionResult Create(Icollection<Rating> ratings)
{
if (ModelState.IsValid)
{
//saving...
}
}
Update:
As one of the good practices, It is better to work with DTO instead of your Database Entity, you might want to create a RatingDto Class:
public partial class RatingDto
{
public int MemberId { get; set; }
public int Rate { get; set; }
}
And not to forget changing View:
<div class="col-md-10">
<input type="hidden" name="MemberId" value="#raterId" />
<input type="number" name="Rate" value="0" />
</div>
Binding in Asp.net MVC works like so, associate html name attribute to property name in C# code.
It`s rather complicated to know what another programmer have expected from his code to do but the Key points are:
Instead of ViewBags and Cookies use Model
Pay attention to how Binding works
Replace Entity with Dto
Use debugger (Google Chrome,Firefox, etc) to check what do you send
to browser
Hope it helps.
Related
I need help to find out the next error. I'm trying to post model with List parameters. But, when I receive the list this has a null value.
Model class:
public class DiagModel{
public List<Component> components { get; set; }
public List<Question> questions { get; set; }
public List<Answer> answers { get; set; }
public List<Questionnaire> forms { get; set; } //it populates after instatiate object from the questions
//forms->(The propierties are idQuestion and idAnswer)
}
The view is shown below (#Html.hiddenFor() for each property from objects in fors were omitted):
#using Test.Models.compounds;
#model DiagModel;
#{
Layout = "~/Views/Shared/_LayoutCommon.cshtml";
}
#if (!string.IsNullOrEmpty(ViewBag.Message))
{
<script type="text/javascript">
alert("#ViewBag.Message");
</script>
}
#using (Html.BeginForm(new { #id = "requestForm" }))
{
#for (int i = 0; i < Model.components.Count(); i++)
{
//The hidden components with razor helper was deleted to make short the code [Component]
<div class="row text-center">
<div class="col-md-10 offset-md-1 text-start" style="background-color: #dddddd">
<span class="text-start">#Model.components[i].name</span>
</div>
</div>
<div class="row"> </div>
List<Question> _questions = Model.questions.Where(p => p.Idcomponent == Model.components[i].Idcomponent).ToList();
for (int j = 0; j < _questions.Count; j++)
{
//The hidden components with razor helper was deleted to make short the code [Question]
<div class="row p-1">
<div class="col-md-10 offset-md-1 text-start">
<label class="form-label fw-bold">#_questions[j].Idquestion #_questions[j].Textopregunta</label>
#Html.DropDownListFor(model => model.forms.Where(c => c.Idquestion == #_questions[j].Idquestion).First().Idanswer, new SelectList(Model.answers.Where(r => r.Idquestion == #_questions.ElementAt(j).Idquestion), "Idquestion", "Text"), "Select an option", new { #class = "form-control" })
</div>
</div>
<div class="row"> </div>
}
}
<div class="row p-1 text-center">
<div class="col-md-12">
<button name="submit" type="submit" class="btn btn-danger" formaction="Question" value=#Model>Enviar</button>
</div><!--end col -->
</div>
}
<div class="row p-2"> </div>
The controller gets the value but the collection is received as null.
[HttpPost]
public ActionResult Question(DiagModel model){
//ViewBag.Message($"Q #1: {model.forms.First().IdQuestion} , R #1: {model.forms.First().IdAnswer}");
ViewBag.Message = $"count: {model.forms.Count}";//Breakpoint
if (ModelState.IsValid) {
return View(model);
}
return View("Index");
}
You can only send input elements with form,
or you can send them as parameters with javascript xhr request.
Most important thing about razor is input element [name] properties need to match the model field.
<input type="text" name="questions[1].Id" class="form-label fw-bold" value="#Model.questions[1].Id" />
If you working on nested objects, it has to be reflected on Model that you try to bind on the server side as well.
Product Model Class
public class Product
{
public Guid ProductId { get; set; }
public string Name { get; set; }
}
Home Controller:
public class HomeController : Controller
{
[HttpGet]
public IActionResult EditProduct()
{
Product product = new Product()
{
ProductId = Guid.Empty,
Name = "Abc"
};
return View(product);
}
[HttpPost]
public IActionResult EditProduct(Product product)
{
Product productCopy = new Product()
{
ProductId = Guid.NewGuid(),
Name = product.Name + "d"
};
return View("EditProductCopy", productCopy);
}
}
EditProduct View
Note: Auto Generated from Product Model Class,
EditProductCopy is similar, only title is different
#model WebApplicationTest.Models.Product
#{
ViewData["Title"] = "EditProductCopy";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>EditProductCopy</h1>
<h4>Product</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="EditProduct">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ProductId" class="control-label"></label>
<input asp-for="ProductId" class="form-control" />
<span asp-validation-for="ProductId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
I call "EditProduct" view. I don't change anything and I click the "Save" button. "EditProductCopy" view is rendered and I expect to see that new ProductId and "Abcd" as Product name. But I see last posted data (ProductId is empty guid and Name is "abc") What is the reason of this problem?
Project Files can be downloaded from this link:
Project Files
Default TagHelper display ModelState value not Model.Just add ModelState.Clear() before you return View:
[HttpPost]
public IActionResult EditProduct(Product product)
{
Product productCopy = new Product()
{
ProductId = Guid.NewGuid(),
Name = product.Name + "d"
};
ModelState.Clear();//add this line...
return View("EditProductCopy", productCopy);
}
Result:
The request is submitted with GET method because method attribute of the form is not specified. So, write method="POST" in the form.
How can I save into my db this the selected option, Right now It's saving all the data but the ProfileText that is what I need...
I think I need to add an asp-for but I dont know where to be honest, or if it's a different way please tell me.
Here is my view:
#model HCCBPOHR.Data.Candidate
#*#model HCCBPOHR.DomainModel.CandidateModel*#
#*#model HCCBPOHR.Services.CandidateService.PostBoth*#
#{
ViewData["Title"] = "CandidateCreate";
}
<h2>CandidateCreate</h2>
<h4>Candidate</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post" enctype="multipart/form-data" asp-action="CandidateCreate">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Number" class="control-label"></label>
<input asp-for="Number" class="form-control" maxlength="9" />
<span asp-validation-for="Number" class="text-danger"></span>
</div>
<div class="form-group">
#Html.DropDownList("ProfileText", "Select Profile")
</div>
<div class="form-group">
<label asp-for="CV" type="file" class="control-label"></label>
<input asp-for="CV" type="file" class="form-control" />
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" onclick="this.disabled=true;this.form.submit();" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
Here is my Model:
public class Candidate : BaseEntity
{
public int Id { get; set; }
public string Name { get; set; }
public int Number { get; set; }
public string ProfileText { get; set; }
public Byte[] CV { get; set; }
public string CVNAME { get; set; }
public List<Profile> ProfileList { get; set; }
}
This is how I'm sending the List to the View:
public IActionResult CandidateCreate(int postId)
{
using (var applicationcontext = new ApplicationContext())
{
IEnumerable<SelectListItem> items = applicationcontext.Profile.Select(c => new SelectListItem{Value = c.ProfileText,Text = c.ProfileText});
ViewBag.ProfileText = items.ToList();
return View();
}
}
The error that I'm having right now is
NullReferenceException: Object reference not set to an instance of an object.
In your view change the code to:
<div class="form-group">
<select asp-for="ProfileText" asp-items="#Model.ProfileList"></select>
</div>
Then in your model you'll have a property which we can call ProfileText which will then get post to the server when the form is submitted.
Change your model by introducing a new prop as follows:
public SelectList ProfileList { get; set; }
Now in your action your will need to do:
var model = new Candidate();
...
model.ProfileList = new SelectList(YourProfileListFromDbOrSomeWhereElse);
return View(model);
Please note you can also use SelectList(IEnumerable, string dataValueField, string dataTextField)Constructor if you want to set the dataValueField and dataTextField. I do not know how you get your ProfileList and what it contains so hence why I've only made use of the SelectList(IEnumerable items); Constructor.
Further reading here
As I can see, you are not populating the dropdownlist. I think it's better practice to have the values that can be selected(in a SelectList or string list) and a variable that will hold the selected value in your model and use DropDownListFor. the syntax would be:
#Html.DropDownListFor(model => model.ProfileText, new SelectList(Model.ProfileList, "name"), new {(here html attributes)#class = "form-control"})
After doing that you will get the selected value when posting the model
When attempting to bind a model to a view, I'm getting a 404 error. The ActionResult is called 'SortDesc' but the view is just a standard 'Index' view. I understand that this isn't loading because the there is now view called 'SortDesc'. However I have two buttons one to sort data ascending and one to sort data decending hence the two seperate functions. I'm just not sure what the best solution would be here, either to continue with the two seperate functions and somehow pass in the correct view to load or to create a new, single HttpPost function on Index that will know which button has been clicked and sort accordingly. Here's the code I have so far:
Models:
public class NumberSetList
{
public int NumberSetListId { get; set; }
public List<NumberList> Numbers { get; set; }
public string SortOrder { get; set; }
}
public class NumberList
{
public int NumberListId { get; set; }
public int Number1 { get; set; }
public int Number2 { get; set; }
public int Number3 { get; set; }
public int Number4 { get; set; }
public int Number5 { get; set; }
public string SortOrder { get; set; }
}
Razor:
#{
ViewBag.Title = "csi media web test";
}
<div class="jumbotron">
<h1>csi media web test</h1>
<p class="lead">Liane Stevenson</p>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-info">
<div class="panel-heading"><i class="glyphicon glyphicon-arrow-right"></i> Enter Your Four Numbers</div>
<div class="panel-body">
<form class="form-inline">
<div class="col-md-9">
<div class="form-group">
<label class="sr-only" for="number1">1st Number</label>
<input type="number" class="form-control" id="number1" name="Number1" placeholder="#1">
</div>
<div class="form-group">
<label class="sr-only" for="number2">2nd Number</label>
<input type="number" class="form-control" id="number2" name="Number2" placeholder="#2">
</div>
<div class="form-group">
<label class="sr-only" for="number3">3rd Number</label>
<input type="number" class="form-control" id="number3" name="Number3" placeholder="#3">
</div>
<div class="form-group">
<label class="sr-only" for="number4">4th Number</label>
<input type="number" class="form-control" id="number4" name="Number4" placeholder="#4">
</div>
</div>
<div class="col-md-3 text-right">
<a class="btn btn-default" href="#Url.Action("SortDesc", "Home")"><i class="glyphicon glyphicon-arrow-down"></i> Sort Desc</a>
<a class="btn btn-default" href="#Url.Action("SortAsc", "Home")"><i class="glyphicon glyphicon-arrow-down"></i> Sort Asc</a>
</div>
</form>
<p>
#if (Model != null)
{
foreach (int number in Model.Numbers)
{
<span class="label label-info">#number</span>
}
}
</p>
</div>
</div>
</div>
</div>
Home Controller:
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult SortDesc([Bind(Include = "Number1, Number2, Number3, Number4")] NumberSetList model)
{
if (!ModelState.IsValid)
{
return View();
}
else
{
NumberSetList list = new NumberSetList();
List<int> numbers = new List<int>();
numbers.Add(model.Number1);
numbers.Add(model.Number2);
numbers.Add(model.Number3);
numbers.Add(model.Number4);
numbers.OrderByDescending(i => i);
list.SortOrder = "Desc";
return View(list);
}
}
Try this
public class NumberSetList {
public int NumberSetListId { get; set; }
public List<NumberSetItem> Numbers { get; set; }
public string SortOrder { get; set; }
}
public class NumberSetItem {
public int Value { get; set; }
}
, use for loop to create inputs for the numbers
#using (Html.BeginForm()) {
<div class="col-md-9">
<div class="form-group">
#if (Model != null && Model.Numbers != null) {
#for (int i = 0; i < Model.Numbers.Count; i++) {
<div class="form-group">
#Html.LabelFor(m => m.Numbers[i].Value, "Number " + (i+1).ToString())
#Html.TextBoxFor(m => m.Numbers[i].Value, new { #class = "form-control" })
</div>
}
<div class="col-md-3 text-right">
<input id="SortOrder" value="Desc" type="button" class="btn btn-default"><i class="glyphicon glyphicon-arrow-down"></i> Sort Desc</input>
<input id="SortOrder" value="Asc" type="button" class="btn btn-default"><i class="glyphicon glyphicon-arrow-down"></i> Sort Asc</input>
</div>
}
</div>
</div>
}
And in the View
[HttpPost]
public ActionResult Index(NumberSetList model) {
if (!ModelState.IsValid) {
return View();
} else {
var numbers = model.SortOrder == "Desc" ?
model.Numbers.OrderByDescending(n => n.Value) :
model.Numbers.OrderBy(n => n.Value);
model.Numbers = numbers.ToList();
return View(model);
}
}
You can fix the issue using a variety of techniques.
Pass the name of the view into the View method like this:
return View("Index", list);
The View method has many overloads and you can see them all here. It is nice to get yourself familiar with the overloads for scenarios like the one you are facing.
If your view is not in the same folder as the action, you will need to pass the path for the view instead of just the name.
Another way is to have a single action and you can call this one Index as well but this one will take a model as an argument. Your model can have the numbers and an enum for sort: Desc, Asc. In your action method you can analyze the model, and do whatever is needed.
The approach with the model is the one I prefer.
EDIT
I just noticed you have this line of code in your view:
<a class="btn btn-default" href="#Url.Action("SortDesc", "Home")"><i class="glyphicon glyphicon-arrow-down"></i> Sort Desc</a>
That will trigger an HTTP GET and therefore it will not hit your SortDsc action method. Remove POST from your action method or use a post technique (Form) to hit your action method using POST.
EDIT 2
Honestly what you are doing is far simpler than you are making it. First thing is when you are using Url.Actio you are not passing nothing to your action method so how will it know about the numbers? I would normally call my action method using AJAX and get the result and display the result.
Without AJAX, you need to use one form for ascending and one for descending. Or you can use a radio button so user can select the order first.
Here is some code to do it using radio buttons.
Action:
[HttpPost]
public ActionResult SortDesc([Bind( Include = "Number1, Number2, Number3, Number4, SortOrder" )] NumberList model) {
if( !ModelState.IsValid ) {
return View("Index");
}
model.Numbers = new List<int>();
model.Numbers.Add( model.Number1 );
model.Numbers.Add( model.Number2 );
model.Numbers.Add( model.Number3 );
model.Numbers.Add( model.Number4 );
model.Numbers.Add( model.Number5 );
if (model.SortOrder == "Desc" ) {
model.Numbers = model.Numbers.OrderByDescending( i => i ).ToList();
}
else {
model.Numbers = model.Numbers.OrderBy( i => i ).ToList();
}
return View("Index", model);
}
Model:
public class NumberList {
public int Number1 { get; set; }
public int Number2 { get; set; }
public int Number3 { get; set; }
public int Number4 { get; set; }
public int Number5 { get; set; }
public int NumberListId { get; set; }
public List<int> Numbers { get; set; }
public string SortOrder { get; set; }
}
View:
#using( Html.BeginForm( "SortDesc", "Home", FormMethod.Post ) ) {
<div class="row">
<div class="col-md-12">
<div class="panel panel-info">
<div class="panel-heading"><i class="glyphicon glyphicon-arrow-right"></i> Enter Your Four Numbers</div>
<div class="panel-body">
<form class="form-inline">
<div class="col-md-9">
<div class="form-group">
<label class="sr-only" for="number1">1st Number</label>
<input type="number" class="form-control" id="number1" name="Number1" placeholder="#1">
</div>
<div class="form-group">
<label class="sr-only" for="number2">2nd Number</label>
<input type="number" class="form-control" id="number2" name="Number2" placeholder="#2">
</div>
<div class="form-group">
<label class="sr-only" for="number3">3rd Number</label>
<input type="number" class="form-control" id="number3" name="Number3" placeholder="#3">
</div>
<div class="form-group">
<label class="sr-only" for="number4">4th Number</label>
<input type="number" class="form-control" id="number4" name="Number4" placeholder="#4">
</div>
<div class="form-group">
<input type="radio" class="form-control" id="number4" name="SortOrder" value="Desc">
</div>
<div class="form-group">
<input type="radio" class="form-control" id="number4" name="SortOrder" value="Asc">
</div>
</div>
<div class="col-md-3 text-right">
<button class="btn btn-default"><i class="glyphicon glyphicon-arrow-down"></i> Sort </button>
#*<a class="btn btn-default"><i class="glyphicon glyphicon-arrow-down"></i> Sort Asc</a>*#
</div>
</form>
<p>
#if( Model != null ) {
foreach( int number in Model.Numbers ) {
<span class="label label-info">#number</span>
}
}
</p>
</div>
</div>
</div>
</div>
}
Hi there.
For more than a day now I have been unable to update my entity models in my MVC project with values from the post. I have read like 30 related issues here on SO and still I have no idea what is even wrong. I made a small project without Ajax and other disturbances, and now I can watch it fail reliably. I was hoping to run this by you, it is very simple, so perhaps someone more experienced can easily identify my misstake. This is what I came up with:
Models and data:
public class StoryDB : DbContext
{
public DbSet<Story> Stories { get; set; }
}
public class Story
{
[Key]
public int StoryID { get; set; }
public string zestory { get; set; }
}
public class StoryViewModel
{
public Story stry;
}
Controller:
//
// GET: /Story/Create
[HttpGet]
public ActionResult Create()
{
StoryViewModel svm = new StoryViewModel();
svm.stry = new Story();
return View(svm);
}
//
// POST: /Story/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(StoryViewModel svm)
{
if (ModelState.IsValid)
{
db.Stories.Add(svm.stry);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(svm);
}
View:
#model MvcApplication7.Models.StoryViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Story</legend>
#Html.HiddenFor(model => model.stry.StoryID)
<div class="editor-label">
#Html.LabelFor(model => model.stry.zestory)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.stry.zestory)
#Html.ValidationMessageFor(model => model.stry.zestory)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
This is the HTML it produces:
<form action="/Story/Create" method="post"><input name="__RequestVerificationToken" type="hidden" value="v0wlNDXbhykfe6IKOep6WMSZVteTDNPdgUVkQ8VcW4RW2oo-ufJSdVkN70Y0OHI4if56HrZiGLaGVy9UzlsoTkKXm963ZwRfJsuBZSVs9uQ1" /> <fieldset>
<legend>Story</legend>
<input data-val="true" data-val-number="The field StoryID must be a number." data-val-required="The StoryID field is required." id="stry_StoryID" name="stry.StoryID" type="hidden" value="0" />
<div class="editor-label">
<label for="stry_zestory">zestory</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="stry_zestory" name="stry.zestory" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="stry.zestory" data-valmsg-replace="true"></span>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
</form>
And what happens is that there is no databinding I can notice, and it crashes on trying to save with an error due to the incomming viewmodel's Story stry being null.
I have also tried to create new viewmodel and belonging story and filling them with TryUpdateModel() with the result that empty entries were made into the database.
Possibly relevant:
Try changing the field to a property:
public class StoryViewModel
{
public Story stry { get; set; }
}