ViewData not being posted back to Controller - asp.net-mvc

I have two pages, one that edits user information, and one that edits information in a pictures table. I recently stopped using strongly typed viewmodels due to the varying types of data required on each page.
The page that edits the user information works fine, but the page that edits picture information does not post back any of the edits that are made in the input fields; except for the ID, which is correct, all the other values come back as null. They both seem to be structured exactly the same way -- I can't figure out what's the difference. As far as I can tell the code for both pages are the same, but I'm not getting data back on the second one.
User Controller and View which works
Controller
public ActionResult Preferences()
{
int userid = getUserID(User.Identity.Name);
// Info for user preferences
var accountInfo = db.users.Single(l => l.ID == userid);
ViewData["accountInfo"] = accountInfo;
AccountController usr = new AccountController(); // Info for user menu
ViewData["userInfo"] = usr.getUserInfo(User.Identity.Name);
return View();
}
[HttpPost]
public ActionResult Preferences(user accountInfo, string oldPW)
{
// Do stuff to save user info
return RedirectToAction(actionname, routeValues);
}
View
#using (Html.BeginForm("Preferences", null, FormMethod.Post,
new { id = "prefsform" }))
{
AutoShowApp_MVC.user item = new AutoShowApp_MVC.user();
item = ViewBag.accountInfo;
<input id="lastname" name="lastname" type="text" value="#item.lastname"/>
<input id="address1" name="address1" type="text" value="#item.address1"/>
<input id="city" name="city" type="text" value="#item.city"/>
<input id="state" name="state" type="text" value="#item.state"/>
<input type="submit" value="Submit Changes" />
}
Picture Controller and View which DON'T work
Controller:
public ActionResult Edit(long id)
{
var picInfo = db.lmit_pics.Single(l => l.ID == id);
ViewData["picInfo"] = picInfo; // get Picture Info
// Get User Info for menu
AccountController usr = new AccountController();
ViewData["userInfo"] = usr.getUserInfo(User.Identity.Name);
return View();
}
[HttpPost]
public ActionResult Edit(lmit_pics picInfo)
{
// Do stuff to save picInfo
return RedirectToAction("Index");
}
View:
#using (Html.BeginForm("Edit", null, FormMethod.Post, new { id = "editform" }))
{
AutoShowApp_MVC.lmit_pics item = new AutoShowApp_MVC.lmit_pics();
item = ViewBag.picInfo;
<input type="text" id="model" value="#item.model" />
<input type="text" id="description" value="#item.description" />
<input type="submit" value="Save" />
}

You do not have the name attribute specified on the inputs on your picture editing form.
<input type="text" id="model" value="#item.model" />
Should Be
<input type="text" id="model" name="model" value="#item.model" />
The form collection works from the name attribute, not the Id attribute which is why you are not getting any data back (you are, it is just not properly attributed).
However, I agree with Wahid above, using strongly typed view models, editorFor helpers, etc not only help to prevent issues such as the above, but really go a long way in making a more secure, easier to maintain site.

Related

How to get MVC button to populate and display a table after being clicked

