Ajax call breaks binding to object children - ajax

Without the ajax call, My main view binds to my parent class and the partial view on main view, binds to a child member of the parent class
parent...
public class Client
{
[ScaffoldColumn(false)]
public int Id { get; set; }
[DisplayName("Name")]
[Required]
[StringLength(120)]
public string Name { get; set; }
// etc...
public virtual Address Address { get; set; }
}
child of parent...
public class Address
{
[ScaffoldColumn(false)]
public int AddressId { get; set; }
[DisplayName("Address")]
[Required]
[StringLength(200)]
public string Street { get; set; }
// etc...
[ForeignKey("Client")]
public int? Id { get; set; }
public virtual Client Client { get; set; }
}
the main view
#using (Html.BeginForm("Create", "Client", FormMethod.Post, new Dictionary<string, object> { { "data-htci-target", "addressData" } }))
{
#Html.AntiForgeryToken()
<div class="row">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-sm-4 col-md-4 col-lg-4">
#Html.Kendo().AutoCompleteFor(model => model.Name).HtmlAttributes(new { style = "width:100%" })
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
#{ var vdd = new ViewDataDictionary(ViewData) { TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = "Address" } };}
#Html.Partial("_AddressPartial", Model.Address, #vdd)
// yada yada...you can imagine the rest of the very standard view
The partial view's model is Address and all hooks up.
When I post back to the server the Address member is properly filled with entered data from the partial view...
So now...in my partial view, I now load the js to call the async routine to load the IP GEO data for the user - so it pre-fills the city, province, country
Any example of an ajax call will suffice...mine calls an AddressControl, returns a partialview result and replaces a div named addressData with the updated partialview :
$(function() {
var urlGeoIeoip = "http://ip-api.com/json/?callback=?";
$.ajax({
url: urlGeoIeoip,
type: "GET",
dataType: "json",
timeout: 5000,
success: function (geoipdata) {
$.ajax({
url: "/getlocationdata/" + geoipdata.country + "/" + geoipdata.regionName + "/" + geoipdata.city,
type: "GET",
timeout: 5000,
success: function (data) {
//alert(data);
//var $form = $(this);
// var $target = $($form.attr("data-htci-target"));
var $newHtml = $(data);
//alert($target);
$("#addressData").replaceWith($newHtml);
$("#City").data("kendoComboBox").value(geoipdata.city);
$("#State").data("kendoComboBox").value(geoipdata.regionName);
$("#Country").data("kendoComboBox").value(geoipdata.country);
}
});
}
}).fail(function(xhr, status) {
if (status === "timeout") {
// log timeout here
}
});
});
All works great!
BUT
Now, when I post back to the user via the submit button, the Address child member of the parent class is null....
How do I get it to rebind the Address member of the parent class after return of the ajax call?

By generating your input fields in the partial view, the HTML helpers are unaware that your Address model is a property of your initial Client model, so it's generating HTML inputs like:
<input type="text" id="City" name="City" />
<input type="text" id="State" name="State" />
If your POST action method is accepting a Client model then the model binder will look for the properties City and State of the Client model, which don't exist.
You need your HTML input to look like:
<input type="text" id="Address_City" name="Address.City" />
<input type="text" id="Address_State" name="Address.State" />
Instead of using a partial for your Address fields, you should use an Editor Template which will then preserve the parent property as you need in this case.
#Html.EditorFor(x => x.Address)

Related

Ajax call returning old ASP.NET MVC partial view instead of updated view

I have an Ajax call triggered by a button, that calls a controller to update a partial view. The controller returns an updated partial view, but the partial view received in the success function of the Ajax call is the original view, not the updated view.
I created a sample ASP.NET MVC program to reproduce the problem. The program displays a list of customers in a table as follows.
Snapshot of UI
The text boxes are rendered in the partial view _Status. When the Toggle Status button is clicked, controller is called via Ajax to toggle the customer's status between true and false, and refresh the partial view of the corresponding text box. The problem is that the status never changes. Why is that?
UPDATE
I just added the following line of code in the Status action of the controller, and now, the Ajax success function correctly receives the updated partial view!
this.ModelState.Clear();
Can someone explain why?
Here is the Index.cshtml view that displays the initial view.
#model IEnumerable<ComboModel.Models.CustomerSummary>
<script type="text/javascript">
function updatePartialView(id) {
debugger;
$.ajax({
url: "/CustomerSummary/Status",
data: $('#' + id + ' :input').serialize(),
dataType: "HTML",
type: "POST",
success: function (partialView) {
// Here the received partial view is not the one created in
// the controller, but the original view. Why is that?
debugger;
$('#' + id).replaceWith(partialView);
},
error: function (err) {
debugger;
},
failure: function (err) {
debugger;
}
});
}
</script>
<h2>Customer Summary</h2>
<table>
<tr>
<th>Name</th>
<th>Active?</th>
<th>Toggle</th>
</tr>
#foreach (var summary in Model)
{
<tr>
<td>#summary.FirstName #summary.LastName</td>
#Html.Partial("_Status", summary.Input)
<td><button type="button" name="#("S" + summary.Input.Number)" onclick="updatePartialView(this.name)">Toggle Status</button></td>
</tr>
}
</table>
The _Status.cshtml partial view.
#model ComboModel.Models.CustomerSummary.CustomerSummaryInput
<td id="#("S" + Model.Number)">
#Html.TextBoxFor(model => model.Active)
<input type="hidden" value="#Model.Number" name="Number" />
</td>
The CustomerSummaryController.cs.
using System.Collections.Generic;
using System.Web.Mvc;
using ComboModel.Models;
namespace ComboModel.Controllers
{
public class CustomerSummaryController : Controller
{
private readonly CustomerSummaries _customerSummaries = new CustomerSummaries();
public ViewResult Index()
{
IEnumerable<CustomerSummary> summaries = _customerSummaries.GetAll();
return View(summaries);
}
public PartialViewResult Status(CustomerSummary.CustomerSummaryInput input)
{
this.ModelState.Clear(); // If I add this, things work. Why?
input.Active = input.Active == "true" ? "false" : "true";
return PartialView("_Status", input);
}
}
public class CustomerSummaries
{
public IEnumerable<CustomerSummary> GetAll()
{
return new[]
{
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "true", Number = 0},
FirstName = "John",
LastName = "Smith"
},
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "false", Number = 1},
FirstName = "Susan",
LastName = "Power"
},
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "true", Number = 2},
FirstName = "Jim",
LastName = "Doe"
},
};
}
}
}
And finally, the CustomerSummary.cs model.
namespace ComboModel.Models
{
public class CustomerSummary
{
public string FirstName { get; set; }
public string LastName { get; set; }
public CustomerSummaryInput Input { get; set; }
public class CustomerSummaryInput
{
public int Number { get; set; }
public string Active { get; set; }
}
}
}
Thanks!
This is a duplicate of Asp.net MVC ModelState.Clear.
In the current scenario, because there is no validation of the status field, it is ok to clear the ModelState. However, the MVC correct way would be to pass a status value (true or false) to a GET action in the controller, toggle the value, return the result string, and update the text box on the page.

