What I want to do is to sent data from a view to another (just a name)
I've tried using the ViewBag but it losts all the data in the postback.
Find useful this example but:
How to pass data from razor view to controller in mvc3?
The data that I'm trying to send is in the index of a list of Stores and I got a link that sends you to the View that contain the images /StoresImages.
I got in the Stores view and in StoreImages index the following inputs:
<input type="text" name="StoreName"/>
and in StoreImagesController:
public ActionResult SaveName(string StoreName, FormCollection Collection){}
This is exactly as is in the example above but I'm getting the following error: not all code paths return a value.
What I'm missing??
You should return something from ActionResult:
[HttpPost]
public ActionResult SaveName(string StoreName, FormCollection Collection)
{
ViewBag.StoreName = StoreName;
return View("viewName");
}
Then you can use ViewBag.StoreName in "viewName" view;
Related
I have a drop down box in my jsp with a search button. On the click of search button on the same jsp below this drop down and search button i am displaying a data table which took the selected value from the drop down and displays all the results matching the key.
Jsp:
<form:form action="/search" modelAttribute="myModel" method="post">
<form:select path="categorySearched">
<form:option option="0" label="--Select--">
<form:options items="${myModel.categoryList}" itemLabel="name" itemValue="id"/>
</form:select>
<button type="submit">Search</button>
</form:form>
<form:form action="/edit" modelAttribute="myModel" method="post">
<c:forEach var=""... -------------------------->>>>> data table displayed properly
</form:form>
Controller:
#RequestMapping(value = "/showSearchPage", method = RequestMethod.GET)
public String showSearch(#ModelAttribute("myModel") MyModel myModel){
//call from db to get list of category type objects
myModel.setCategoryList(categories);
return "SearchPage";
}
#RequestMapping(value = "/search", method = RequestMethod.POST)
public String searchGoals(#ModelAttribute("myModel") MyModel myModel) throws Exception {
System.out.println(goalModel.getCategoryList());------------>> null; want this to have all objects in the list
..................
return "SearchPage";
}
MyModel:
private List<Category> categoryList;
private String categorySearched;
Catgory:
private String id;
private String name;
As you can see on search i am returning "SearchPage" and displaying same page.
i want to re-populate drop down on Search without calling the db again. It is because i can change the search criteria again from different selection in drop down.
Please help me bind the category objects from drop down to the model. Everything else is working as expected. only when i click on search button and page reloads the drop down is not getting populated.
When you are processing a /search request, the list of all categories is nowhere : you do not want to fetch it from the db and it did not come from the request parameters. Because when you write :
#RequestMapping(value = "/search", method = RequestMethod.POST)
public String searchGoals(#ModelAttribute("myModel") MyModel myModel)
Spring creates a new MyModel and populates it with request parameters.
If the request is simple enough, the more straightforward solution would be to cache the getCategories(xxx) method at service level. That way, you can call it as many times you want without reloading it from db. EhCache for example integrates nicely in Spring. Advantage : you just write in your code that you want the date and the framework deals with the caching
An alternative is to use a #SessionAttribute. If you add
#SessionAttributes("myModel")
above you controller class declaration, you ask Spring to store the model attribute myModel in session and take it from there instead of re-creating a new one on each request. It should meet your requirement but has drawbacks : there is no simple and reliable way to purge the attribute from the request when it is no longer needed. It is up to you to decide whether you can waste some session memory for that or not, depending on the number of expected simultaneous sessions, the server memory, ...
This question already has answers here:
When to use TempData vs Session in ASP.Net MVC
(7 answers)
Closed 7 years ago.
I have an ASP.NET MVC online shop-like application with two views:
An item's page (photo, description, etc.)
A form where the user may leave a review
After the user successfully submits the form, he should be redirected back to the item's page and a one-time message should be displayed on top: "Your review has been submitted successfully".
The controller code (simplified) looks like this:
[HttpGet]
public ActionResult ViewItem([Bind] long id)
{
var item = _context.Items.First(x => x.Id == id);
return View(item);
}
[HttpGet]
public ActionResult AddReview()
{
return View();
}
[HttpPost]
public ActionResult AddReview([Bind] long id, [Bind] string text)
{
_context.Reviews.Add(new Review { Id = id, Text = text });
_context.SaveChanges();
return RedirectToAction("ViewItem");
}
There are a few requirements to meet:
The message must not show again if the user refreshes the item's page.
The message must not pollute the URL.
The controller methods may not be merged into one.
I was thinking of storing the message in user session and discarding it once displayed, but may be there's a better solution?
By using tempdata you can pass message or data(string/object) from one page to another page and it's valid only from one action to another.
Some key points about tempdata:
TempData is a property of ControllerBase class.
TempData is used to pass data from current request to subsequent request (means redirecting from one page to another).
It’s life is very short and lies only till the target view is fully loaded.
It’s required typecasting for getting data and check for null values to avoid error.
It is used to store only one time messages like error messages, validation messages. To persist data with TempData refer this article:Persisting Data with TempData
In your controller:
[HttpPost]
public ActionResult AddReview([Bind] long id, [Bind] string text)
{
_context.Reviews.Add(new Review { Id = id, Text = text });
_context.SaveChanges();
TempData["message"] = "someMessage";
return RedirectToAction("ViewItem");
}
In your view page:
#TempData["message"]; //TempData["message"].ToString();
I am passing an object to an action method and that action method displays the view but it has all the proerties in the querystring and I do not want that (I have a long json string that cannot pass in url). How can I pass in a model object and not have it in the querystring? Also when you have a strong type view, Where does the object values for the Model store? Thanks for any help.
//This works fine when I am calling /controller/uploader
public ActionResult Uploader(Model model)
{
//logic
return View(model);
}
//But when I am on another method and want to call uploader it does pass the object but puts //all the data in a querystring
public void DoSomething(string val, string anotherval){
Model model = new Model();
Uploader(model);//This passes the object but when uploader page shows it has all the //model object properties in querystring and I do not want that.
return RedirectToAction("Uploader",model);//or this does the same thing
}
Try using the POST method on the html form:
<form action="/uploader" method="POST">
<!-- maybe some input elements? -->
<input type="submit" />
</form>
This will transfer the data as Form Encoded within the request body and keep the data out of the query string.
I'm a bit confused.
I have a pretty standard MVC3 setup: Home Controller/Index method, Strongly typed view to a ViewModel.
My ViewModel is a collection of three generic lists (Schemes, Types, Tables),
TableModel
Schemes List
TypesList
TablesList
Schemes and Types populate dropdowns to act as filters on the third (Tables) collection which populates a HTML table via a #foreach loop
I populate these via a call to Home/Index (no arguments). This works fine. Now I want to mark a number of rows from the TablesList collection for deletion by checking a checkbox and then, on clicking Submit, I want the deletion to be actioned via a Post and the table contents to be refreshed with the remaining tables back into the same place (replacing the existing HTML table
In my Index View I have this section:
#using (Html.BeginForm("DeleteTables", "Home"))
{
#Html.Hidden("tableList", #Model.TablesList)
<input id="deleteButton" type="submit" />
}
in my HomeController I have a POST method as follows
[HttpPost]
public ActionResult DeleteTables(List<ViewModel.ITableInformation> tableList)
{
var deleteableTableIds = from t in tableList
where t.DeleteTable
select t.TableId;
this.tableModel.DeleteTablesById(deleteableTableIds.ToList());
.... execute a db call to get remaining tables and return a PartialView or JSON
}
Problem is I'm expecting the tableList argument to this function to contain my model but it's empty.
Any idea what I'm doing wrong - pretty new to this I'm afraid.
Thanks
The hidden can't take a complex object; what you would need to do is deserialize each object and store it in the hidden as a string, something like:
#{
var tableIDs = "";
foreach (var i in Model.TablesList) {
tableIDs = //serialized object in proper format
}
}
#Html.Hidden("tableList", #tableIDs)
From the server, you can create the objects through a custom model binder, or accept an input of type string, and deserialize the collection.
I'm building a validation form in my application. In that form there are two buttons. One to accept and one to reject. When the user press reject the rejection reason field must be provided. I check this serverside.
I first check what button is pressed and then if the field is empty I add a moddel error to the modelstate. But, because all fields in the form are readonly, those are not posted back to the server and therefor when I return the view back to usern there is no data. I'm probably missing something obvious, but cant find what to do. (I know I can make all fields in my form hidden, but due to the large amount of fields this would be really ugly)
This is my code.
[HttpPost]
public virtual ActionResult Validate(string action, Record dto) {
if(action == Global.Accept) {
ciService.Store(dto);
return RedirectToAction("Index", "Ci");
} else {
if(string.IsNullOrEmpty(dto.RejectionReason)) {
ModelState.AddModelError("RejectionReason", "REQUIRED!!!!");
return View("Validate", dto);
}
ciService.Reject(dto);
return RedirectToAction("Index", "Ci");
}
}
You need to recreate the model from the database and then change it to match whatever changes are posted in dto. Then use that combined model in the view.
Instead of passing the DTO back from the browser, I would use a hidden HTML field or a querystring parameter containing the ID that identifies the DTO. Then your POST action method would look something like:
[HttpPost]
public virtual ActionResult Validate(string action, int id)
{
// reload the DTO using the id
// now you have all the data, so just process as you did in your question
if (action == Global.Accept) { ... }
...
}
Your GET method might look something like the following then...
[HttpGet]
public virtual ActionResult Validate(int id)
{
// load the DTO and return it to the view
return View();
}
In this way you have all the data you need within your POST action method to do whatever you need.
You need to have hidden fields corresponding to each property displayed in UI.
e.g.,
#Html.LabelFor(m=>m.MyProperty) - For Display
#Html.Hiddenfor(m=>m.MyProperty) - ToPostback the value to server
If I understand right, the problem is because you don't use input.
To solve your problem insert some input hidden in your form with the value you need to be passed to the controller
#Html.HiddenFor(model => model.Myfield1)
#Html.HiddenFor(model => model.Myfield2)
that should fix the values not passed back to your actions
If you don't need these fields on the server side, simply create a new ViewModel
RecordValidateViewModel and this contains only the fields in it that need to be validated. The model binder will populate then and you will have validation only on the fields in that model rather than all the other fields you don't seem to want there.
If you need them to validate, then post them back to the server. Its not 'ugly' if hidden.