Completely new to asp.net mvc... completely new to web apps so bear with me...
Lets say I have an Action on a controller that requires a specific piece of information, say an int Id value.
A view is rendered from this Action. This view contains a button which will take the user off to a new Action on another Controller.
On the view of this second Action, there is a link that will send them back to the original Action on the Controller. Obviously, I've lost the original Id value and therefore the information I need to render my original view. What do I need to be looking into to solve this? Are there techniques/patterns that could be used to help?
I know I can keep passing the value around but if the other controller doesn't actually need this value it seems wasteful. I think I'm probably approaching the problem the wrong way to be honest. Any help appreciated.
I know I can keep passing the value
around but if the other controller
doesn't actually need this value it
seems wasteful.
But the second controller does need the id to function properly - as you've said, it needs the id to render the return link. Passing it around is the right thing to do.
There are many ways you can achieve this. Some of them are :
You can keep the value in the Query String.
If navigation from Action-1 to Action-2 is done via posting a form, you can send the value with a hidden input tag. Eg : <input type="hidden" name="n" value="v" />
You can use TempData to persist information between two requests (though it doesn't look like this is a good solution for your case)
Without knowing what exactly you are trying to do, it's hard to know best solution.
Related
I am having an issue with my session variables. I am adding objects to session, so that when i navigate to the next page (building a sort of questionnaire) i can retrieve these values in another Controller action, and use the stored value to make some calculations.
It is also said that this functionality is used for the user to go backwards through the questionnaire, should they wish to change an input to get a different outcome. However upon going backwards, the variables are gone, and my controller action code fails and brings back a null reference exception.
Any thoughts on why this is doing this? I am adding the the variable to session using following way:
Session["UserInfo"] = myObject;
and retrieving like so
InputData data = (InputData) Session["UserInfo"];
any reasons why i'm losing these objects. If i go back and click submit again , they're back in session and usable on the following page. I don't think this is a session timeout issue as i do it well within 20mins, usually like 30secs (as i'm developing the system and testing and making changes etc.)
I have solved this, my issue was the GET and POST requests on my action controllers. I was not specifying two controller actions explicitly (HTTPGET and HTTPPOST) so all requests going to the same action, and therefore was over-riding the session variable with NULL as nothing was being posted, as a ajax get request.
Setup up two action results HTTP POST and HTTP GET one with input parameters and the other without. Never crossed my mind, until had a cup of coffee and a fresh brain.
Suppose I have a model with some string property.
Imagine also that this string property is actually a comma delimited list of values.
If I want to make a form to update values on my model it would be easy enough to call:
#Html.TextBoxFor(model => model.myCommaDelimitedProp, new { #class = "form-control", placeholder = "CommaDelimitedPropValue" })
However, that is not good enough for the intended application.
I would like to have a custom EditorFor() that could somehow take my property, use string parsing and next generate an array of text boxes to display the pre-existing values.
That would also be relatively trivial.
However, what I cannot seem to solve, mainly because I lack client side experience (js, jquery, angular, ...):
How could I make my editor such that there would be a small button so that I could dynamically add rows, fill them such that, upon form submission, I could string the new values onto the pre-existing string.
So specifically, what would any of you use to achieve this client side behaviour?
I just need some help to be put on the way...
You can achieve this with editor templates. There's a quick intro I threw together on my blog. The only additional thing you'll need is UIHint. Since you won't be able to rely on a specific C# type or DataType annotation to determine that this should be treated as a comma-delimited property. You can just explicitly tell Razor what template it should use. For example:
[UIHint("CommaDelimited")]
public string MyCommaDelimitedProperty { get; set; }
Which would correspond to the editor template: Views\Shared\EditorTemplates\CommaDelimited.cshtml. Once you set up that view how you like it. Then in your form you just call:
#Html.EditorFor(m => m.MyCommaDelimitedProperty)
EDIT
I'll leave my previous answer because it could still be helpful in terms of being able to generate a control for a specific type of thing. You actually may still need to use it to get the right set up on your field to make the JS work properly.
However, when it comes to the client-side handling of this, I figured there had to be something out there already to solve this problem. (Never do more work than you have to.) A cursory search turned up a little script called Tokenfield for Bootstrap. I'm not sure if you're using Bootstrap or not. If not, I also found jQuery Tokeninput and jquery.token-field. I'm sure there's others, as well.
I was wondering whether there is a way to create an ActionLink or similar, that changes only a few parameters of the actual query, and keeps all the other parameters intact. For example if I'm on an URL like http://example.com/Posts/Index?Page=5&OrderBy=Name&OrderDesc=True I want to change only the Page, or OrderBy parameter and keep all other parameters the same, even those I don't yet know of (like when I want to add a Search parameter or something similar too).
The header of my current action looks like this:
public ActionResult Index(int? Page, string OrderBy, bool? Desc)
and I'm only interested in the values that this controller "eats". I want however that when I extend this action (for example with a string Search parameter) the links should work the same way as before.
Here is what I did already:
Create a new RouteValueDictionary and fill it with everything from RouteData.Values
Problem: This only fills the parameters that are used in the Routing, so all other optional parameters (like Page) to the controller are lost
Add everything from HttpContext.Request.QueryString to the previous dictionary
This is what I am currently using
Problem: It might have some junk stuff, that the Controller didn`t ask for, and it doesn't work if the page was loaded using POST. You also don't have any ModelBindings (but this isn't much of a problem, because we are re-sending everything anyway)
Use HttpContext.Request.Params
Problem: this has too much junk data which imho one shouldn't add to a RouteValueDictionary that is passed to an ActionLink
So the questions:
Is there an RVD that has all the data that was passed to the Controller and was used by it?
Is this solution good, or are there any caveats I didn't think about (mainly in the context of changing a few query parameters while keeping the others intact)?
Is there a way to filter out the "junk" data from the Params object?
EDIT: Checked the RouteData.DataTokens variable, but it's usually empty, and doesn't contain everything I need. It seems to only contain parameters that are needed for the routing somewhere, but not all of the parameters.
Have a look in RouteData.DataTokens.
RouteData.DataTokens # MSDN documentation:
Gets a collection of custom values that are passed to the route handler but are not used when ASP.NET routing determines whether the route matches a request.
HTHs,
Charles
I'm currently trying to user actionlink helpers in a way that I don't think was described in NerdDinner.
Lets say I am on this page
/Dinners/
and on that page there is a list of dinners, ok fine and working
now lets say I want to goto a new section of the site, which I have created a new controller MenuItemsController
so lets say I want to goto a new part of the website that manages menu items.
So going to
/menuitems/3
would bring up all the menu items assoicated with dinner id 3.
This is also working.
I am having trouble, linking to each of the menu item pages, because when I use the actionlink code, without much modification i get this
dinner1 = link /dinners/menuitems/3
rather than
dinner = link /menuitems/3
The actionlink code i am trying is
<%= Html.ActionLink("Menu Items", "/menuitems", new { id=item.id })%>
you can see the / there. This feels wrong.
I wasn't sure if this post was talking about the same problem or not.
how do i have links to root controllers in site.master in asp.net mvc
Are action links the completely wrong thing for me to be using here, becuase they are binded directly to the controller I am currently inside of?
If so, what would be the best method for me to achieve what I am trying to do, and also add further complexity like linking to create/edit/delete methods?
Just get rid of the slash and specify the controller and action explicitly:
<%= Html.ActionLink("Menu Items", "Item", "menuitems",
new RouteValueDictionary { { "id", item.id } })%>
You don't give an action name in your examples, so I guessed "Item." Insert the correct action name, obviously.
The current controller name is used if you use one of the ActionLink overloads which don't take a controller name.
I've written an in-depth explanation of routing, ActionLink, and more.
I oddly after much searching all day just found this page,
http://devlicio.us/blogs/derik_whittaker/archive/2008/03/06/link-building-101-with-asp-net-mvc.aspx
it seems like method 3 may be what I need, I'll try it when I get home.
Heading
I want to pass some variables from one page to another but I don't want them to appear in the URL. When I use a form to post the an ActionResult it works fine. However, when I do this
return RedirectToAction("Trackers",new{page = 1, orderby=desc});
I get the URL:
http://examplesite.com/Trackers?page=1&orderby=desc
Is there any way I can get the following URL instead but still pass the page and orderby variables "behind the scenes"?
http://examplesite.com/Trackers
Thanks
TheLorax
I'm not sure it's a good idea to do what you're suggesting, however, you might be able to use the TempData (same place as the ViewData) to save your information before the redirect. I believe that after your next request, anything in the temp data is cleared out.
You could pass a Model object containing the page number and the orderby instead of an anonymous object, and have your view inherit the model class of the object you are passing. Your model object with the page number and orderby then becomes available to the view, without employing a query string
This is not, however, the preferred method of doing this. Your model objects should be reserved for their intended purpose, which is passing actual data to your view.
When you use RedirectToAction method the browser will recieve an http redirect response from the server and then will do a GET request to the new URL.
I think there is no way to make the browser make a POST request when redirecting.
Also it is better to pass these variables through the query string in order for the user to be able to bookmark the page.