MVC - Html.BeginForm. My action method does not recieve argument - asp.net-mvc

I am trying to save data to my model.
Here is my Action method for doing that:
...
[HttpPost]
public ActionResult UpdateSectionInformation(SectionInformation sectionInformation) {
ViewBag.SectionUpdatedSuccesfully = true;
SectionInformation s = sectionInformation;
// Save settings to database.
using (var session = MvkStorage.GetSession()) {
var client = new MvkSectionStorageHandler(session);
try {
client.SaveOrUpdateSection(s.Section);
client.SaveOrUpdateSectionReschedulingRelations(s.RescheduleFromRelations);
client.SaveOrUpdateSectionReschedulingRelations(s.RescheduleToRelations);
} catch (Exception) {
ViewBag.SectionUpdatedSuccesfully = false;
}
}
return View("Index", s);
}
Here is the Html.BefinForm "declaration" (the controller name is SectionController):
#using(Html.BeginForm("UpdateSectionInformation", "Section", FormMethod.Post)) {
It seems like the problem is that the UpdateSectionInformation get an empty model. How should I solve that? I am new to MVC and I really donĀ“t get where UpdateSectionInformation is called.
I have seen something about Html.HiddenFor, should I use that here?:
#for (int i = 0; i < Model.RescheduleFromRelations.Count(); i++ ) {
var relation = Model.RescheduleFromRelations.ElementAt(i);
var relationId = relation.FromSection.ToString() + relation.ToSection.ToString();
...
Edit: Problem solved thanks to comment

Related

The controller for path " " was not found or does not implement IController. error

I pull the tags in the news details section. The corresponding code block is below.
NewsDetail:
foreach (var item in etiketler.Take(1))
{
<span>#item</span>
}
foreach (var item in etiketler.Skip(1))
{
<span>#item</span>
}
Controller :
public ActionResult Tag(string tag, int? pageSize)
{
string id = this.RouteData.Values["tag"].ToString();
SectionServices _sectionServices = new SectionServices();
if (!pageSize.HasValue) pageSize = 1;
ViewBag.Current = pageSize;
Models.TagModel model = new Models.TagModel();
var dat = _sectionServices.getNewsByTag((int)pageSize, tag);
ViewData["etiket"] = tag;
if (dat != null)
{
ViewBag.Tag = tag;
model.getNews = dat;
return View(model);
}
return View();
}
Route Config :
routes.MapRoute(
name: "TagPage",
url: "{tag}-haberleri/{pageSize}",
defaults: new { controller = "Page", action = "Tag", pageSize = UrlParameter.Optional }
);
I get errors like "The controller for path '/Mert Hakan_haberleri / 2' was not found or does not implement IController" in log records. what is the cause of this error, clicking on tags works correctly, but I see this error in log records.
I also had this error. When I embedded the classes into a namespace, everything started working for me.
namespace PageControllers { // added this line!
public class PageController {
public ActionResult Tag() {
//code logic
return View();
}
}
}

How to hide status query string from Url after updating from MVC Controller