I've looked for 4 or 5 hours now on how to get this to work but I simply cannot figure it out. I'm suppose to get a form that has both a submit and delete button. The submit should submit the data in the form to a table that gets populated and created at the same time while the delete button would delete the most recent addition. It doesn't seem to matter what I've tried to do it just doesn't work. Whenever I click on my save button it just reloads the page with empty form fields and no table with the data.
My Controller code
public class PersonController : Controller
{
private static List<Person> Persons = new List<Person>();
public ActionResult Index()
{
return View();
}
public ActionResult Start()
{
return View("PersonData");
}
public ActionResult AddPerson(string firstName, string lastName, string birthDate)
{
Person p = new Person();
p.firstName = firstName;
p.lastName = lastName;
p.birthDate = birthDate;
if (Persons.Count > 0)
{
Persons.Add(p);
}
return View("PersonData");
}
public ViewResult DeletePerson()
{
if(Persons.Count > 0)
{
Persons.RemoveAt(0);
}
return View("PersonData");
}
}
My View code
#model IEnumerable<UsingViewsandModels.Models.Person>
....
#using (Html.BeginForm("AddPerson", "PersonController"))
{
}
<form>
<label name="firstName">First Name: </label>
<input type="text" name="firstName" />
<br />
<label name="lastName">Last Name: </label>
<input type="text" name="lastName" />
<br />
<label name="birthDate">Birth Date: </label>
<input type="text" name="birthDate" />
<br />
<button type="submit" value="Submit" name="AddPerson" onclick="AddPerson()">Save</button>
<button type="submit" value="Delete" name="DeletePerson" onclick="DeletePerson()">Delete</button>
</form>
#if (Model != null && Model.Count() > 0)
{
<table>
<tr><th>FirstName</th><th>LastName</th><th>BirthDate</th></tr>
#foreach (UsingViewsandModels.Models.Person p in Model)
{
<tr>
<td>p.firstName)</td>
<td>p.lastName)</td>
<td>p.birthDate)</td>
</tr>
}
</table>
}
Any help would be greatly appreciated. I'm fairly certain I'm just being an idiot and it's something very simple.
You have this code:
return View("PersonData");
That means: return the view named "PersonData".
You are not sending no data to the view. Use the overload and send the model to your view like this:
return View("PersonData", Persons);
Now your view has access to all the data in Persons and it will work.

Update and ASP.NET MVC model on button click

I'm new to ASP.NET MVC. I'm trying to update model on button click with no success: every time I push the button an HttpGet controller method is invoked.
Here is my markup
#model DataInterface.Model.Entry
<button onclick="location.href='#Url.Action("Survey")'">Finish survey</button>
Here is Controller code
[HttpGet]
public ActionResult Survey()
{
var entry = new Entry();
return View(entry);
}
[HttpPost]
public ActionResult Survey(Entry newEntry)
{
// save newEntry to database
}
When I click button HttpGet method is invoked. Why?
It is bad to be a rookie)
Thanks to all!
If you access a URL without explicitly specifying the HTTP method, ASP.NET MVC will assume a GET request. To change this, you can add a form and send it:
#using (Html.BeginForm("Survey", "Controller", FormMethod.Post))
{
<input type="submit" value="Finish survey" />
}
If you do this, your POST method will be invoked. The Entry parameter, however, will be empty, since you do not specify any values to send along with the request. The easiest way to do so is by specifying input fields, e.g. text inputs, dropdown, checkboxes etc.
#using (Html.BeginForm("Survey", "Controller", FormMethod.Post))
{
#Html.TextBoxFor(m => m.Title)
<input type="submit" value="Finish survey" />
}
If you have the object stored on the server somewhere and only want to finish it off by writing it into the database or changing its status, you could pass the Id of the object (or some temporary Id) along the post request and make the controller method work only with the Id:
#using (Html.BeginForm("Survey", "Controller", FormMethod.Post))
{
#Html.HiddenFor(m => m.Id)
<input type="submit" value="Finish survey" />
}
[HttpPost]
public ActionResult Survey(Entry newEntry)
{
// newEntry.Id will be set here
}
#using (Html.BeginForm("Survey", "<ControllerName>", FormMethod.Post))
{
<input type="submit" value="Finish survey" />
}
you must declare your form
#model DataInterface.Model.Entry
#using (Html.BeginForm("action", "Controlleur", FormMethod.Post, new {#class = "form", id = "RequestForm" }))
{
<input type="submit" value="Finish survey" />
}

Get Values of DropDownList which is inside webgrid and also each dropdown is an attribute of the model