Reload partial view via Ajax: controls in partial are renamed

I'm following this standard pattern for using Ajax to reload a partial view. However, when the partial view is reloaded, the controls in the view have different IDs. They lose the name of the parent model. This means that when the form is posted back, model binding won't work.
So in the example below, when the page is first loaded, the checkbox id is "PenguinEnclosure_IsEnoughPenguins" but after the partial is reloaded, the checkbox id is "IsEnoughPenguins" The ID must be "PenguinEnclosure_IsEnoughPenguins" for model binding to correctly bind this to the PenguinEnclosure property of the VM.
Model:
public class ZooViewModel
{
public string Name { get; set; }
public PenguinEnclosureVM PenguinEnclosure { get; set; }
}
public class PenguinEnclosureVM
{
public int PenguinCount { get; set; }
[Display(Name = "Is that enough penguins for you?")]
public bool IsEnoughPenguins { get; set; }
}
Controller:
public ActionResult Index()
{
var vm = new ZooViewModel
{
Name = "Chester Zoo",
PenguinEnclosure = new PenguinEnclosureVM { PenguinCount = 7 }
};
return View(vm);
}
public ActionResult UpdatePenguinEnclosure(int penguinFactor)
{
return PartialView("DisplayTemplates/PenguinEnclosureVM", new PenguinEnclosureVM { PenguinCount = penguinFactor * 10 });
}
View:
#model PartialProblem.Models.ZooViewModel
#Scripts.Render("~/bundles/jquery")
<p>
Welcome to #Model.Name !
</p>
<p>
<div id="penguin">
#Html.DisplayFor(m => m.PenguinEnclosure)
</div>
</p>
<button id="refresh">Refresh</button>
<script>
$(document).ready(function () {
$("#refresh").on("click", function () {
$.ajax({
url: "/Home/UpdatePenguinEnclosure",
type: "GET",
data: { penguinFactor: 42 }
})
.done(function (partialViewResult) {
$("#penguin").html(partialViewResult);
});
});
});
</script>
Partial View:
#model PartialProblem.Models.PenguinEnclosureVM
<p>
We have #Model.PenguinCount penguins
</p>
<p>
#Html.LabelFor(m => m.IsEnoughPenguins)
#Html.CheckBoxFor(m => m.IsEnoughPenguins)
</p>
An approach I have used is to set the "ViewData.TemplateInfo.HtmlFieldPrefix" property in the action that responds to your ajax call (UpdatePenguinEnclosure). This tells Razor to prefix your controls names and/or Ids.
You can choose whether to hard code the HtmlFieldPrefix, or pass it to the action in the ajax call. I tend to do the latter. For example, add a hidden input on the page with its value:
<input type="hidden" id="FieldPrefix" value="#ViewData.TemplateInfo.HtmlFieldPrefix" />
Access this in your ajax call:
$.ajax({
url: "/Home/UpdatePenguinEnclosure",
type: "GET",
data: { penguinFactor: 42, fieldPrefix: $("#FieldPrefix").val() }
})
Then in your action:
public ActionResult UpdatePenguinEnclosure(int penguinFactor, string fieldPrefix)
{
ViewData.TemplateInfo.HtmlFieldPrefix = fieldPrefix;
return PartialView("DisplayTemplates/PenguinEnclosureVM", new PenguinEnclosureVM { PenguinCount = penguinFactor * 10 });
}
Try this:
Controller:
public ActionResult UpdatePenguinEnclosure(int penguinFactor)
{
PenguinEnclosureVM pg = new PenguinEnclosureVM { PenguinCount = penguinFactor * 10 };
return PartialView("DisplayTemplates/UpdatePenguinEnclosure", new ZooViewModel { PenguinEnclosure = pg });
}
Your Partial:
#model PartialProblem.Models.ZooViewModel
<p>
We have #Model.PenguinEnclosure.PenguinCount penguins
</p>
<p>
#Html.LabelFor(m => m.PenguinEnclosure.IsEnoughPenguins)
#Html.CheckBoxFor(m => m.PenguinEnclosure.IsEnoughPenguins)
</p>
I Think this will do the trick