I have a view which shows info according to a specific Id.
My Controller is:
public ActionResult ModifyWorkout(string WorkoutId, bool? Status)
{
Guid pkWorkoutId = new Guid(WorkoutId);
BLLWorkouts _objBLLWorkouts = new BLLWorkouts();
var WorkoutRow = _objBLLWorkouts.GetOneWorkout(pkWorkoutId);
WorkoutModel PageModel = new WorkoutModel
{
pkWorkoutId = WorkoutRow.pkWorkoutId,
WorkoutName = WorkoutRow.WorkoutName,
WorkoutNote = WorkoutRow.WorkoutNote,
Sessions = WorkoutRow.Sessions,
CmpFlag = WorkoutRow.CmpFlag,
tblWorkoutSessions = WorkoutRow.tblWorkoutSessions
};
ViewBag.UpdateStatus = Status;
return View(PageModel);
}
I always pass a Query String as Workout id for getting a single record. But when I update that records it is posting to another action:
public ActionResult UpdateWorkout(WorkoutModel model)
{
bool _status = false;
BLLWorkouts _objBLLWorkouts = new BLLWorkouts();
tblWorkout _row = new tblWorkout();
_row.WorkoutName = model.WorkoutName;
_row.WorkoutNote = model.WorkoutNote;
_row.Sessions = model.Sessions;
_row.pkWorkoutId = model.pkWorkoutId;
_row.CmpFlag = model.CmpFlag;
_status = _objBLLWorkouts.UpdateWorkout(_row);
return RedirectToAction("ModifyWorkout", new { WorkoutId = model.pkWorkoutId, Status = _status });
}
Now problem is that after updating my url becomes like this:
/ModifyWorkout?WorkoutId=438b6828-1a21-4ad0-9e40-485dda75b1f6&Status=true"
And Status message is shown even after refreshing the page due to &Status=true in Url.
<div >
#if (ViewBag.UpdateStatus != null)
{
if (ViewBag.UpdateStatus)
{
<span class="successmsgCommon">Workout updated successfully.</span>
}
else
{
<span class="errormsgCommon">Workout was not updated. Please try again.</span>
}
}
</div>
Is there any way to solve this?
Use TempData to send the value
TempData["Status"] = true;
Consume
if (TempData["Status"])
About TempData
TempData is used to pass data from current request to subsequent request means incase of redirection.
TempData is a dictionary object that is derived from TempDataDictionary class and stored in short lives session
You can use TempData for this:
TempData["Status"] = _status;
return RedirectToAction("ModifyWorkout", new { WorkoutId = model.pkWorkoutId });
ASP.NET MVC will store this value for the next request so you can read it in the redirected action.
if ((bool)TempData["Status"])
{
<span class="successmsgCommon">Workout updated successfully.</span>
}
else
{
<span class="errormsgCommon">Workout was not updated. Please try again.</span>
}

two models in a view - not working for me

I have created an entity data model from my database. however in certain areas of the application i need to pass two models. thus i create a third model which has as properties the objects of each required model.
In the scenario, i want to use one model just to show some data to the user and the other is to be populated by the user using form elements. therefore, i create a constructor in my custom model to populate it. here's the code:
THE CUSTOM MODEL
public class ordersModel
{
public ordersModel(order or)
{
this.prods = new order_products();
this.new_order = new order();
this.new_order.customer_id = or.customer_id;
this.new_order.my_id = or.my_id;
this.new_order.my_order_id = or.my_order_id;
this.new_order.order_date = or.order_date;
this.new_order.order_status_id = or.order_status_id;
}
public order new_order { get; set; }
public order_products prods { get; set; }
}
IT IS USED IN THE CONTROLLER AS FOLLOWS:
public ActionResult Create()
{
order or = new order();
// Store logged-in user's company id in Session
//or.my_id = Session["my_id"].ToString();
//do something to allow user to select customer, maybe use ajax
or.customer_id = "123";
or.order_amount = 0;
or.my_id = "74973f59-1f6c-4f4c-b013-809fa607cad5";
// display date picker to select date
or.order_date = DateTime.Now.Date;
// fetch statuses from database and show in select list box
or.order_status_id = 1;
return View(or);
}
//
// POST: /Orders/Create
[HttpPost]
public ActionResult Create(order or)
{
using (invoicrEntities db = new invoicrEntities())
{
var temp = db.last_order_number.SingleOrDefault(p => p.my_id == or.my_id);
if (temp != null)
{
or.my_order_id = temp.my_order_id + 1;
if (ModelState.IsValid)
{
ordersModel ord = new ordersModel(or);
db.orders.AddObject(or);
temp.my_order_id = temp.my_order_id + 1;
//TempData["my_order_id"] = or.my_order_id;
db.SaveChanges();
return RedirectToAction("AddProducts", ord);
//return RedirectToAction("AddProducts", new { id = or.my_order_id });
}
return View(or);
}
return RedirectToAction("someErrorPageDueToCreateOrder");
}
}
public ActionResult AddProducts()
{
using (invoicrEntities db = new invoicrEntities())
{
//string my_id = TempData["my_id"].ToString();
//string my_order_id = TempData["my_order_id"].ToString();
string my_id = "74973f59-1f6c-4f4c-b013-809fa607cad5";
int my_order_id = 1;
//Int64 my_order_id = Convert.ToInt64(RouteData.Values["order_id"]);
// Display this list in the view
var prods = db.order_products.Where(p => p.my_id == my_id).Where(p => p.my_order_id == my_order_id).ToList();
var or = db.orders.Where(p => p.my_id == my_id).Where(p => p.my_order_id == my_order_id).ToList();
if (or.Count == 1)
{
//ViewData["name"] = "sameer";
ViewData["products_in_list"] = prods;
ViewData["order"] = or[0];
return View();
}
return RedirectToAction("someErrorPageDueToAddProducts");
}
}
[HttpPost]
public ActionResult AddProducts(order_products prod)
{
prod.my_id = "74973f59-1f6c-4f4c-b013-809fa607cad5";
// find a way to get the my_order_id
prod.my_order_id = 1;
return View();
}
THIS ALL WORKS OUT WELL, UNTIL IN THE "ADDPRODUCTS" VIEW:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<invoicr.Models.ordersModel>" %>
AddProducts
<h2>AddProducts</h2>
<%: Model.new_order.my_id %>
the above statement gives an error
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
what am i doing wrong here?
You seem to be passing the wrong model when redisplaying your Create view.
Try passing the ord instance which is of type ordersModel and which is what your view is strongly typed to:
public ActionResult Create(order or)
{
using (invoicrEntities db = new invoicrEntities())
{
var temp = db.last_order_number.SingleOrDefault(p => p.my_id == or.my_id);
if (temp != null)
{
or.my_order_id = temp.my_order_id + 1;
ordersModel ord = new ordersModel(or);
if (ModelState.IsValid)
{
db.orders.AddObject(or);
temp.my_order_id = temp.my_order_id + 1;
db.SaveChanges();
return RedirectToAction("AddProducts", ord);
}
return View(ord);
}
return RedirectToAction("someErrorPageDueToCreateOrder");
}
}
UPDATE:
Now that you have shown your AddProducts action you are not passing any model to the view although your view expects an ordersModel instance. So don't just return View();. You need to pass an instance of ordersModel:
if (or.Count == 1)
{
ViewData["products_in_list"] = prods;
ViewData["order"] = or[0];
ordersModel ord = new ordersModel(or[0]);
return View(ord);
}