I have a webgrid contains a dropdown which contains different items for each user(Items are grouped). I want to get the selected values to the controller . How can I do that. Heres my ;
Model :
public SelectList AvailableDevices { get; set; }
View :
...
var grid = new WebGrid(Model. ...
..
..
grid.Column(header: "AvailableDevices", format: #item => Html.DropDownList("value", (IEnumerable<SelectListItem>)item.AvailableDevices)),
And I have a Submit Button
#using (Html.BeginForm("AssignUserDevices", "Device"))
{
<input type="submit" value="setUserDevice" onchange="CheckSelectedDevices()" />
}
I want to set users device according to his user type. I know what his choices and send dropdown items according to his type. So each item in webgrid differs from each other.
And Also I dont know how to give indices to each item in webgrid.( I think we will need it.)
Im new at MVC so hope you will understand.
Thanks;
What I got from our requirement that you want the selected item and have that item value in form field before posting if yes then you can follow as given.
#Html.DropDownList("value", (IEnumerable<selectlistitem>)item.AvailableDevices), new {#class="deviceclass"} )
#using (Html.BeginForm("AssignUserDevices", "Device"))
{
<input type="hidden" value="" name="deviceId" id="deviceId" />
<input type="hidden" value="" name="userId" />
<input type="submit" value="setUserDevice" />
}
<script>
$(".deviceclass").on('change', function () {
var dropdownvalue = $(this).val();
$('#deviceId').val(dropdownvalue);
})
</script>
and you can define an action function in controller
public ActionResult Details(string deviceId, string userId)
{
// do as you need.
return View();
}

MVC ERROR Illegal characters in path.

can someone tell me if im on the right track? Im trying to display my query but i get an error. I have two textbox with the same parameter and that parameter is declared as an IEnumerable.
[HttpPost]
public ActionResult Orders1(IEnumerable<int> order)
{
using (CostcoEntities1 context = new CostcoEntities1())
{
var query = string.Empty;
foreach (var orderID in order)
{
query = (from a in context.CM_Checkout_Details
where a.CheckoutDetails_ID == orderID
select a).ToString();
}
return View(query);
}
}
this is what my controller looks like..
I am trying to read the two numbers(Id) in the text box and diplay data based on those id.
#using (Html.BeginForm("Orders1", "Track", FormMethod.Post))
{
#Html.TextBox("order")<br />
#Html.TextBox("order")
<input type="submit" value="Submit" />
}
First thing, change the names of the textboxes so that they are not the same:
#using (Html.BeginForm("Orders1", "Track", FormMethod.Post))
{
#Html.TextBox("order1")<br />
#Html.TextBox("order2")
<input type="submit" value="Submit" />
}
Next, change the signature of your action method:
[HttpPost]
public ActionResult Orders1(string order1, string order2)
MVC's model binding will try to match order1 and order2 to stuff in Request.Form, for example, which should pick up the textbox values.

object gets passed to action as string

I have a form that has a hidden field wich stores a object. This object is a RoutesValues (I want to store a reference because when I process the form I want to redirect to a route). The action that processes the form is:
public ActionResult Añadir(string userName, string codigoArticulo, string resultAction, string resultController, object resultRouteValues, int cantidad)
{
processForm(codigoArticulo, cantidad);
if (!ModelState.IsValid)
TempData["Error"] = #ErrorStrings.CantidadMayorQue0;
if (!string.IsNullOrWhiteSpace(resultAction) && !string.IsNullOrWhiteSpace(resultController))
return RedirectToAction(resultAction, resultController, resultRouteValues);
return RedirectToAction("Index", "Busqueda", new {Area = ""});
}
and my form is:
#using (Html.BeginForm("Añadir", "Carrito", FormMethod.Get, new { #class = "afegidorCarrito" }))
{
<fieldset>
<input type="hidden" name="codigoArticulo" value="#Model.CodiArticle" />
<input type="hidden" name="resultController" value="#Model.Controller" />
<input type="hidden" name="resultAction" value="#Model.Action" />
<input type="hidden" name="resultRouteValues" value="#Model.RouteValues" />
<input type="text" name="cantidad" value="1" class="anadirCantidad" />
<input type="submit" />
</fieldset>
}
the problem I have is that resultRouteValues gets passed as a string instead of an object. Is there any way to fix this?
Thanks.
No, there is no easy way if RouteValues is a complex object. You will have to serialize the object into some text representation into this hidden field and then deserialize it back in your controller action. You may take a look at MvcContrib's Html.Serialize helper.

Resources