MVC Entity Framework modifying child entities

I'm quite new to using MVC3 and EF4 and I'm trying to implement the CRUD functions of a parent-child entity set, however I haven't found an example of some specific requirements that I need and therefore would like a bit of help.
The situation I have is that I have a Product entity that has child Category entities. I have all of the CRUD functionality working fine for the Product entity and the detail functionality working with the Category entity within the Product details view. However I need to implement the addition and removal of child Categories from a given Product.
Normally this wouldn't be much of an issue, but in this case when a user adds a Category to a Product I need to only allow the user to be able to select from a list of all available Categories from the database. The user will also be able to remove any of the existing child Categories from a Product.
I expect implementing a DropDownList with all of the unused 'Categories' would work well, however I don't know how to use one to allow the user to add and remove 'Categories' and then save the changes to the database via EF.
Has anyone got any suggestions/examples on how to accomplish this?
If any extra information is required, please ask.
Thanks very much.
I have done similar with Authors and Books with many-to-many relation. The basic idea is to create a JSON object from view which contains all authors inside it and submit to controller. I also used jQuery UI TagIt to allow user to add/remove authors associated with the book. When user clicks on 'Save Book' button, the script builds a JSON object which mimics the Book object.
Below is the code. Please make sure you have added "json2.js" and "tagit.js" in the project before you try this code.
View Models:
public class BookViewModel
{
public string Title { get; set; }
public int BookId { get; set; }
public int IsAvail { get; set; }
public string CallNumber { get; set; }
//Assiged authors
public List<AuthorViewModel> Authors { get; set; }
//available authors
public List<AuthorViewModel> AuthorOptions { get; set; }
}
public class AuthorViewModel
{
public int AuthorId { get; set; }
public string FirstName { get; set; }
}
Code for Book/Edit.chtml:
#using System.Web.Script.Serialization
#model eLibrary.Models.BookViewModel
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<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>
#*This is for JSON*#
<script src="../../Scripts/json2.js" type="text/javascript"></script>
<script src="../../Scripts/tagit.js" type="text/javascript"></script>
#*These are for styling Control*#
<link href="../../Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
//This function is used for sending data(JSON Data) to BookController
function BookSave() {
// Step 1: Read View Data and Create JSON Object
var author = { "AuthorId": "", "FirstName": "" };
// Creating book Json Object
var book = { "BookId": "", "Title": "", "IsAvail": "", "CallNumber":"", "authors": []};
// Set Boook Value
book.BookId = $("#BookId").val();
book.Title = $("#Title").val();
book.IsAvail = $("#IsAvail").val();
book.CallNumber = $("#CallNumber").val() ;
var tags = $('#authors').tagit('tags');
for (var i in tags) {
author.AuthorId = tags[i].value;
author.FirstName = tags[i].label;
book.authors.push(author );
author = { "AuthorId": "", "FirstName": "" };
}
// Step 1: Ends Here
// Set 2: Ajax Post
// Here i have used ajax post for saving/updating information
$.ajax({
url: '/Book/Edit',
data: JSON.stringify(book),
type: 'POST',
contentType: 'application/json;',
dataType: 'json',
success: function (result) {
if (result.Success == "1") {
window.location.href = "/Book/Edit";
}
else {
alert(result.ex);
}
}
});
}
</script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Book Details</legend>
#Html.HiddenFor(model => model.BookId)
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IsAvail)
</div>
#Html.EditorFor(model => model.IsAvail)
#Html.ValidationMessageFor(model => model.IsAvail)
#Html.EditorFor(model => model.CallNumber);
</fieldset>
#Html.Partial("AuthorsByBook", Model.Authors, new ViewDataDictionary { { "mode", "EDIT" } })
<input type="button" value="Book Save" onclick="BookSave()" />
}
Code for Book/AuthorsByBook.chtml
#model IEnumerable< eLibrary.Models.AuthorViewModel>
<link href="../../Content/tagit-awesome-blue.css" rel="stylesheet" type="text/css" />
<div class="box">
<ul id="authors" name="authors">
</ul>
</div>
<script type="text/javascript">
//Load authors in the javascript variable
$(function () {
var initialAuthorList=[];
#if(ViewData["mode"]=="EDIT")
{
foreach (var category in Model)
{
<text>
initialAuthorList.push({label: "#category.FirstName", value: #category.AuthorId });
</text>
}
}
$('#authors').tagit({tagSource: function (request, response) {
$.ajax({
url: "/Author/SearchAuthor", type: "POST", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
success: function (data) {
response($.map(data, function (item) {
return { label: item.FirstName, value: item.AuthorId }
}))
}
})
},
initialTags:initialAuthorList,minLength:3,allowNewTags:false,sortable:true,delay:400});
});
</script>
Code for BookController.cs
public ActionResult Edit(int id)
{
//To DO: use repository to fetch data
Book book = db.Books.Single(a => a.BookId == id);
Mapper.CreateMap<Book, BookViewModel>();
Mapper.CreateMap<Author, AuthorViewModel>();
BookViewModel bookVm = Mapper.Map<Book, BookViewModel>(book);
List<AuthorViewModel> Authors = Mapper.Map<List<Author>,List<AuthorViewModel>>( db.Authors.ToList());
bookVm.AuthorOptions = Authors;
return View(bookVm);
}
[HttpPost]
public ActionResult Edit(BookViewModel bookv)
{
//create maps
Mapper.CreateMap<AuthorViewModel, Author>();
Mapper.CreateMap<BookViewModel, Book>();
//convert view objects to model objects
Book book = Mapper.Map<BookViewModel, Book>(bookv);
List<Author> authors = Mapper.Map<List<AuthorViewModel>, List<Author>>(bookv.Authors.ToList());
//this has to be executed before db.Books.Attach
//clear authors
book.Authors.Clear();
db.Books.Attach(book);
//assign authors to book
foreach (Author a in authors) { db.Authors.Attach(a); }
book.Authors.Clear();
foreach (Author a in authors) { book.Authors.Add(a); }
db.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
Code for SearchAuthor method in AuthorController.cs
public JsonResult SearchAuthor(string searchText, int? maxResults)
{
IEnumerable<Author> query = db.Authors;
searchText = searchText.ToLower();
query = query.Where(c => c.FirstName.ToLower().Contains(searchText));
if ((maxResults ?? 0) == 0)
{
return Json(query.ToList());
}
else
{
return Json(query.Take((int)maxResults).ToList());
}
}

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>

pass input text from view to controller

i know there are a lot questions like this but i really cant get the explanations on the answers... here is my view...
<script type="text/javascript" language="javascript">
$(function () {
$(".datepicker").datepicker({ onSelect: function (dateText, inst) { },
altField: ".alternate"
});
});
</script>
#model IEnumerable<CormanReservation.Models.Reservation>
#{
ViewBag.Title = "Index";
}
<h5>
Select a date and see reservations...</h5>
<div>
<div class="datepicker">
</div>
<input name="dateInput" type="text" class="alternate" />
</div>
i want to get the value of the input text... there's already a value in my input text because the datepicker passes its value on it... what i cant do is to pass it to my controller... here is my controller:
private CormantReservationEntities db = new CormantReservationEntities();
public ActionResult Index(string dateInput )
{
DateTime date = Convert.ToDateTime(dateInput);
var reservations = db.Reservations.Where(r=>r.Date==date).Include(r => r.Employee).Include(r => r.Room).OrderByDescending(r => r.Date);
return View(reservations.ToList());
}
i am trying to list in my home page the reservations made during the date the user selected in my calender in my home page....
I don't see a Form tag in your View...or are you not showing the whole view? hard to tell.. but to post to your controller you should either send the value to the controller via an ajax call or post a model. In your case, your model is an IEnumerable<CormanReservation.Models.Reservation> and your input is a date selector and doesn't look like it is bound to your ViewModel. At what point are you posting the date back to the server? Do you have a form with submit button or do you have an ajax call that you aren't showing?
Here is an example of an Ajax request that could be called to pass in your date
$(function () {
$(".datepicker").onselect(function{
searchByDate();
})
});
});
function searchbyDate() {
var myDate = document.getElementById("myDatePicker");
$.ajax({
url: "/Home/Search/",
dataType: "json",
cache: false,
type: 'POST',
data: { dateInput: myDate.value },
success: function (result) {
if(result.Success) {
// do something with result.Data which is your list of returned records
}
}
});
}
Your datepicker control needs something to reference it by
<input id="myDatePicker" name="dateInput" type="text" class="alternate" />
Your action could then look something like this
private CormantReservationEntities db = new CormantReservationEntities();
public JsonResult Search(string dateInput) {
DateTime date = Convert.ToDateTime(dateInput);
var reservations = db.Reservations.Where(r=>r.Date==date).Include(r => r.Employee).Include(r => r.Room).OrderByDescending(r => r.Date);
return View(reservations.ToList());
return Json(new {Success = true, Data = reservations.ToList()}, JsonRequestBehaviour.AllowGet());
}
Update
If you want to make this a standard post where you post data and return a view then you need to make changes similar to this.
Create a ViewModel
public class ReservationSearchViewModel {
public List<Reservation> Reservations { get; set; }
public DateTime SelectedDate { get; set; }
}
Modify your controller actions to initially load the page and then be able to post data return the View back with data
public ActionResult Index() {
var model = new ReservationSearchViewModel();
model.reservations = new List<Reservation>();
return View(model);
}
[HttpPost]
public ActionResult Index(ReservationSearchViewModel model) {
if(ModelState.IsValid)
var reservations = db.Reservations.Where(r => r.Date = model.SelectedDate).Include(r => r.Employee).Include(r => r.Room).OrderByDescending(r => r.Date);
}
return View(model)
}
Modify your view so that you have a form to post to the Index HttpPost action
#model CormanReservation.Models.ReservationSearchViewModel
<h5>Select a date and see reservations...</h5>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
#Html.EditorFor(model => model.SelectedDate)
#Html.EditorFor(model => model.Reservations) // this may need to change to a table or grid to accomodate your data
<input type="submit" value="Search" />
}

Resources