I need to post the selected item's id from dropdown to post method of same controller and the render the content in same view
PLease help me fast :(
My View
#Html.DropDownListFor(x => x.hotelmodel.SelectedHotelId, Model.hotelmodel.DrpHotelList)
<div>
<p>#Model.percentageoccupied</p>
<p>#Model.Revenue</p>
<p>#Model.UnSold</p>
<div>
MY HttpGetMethod
[HttpGet]
public ActionResult Counter()
{
var personid = ((PersonModel)Session["PersonSession"]).PersonId;
var model = new CounterforModel();
model.hotelmodel.DrpHotelList = iCommonservice.GetHotelListByPersonId(personid);
return View(model);
}
My HttpPostMethod
[HttpPost]
public ActionResult Counter(int id)
{
var result = iCommonservice.LoadCounter(id);
model.percentageoccupied = Convert.ToInt32(result[0].percentageoccupied);
model.Revenue = Convert.ToDecimal(result[0].Revenue);
model.UnSold = Convert.ToInt32(result[0].UnSold);
return View(model);
}
In your POST method pass your View Model as parameter. Then you can use the posted hotelModel.SelectedHotelId for what you need, update the model values and pass your updated model to the View.
public ActionResult Counter(CounterforModel model)
{
var result = iCommonservice.LoadCounter(model.hotelmodel.SelectedHotelId);
model.percentageoccupied = Convert.ToInt32(result[0].percentageoccupied);
model.Revenue = Convert.ToDecimal(result[0].Revenue);
model.UnSold = Convert.ToInt32(result[0].UnSold);
return View(model);
}
If you want, you can use #Ajax.BeginForm() or jQuery .ajax() to make an ajax call to your action. You can look here.
Related
I need to use Post-Redirect-Get to show data, which I entered in "Information" page on "Index" page. I have the following methods, but it doesn't work. It doesn't even redirect me on submit. What am I doing wrong?
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Information()
{
return View();
}
//Get info
[HttpGet]
public ActionResult Submit(Models.Information FirstName,
Models.Information LastName,
Models.Information DateOfBirth,
Models.Information HourOfBirth,
Models.Information NumberOfKids,
Models.Information Emso,
Models.Information Email,
Models.Information PlaceOfBirth)
{
if (ModelState.IsValid)
{
Models.Information info = new Models.Information();
info.FirstName = FirstName.ToString();
info.LastName = LastName.ToString();
info.DateOfBirth = Convert.ToDateTime(DateOfBirth);
info.HourOfBirth = Convert.ToDateTime(HourOfBirth);
info.NumberOfKids = Convert.ToInt32(NumberOfKids);
info.Emso = Emso.ToString();
info.Email = Email.ToString();
info.PlaceOfBirth = PlaceOfBirth.ToString();
TempData["info"] = info;
return RedirectToAction("Summary");
}
return View();
}
//Show info
[HttpPost]
public ActionResult Post(Models.Information info)
{
info.FirstName = ViewData["FirstName"].ToString();
info.LastName = ViewData["LastName"].ToString();
info.DateOfBirth = Convert.ToDateTime(ViewData["DateOfBirth"]);
info.HourOfBirth = Convert.ToDateTime(ViewData["HourOfBirth"]);
info.NumberOfKids = Convert.ToInt32(ViewData["NumberOfKids"]);
info.Emso = ViewData["Emso"].ToString();
info.Email = ViewData["Email"].ToString();
info.PlaceOfBirth = ViewData["PlaceOfBirth"].ToString();
return View();
}
}
I try to show data on Index page like this:
First name: <input type='text' runat="server" value="#ViewData["FirstName"]" /><br />
Your code looks sort of confusing to me and I am not sure what you are trying to accomplish. But first, let's use an example on what I think you are trying to accomplish.
User enters information on the information action/view
(POST)This is POSTed to a controller/action which then verifies the model and puts in into the ViewData (REDIRECT TO STEP 3)
(GET)You want to redisplay this data on a summary page.
Under those assumptions, lets clean up your code a bit, leverage the use of the ViewData and TempData objects and see if we can make this work.
Information Action
public ActionResult Information()
{
//In a strongly typed view, typically you would send an empty model
//so the model binder/Html.Input helpers have something to bind to
return View(new Models.Information());
}
Information POST to handle incoming data
[HttpPost]
public ActionResult Information(Models.Information info)
{
//Yup - you can use the same action name as the GET action above
//You can name this anything you want, but I typically keep the same names so
//I know where the data came from
//I think your assignments are backwards. info came into the controller action
//You want to save this as ViewData. Also, let's do that in one line of code
//And since we are redirecting, lets use the TempData dictionary
//Notice the method type decorator above [HttpPost]. This is the P in PRG (Post)
if(modelState.IsValid()){
TempData["info"] = info;
//Notice the name of the ActionMethod below. The is the R in PRG (Redirect)
return RedirectToAction("Summary");
}
//There were errors, lets send back to the Information view
return View(info);
}
Summary Action
public ActionResult Summary()
{
//We were redirected here, and this is a GET method. This is the G in PRG
//(GET)
//lets go ahead and set the TempData stuff to a model, it just looks nicer on
//the view
var model = TempData["info"];
return View(model);
}
As for the views, here is a snippet of what each might look olike
Information View
#model Models.Information
#{using(Html.BeginForm()){
#Html.LabelFor(x=>x.FirstName)<br/>
#Html.TextBoxFor(x=>x.Firstname)
//Repeat for each property
<input type="Submit" value="Submit"/>
}}
Summary View
#model Models.Information
#Html.LabelFor(x=>x.FirstName)<br/>
#Html.DisplayFor(x=>x.Firstname)
//Repeat for each property
I had a look at this:
ASP.NET MVC - How to pass an Array to the view?
and am struggeling with deploying my DateTime[] as a dropdownlist in the view, herewith my line but it is not correct:
<p style="color:Red"><%: Html.DropDownList("Choose a Sunday: ", (IEnumerable<SelectListItem>)ViewData["Sundays"], "--Select--")%>
</p>
In the controller i have:
[HttpGet]
public ActionResult MyAction()
{
DateTime[] allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now);
ViewData["Sundays"] = allSundaysInMonth;
return View();
}
can someone help please?
thanks
Perhaps what you want to do is this:
[HttpGet]
public ActionResult MyAction()
{
IEnumerable<SelectListItem> allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now).Select(day => new SelectListItem() { Text = day.ToString(), Value = day.ToString() });
ViewData["Sundays"] = allSundaysInMonth;
return View();
}
That is depending on your display format. What I'm trying to point out is that DateTime and SelectListItem may not have an implicit cast, so you get a type mismatch at runtime.
If you ever think (realize) dynamic magic variables like ViewData/ ViewBag is an evil and thinking about using strongly typed ViewModel for your view, you can do like this
create a ViewModel specific for your View (UI).
public class EventViewModel
{
public IEnumerable<SelectListItem> AllSundays { set;get;}
public string SelectedSunday { set;get;}
}
In your action method, set the value and send it to the view
public ActionResult MyAction()
{
var vm=new EventViewModel();
vm.AllSundays = GetDatesOfSundays(System.DateTime.Now).
Select(d => new SelectListItem() {
Text = d.ToString(), Value = d.ToString() }).ToList();
return View(vm);
}
Change your view like this
#model EventViewModel
#Html.DropDownListFor(x => x.SelectedSunday, Model.AllSundays, "--Select One--")
ViewBag/ViewData is bad. It makes your code ugly. Stick to strongly typed.
You cast the list to IEnumerable<SelectListItem>, but its a list of DateTimes. Casting the list to IEnumerable<DateTime> should fix it.
Or you might want to put list of SelectListItem on the ViewData instead!
I have a base Controller like follow
public abstract class BaseController
{
protected ActionResult LogOn(LogOnViewModel viewModel)
{
SaveTestCookie();
var returnUrl = "";
if (HttpContext != null && HttpContext.Request != null && HttpContext.Request.UrlReferrer != null)
{
returnUrl = HttpContext.Request.UrlReferrer.LocalPath;
}
TempData["LogOnViewModel"] = viewModel;
return RedirectToAction("ProceedLogOn", new { returnUrl });
}
public ActionResult ProceedLogOn(string returnUrl)
{
if (CookiesEnabled() == false)
{
return RedirectToAction("logon", "Account", new { area = "", returnUrl, actionType, cookiesEnabled = false });
}
var viewModel = TempData["LogOnViewModel"] as LogOnViewModel;
if (viewModel == null)
{
throw new NullReferenceException("LogOnViewModel is not found in tempdata");
}
//Do something
//the problem is I missed the values which are set in the ViewBag
}
}
and another Controller
public class MyController : BaseController
{
[HttpPost]
public ActionResult LogOn(LogOnViewModel viewModel)
{
// base.LogOn is used in differnet controller so I saved some details in view bag
ViewBag.Action = "LogonFromToolbar";
ViewBag.ExtraData = "extra data related only for this action";
return base.LogOn(viewModel);
}
}
the problem is I missed the view bag values in ProceedLogOn action method.
I have the values in Logon method in BaseController.
How can I copy the values of ViewBag from one Action to another Action?
So I can not simply say this.ViewBag=ViewBag;
because ViewBag doesn't have setter. I was thinking of Iterating through viewbag.
I tried ViewBag.GetType().GetFields() and ViewBag.GetType().GetProperties() but they return nothing.
ViewData reflects ViewBag
You can iterate the values you've stored like this :
ViewBag.Message = "Welcome to ASP.NET MVC!";
ViewBag.Answer = 42;
foreach (KeyValuePair<string, object> item in ViewData)
{
// if (item.Key = "Answer") ...
}
This link should also be useful
I'm afraid I don't have the answer how to copy ViewBag.
However, I would never use ViewBag that way.
ViewBag is some data the Controller gives to the View to render output if someone does not like to use ViewModel for some reasons. The View should never know anything about the Controller but your ViewBag is holding a ActionName ;).
Anyway, the ProceedLogOn action method has pretty much parameters which is ... not a nice code actually so why hesitate to add more parameters which are currently being hold in MyController.Logon ViewBag? Then inside method ProceedLogOn you have what you want.
;)
Actually I'm very new to ASP.NET MVC and I need your help.
Here I have some Create Method that takes an argument from the URL to use it as id:
in 'vote' controller :
public ActionResult Create(int id)
{
Meeting meeting = db.Meetings.Find(id); // get the object
ViewBag.meetingID = meeting.meetingID; // get its id and assign it to a ViewBag
return View();
}
and I would like to do something like :
vote.meetingID = #ViewBag.meetingID
in the model so that is directly assgin this property without excplicitely typing it from the HTML view (I mean #Html.EditorFor(model=>meetingID) )
The question is not that clear, but try this.
You could pass the entire model to the view.
Controller:
public ActionResult Create(int id)
{
Meeting meeting = db.Meetings.Find(id); // get the object
ViewData["myMeeting"] = meeting;
return View();
}
To use in the view you can declare it as a variable at the top of the view:
Declare:
#
{
var meetingData = ViewData["myMeeting"] as Meeting;
}
Usage:
<div>
#meetingData.meetingID
</div>
If I have the usual Edit actions, one for GET to retrieve an object by it's ID and to display it in an edit form. The next for POST to take the values in the ViewModel and update the object in the database.
public virtual ActionResult Edit(int id)
[HttpPost]
public ActionResult Edit(VehicleVariantEditSaveViewModel viewModel)
If an error occurs during model binding in the POST action, I understand I can RedirectToAction back to the GET action and preserve the ModelState validation errors by copying it to TempData and retrieving it after the redirect in the GET action.
if (TempData["ViewData"] != null)
{
ViewData = (ViewDataDictionary)TempData["ViewData"];
}
How do I then convert that ViewData, which includes the previous invalid ModelState, into a new model to send to the view so the user sees their invalid input with validation warnings? Oddly enough if I pass in a new instance of my ViewModel retrieved from the database (with the original valid data) to the View() this is ignored and the (invalid) data in the ViewData is displayed!
Thanks
I had a similar problem and decided to use the following pattern:
public ActionResult PersonalRecord(Guid id)
{
if (TempData["Model"] == null)
{
var personalRecord = _context.PersonalRecords.Single(p => p.UserId == id);
var model = personalRecord.ToPersonalRecordModel();
return View(model);
}
else
{
ViewData = (ViewDataDictionary) TempData["ViewData"];
return View(TempData["Model"]);
}
}
[HttpPost]
public ActionResult PersonalRecord(PersonalRecordModel model)
{
try
{
if (ModelState.IsValid)
{
var personalRecord = _context.PersonalRecords.Single(u => u.UserId == model.UserId);
personalRecord.Email = model.Email;
personalRecord.DOB = model.DOB;
personalRecord.PrimaryPhone = model.PrimaryPhone;
_context.Update(personalRecord);
_context.SaveChanges();
return RedirectToAction("PersonalRecord");
}
}
catch (DbEntityValidationException ex)
{
var errors = ex.EntityValidationErrors.First();
foreach (var propertyError in errors.ValidationErrors)
{
ModelState.AddModelError(propertyError.PropertyName, propertyError.ErrorMessage);
}
}
TempData["Model"] = model;
TempData["ViewData"] = ViewData;
return RedirectToAction("PersonalRecord", new { id = model.UserId });
}
Hope this helps.
I noticed that the Model is included in ViewData so you don't need to pass it in addition to the ViewData, what I don't understand is how you get at it to then return it to the view.
public ViewResult Edit(int id)
{
// Check if we have ViewData in the session from a previous attempt which failed validation
if (TempData["ViewData"] != null)
{
ViewData = (ViewDataDictionary)TempData["ViewData"];
}
VehicleVariantEditViewModel viewModel = new VehicleVariantControllerViewModelBuilder()
.BuildForEdit(id);
return View(viewModel);
}
The above works but obviously it's making an unnecessary call to the database to build a new Model (which gets automagically overwritten with the invalid values from the Model in the passed ViewData)
Confusing.