ASP.NET MVC: Server Validation & Keeping URL paramters when returning the view

I currently have the following code for the POST to edit a customer note.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditNote(Note note)
{
if (ValidateNote(note))
{
_customerRepository.Save(note);
return RedirectToAction("Notes", "Customers", new { id = note.CustomerID.ToString() });
}
else
{
var _customer = _customerRepository.GetCustomer(new Customer() { CustomerID = Convert.ToInt32(note.CustomerID) });
var _notePriorities = _customerRepository.GetNotePriorities(new Paging(), new NotePriority() { NotePriorityActive = true });
IEnumerable<SelectListItem> _selectNotePriorities = from c in _notePriorities
select new SelectListItem
{
Text = c.NotePriorityName,
Value = c.NotePriorityID.ToString()
};
var viewState = new GenericViewState
{
Customer = _customer,
SelectNotePriorities = _selectNotePriorities
};
return View(viewState);
}
}
If Validation fails, I want it to render the EditNote view again but preserve the url parameters (NoteID and CustomerID) for something like this: "http://localhost:63137/Customers/EditNote/?NoteID=7&CustomerID=28"
Any ideas on how to accomplish this?
Thanks!
This action is hit by using a post. Wouldn't you want the params to come through as part of the form rather than in the url?
If you do want it, I suppose you could do a RedirectToAction to the edit GET action which contains the noteId and customerId. This would effectively make your action look like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditNote(Note note)
{
if (ValidateNote(note))
{
_customerRepository.Save(note);
return RedirectToAction("Notes", "Customers", new { id = note.CustomerID.ToString() });
}
//It's failed, so do a redirect to action. The EditNote action here would point to the original edit note url.
return RedirectToAction("EditNote", "Customers", new { id = note.CustomerID.ToString() });
}
The benefit of this is that you've removed the need to duplicate your code that gets the customer, notes and wotnot. The downside (although I can't see where it does it here) is that you're not returning validation failures.

Binder for long{} in MVC

[AcceptVerbs(HttpVerbs.Post)]
public JsonActionResult <BaseAsyncResponse> Add(long[] IdList)
{
for (int i = 0; i < IdList.Length; i++)
{
// do something
}
}
var o = {
url: addButton.action.url,
method: addButton.action.method,
params: {
'IdList': Ext.encode(allIds)
}
};
Ext.Ajax.request(o);
I am trying to pass a long[] to code behind from an Ajax call. The IdList currently comes in as a string which I convert into a JsonArray. Is there a ways to use the bind attribute ?
If you want to use DefaultModelBinder your request content should look like:
IdList[0]=100&IdList[1]=200&IdList[2]=300&IdList[3]=400&...&IdList[n]=...

Resources