How to handle query string in Asp.net MVC 5 - asp.net-mvc

I have an ASP.NET MVC 5 website. I have used action link while designing table to display a list of data. while navigating from that action link I have passed a class object as a parameter. After visiting that link, it parses that object parameter as long query string which exposes data in the URL.
What is the way to handle a query string in MVC?
Is it possible to hide query string or way to pass an object as a parameter without exposing it in the URL?

You can not hide the query string, it is part of the URL. You could encrypt it tho.
One solution would be to use a POST request instead of a GET. Then you can send the data in the body of the request, it will not show up in the URL. But it will still be accessible if you inspect the network traffic (e.g. if you run Fiddler on the client computer).
Another solution would be to still use a GET request, but instead of passing all the data, just pass an ID, then load the data again from the database using this ID. Note that this ID can be spoofed too, so make sure the User has actually the permissions to request this ID.
#Html.ActionLink("Show details", "Details", "Data", new { dataId = Model.Id })
[HttpGet]
public ActionResult Details(long dataId) {
var data = _dbContext.Data.Find(dataId);
var vm = new DataDetailsViewModel(data);
return View("Details", vm);
}

Related

How can I extract a parameter named "action" from the url without having to manually parse the querystring in MVC?

I have a site entry controller that is used via a url generated by a single sign on manager. The SSO manager appends an identifying hash as an action parameter to the url of the system it is attempting to sign on to.
So the url being generated by the SSO manager looks like:
http://mysite/Entry/SingleSignOn?action=123456789ABCDEFG
I think I just need to set up a better route, but I haven't been able to get it to work yet. When I try to get the action from the url via standard MVC binding, it is giving me the name of the action, not the hash I need:
public ActionResult SingleSignOn(string action)
{
// action returns "SingleSignOn"
var querystring = Request.Url.Query; //returns "?action=123456789ABCDEFG"
return RedirectToAction("Index");
}
I know I can just split open the querystring, but would prefer not to if possible. It doesn't seem like a terribly complex problem, but I am just not finding the right route.
You can use Request.QueryString["action"] to explicitly get the parameter value from your request url.
public ActionResult SingleSignOn(string action)
{
var querystring = Request.QueryString["action"];
// Do something with querystring
return RedirectToAction("Index");
}

MVC Redirect to a different view in another controller

After a user has completed a form in MVC and the post action is underway, I am trying to redirect them back to another view within another model.
Eg. This form is a sub form of a main form and once the user has complete this sub form I want them to go back to the main form.
I thought the following might have done it, but it doesn't recognize the model...
//send back to edit page of the referral
return RedirectToAction("Edit", clientViewRecord.client);
Any suggestions are more that welcome...
You can't do it the way you are doing it. You are trying to pass a complex object in the url, and that just doesn't work. The best way to do this is using route values, but that requires you to build the route values specifically. Because of all this work, and the fact that the route values will be shown on the URL, you probably want this to be as simple a concise as possible. I suggest only passing the ID to the object, which you would then use to look up the object in the target action method.
For instance:
return RedirectToAction("Edit", new {id = clientViewRecord.client.ClientId});
The above assumes you at using standard MVC routing that takes an id parameter. and that client is a complex object and not just the id, in which case you'd just use id = clientViewRecord.client
A redirect is actually just a simple response. It has a status code (302 or 307 typically) and a Location response header that includes the URL you want to redirect to. Once the client receives this response, they will typically, then, request that URL via GET. Importantly, that's a brand new request, and the client will not include any data with it other than things that typically go along for the ride by default, like cookies.
Long and short, you cannot redirect with a "payload". That's just not how HTTP works. If you need the data after the redirect, you must persist it in some way, whether that be in a database or in the user's session.
If your intending to redirect to an action with the model. I could suggest using the tempdata to pass the model to the action method.
TempData["client"] = clientViewRecord.client;
return RedirectToAction("Edit");
public ActionResult Edit ()
{
if (TempData["client"] != null)
{
var client= TempData["client"] as Client ;
//to do...
}
}

Alternative to using Webclient to get HTML output

A product I've inherited is using WebClient to read HTML from a MVC based site. Each page is a different type of e-mail, so in order to compose and send an e-mail they use WebClient to request a URL and download the string.
var outputHtml = string.Empty;
using (WebClient client = new WebClient())
{
client.Encoding = Encoding.UTF8;
outputHtml = client.DownloadString(emailURL);
}
return outputHtml;
Is there a way to remove the need to host this email based site but retain most of this code. I guess what I need to do is pass my request to the controller and retrieve the output after the razor engine has passed the view model through the cshtml page.
Is that possible?
There are many ways you could render a Razor view to a string. One possibility is to use RazorEngine. Another possibility is to use some specifically designed framework for this purpose such as Postal.

Completely not understanding View Data for MVC right now, need some serious help & code examples

I really need to maintain this string called "filterParams" in my MVC application. After the user enters some search parameters he clicks submit, and the grid is rebinded with that parameter. That works great. I also save the filterParams data in a Javascript variable, so when the user pages, and the OnDataBinding event is raised, the filter is also passed through that ajax call as well. this is all well and good however there is a huge issue, because when the user updates a question, all the results dissapear because it returns to the View and it does not have any data there. The way I'm using ViewData isn't working, and I could use your help, because if I can store it in ViewData and access it, it would fix my problems. I cannot use TempData because there are a number of other Actions that can be called in between Select and Update...Long question short, how do I implement ViewData correctly to store and retrieve a string in my controller?
Here are some code snippets.
[GridAction]
public ActionResult GetAllQuestion(string filterParams)
{
var _filterParams = new List<string>();
_filterParams.Add(filterParams);
ViewData["filterParams"] = _filterParams;
return View(new GridModel(QuestionManager.Instance.GetQuestion(filterParams)));
}
[GridAction]
public ActionResult EditQuestion(int id, QuestionDTO pQuestion)
{
// var _question = QuestionManager.Instance.GetQuestion(id,false).FirstOrDefault();
// TryUpdateModel(_question);
var _filterParams = (List<string>)ViewData["filterParams"];
var filterParams = _filterParams[0];
QuestionManager.Instance.UpdateQuestion(pQuestion);
// return View(new GridModel(QuestionManager.Instance.GetQuestion(id, false)));
return View(new GridModel(QuestionManager.Instance.GetQuestion(filterParams)));
}
in my aspx page
Html.Telerik().Grid<QuestionDTO>()
.DataBinding(dataBinding => dataBinding.Ajax().Select("GetAllQuestion", "Question", new { filterParams = string.Empty }).Update("EditQuestion", "Question").Insert("CreateQuestion", "Question"))
How can I get this to work please? Help is appreciated
ViewBag/ViewData only works for sending data from an action to a view. It does not get populated by the Model Binder when a request is made to an action, and its state is not saved between requests because ASP.net MVC is entirely stateless. In other words, the ViewData dictionary is always empty at the start of a request.
Meaning this line in your EditQuestion action will not work:
var _filterParams = (List<string>)ViewData["filterParams"];
ViewData is empty, so _filterParams will be null.
You have to manually send filterParams to the EditQuestion action just as you do for the GetAllQuestions action.
Perhaps a better alternative would simply be to persist filterParams using a temp cookie on the client side.
So, just to defy all the misinformation I've read on the subject, TempData infact does persist through multiple action calls in the controller and was able to be used to implement the functionality I needed.
Why just not store the data in Session?
Here's a good explanation with examples
http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications

multi steps information submission using TemData IN ASP.Net MVC

I am working on a MVC web form where user will submit the Album information in the first step, after submitting the Album information in the second step user can submit the track information data.But i am little confused how i ll do in MVC , in normal webform it is easy for me to do .I am looking for some sloution for this.
If you're not writing the Album information to some kind of permanent storage at the end of step 1, e.g. database, file etc., then you could use TempData to keep track of the information entered into the wizard between page requests.
TempData uses Session state under the hood and is only persistent across a single request, so you would need write your album/track information to TempData at the end of every controller action and read it in again at the beginning of every action. Then, once you have accumulated all the album/track information, write it to permanent storage.
You might also consider just storing the album and Track ids in the URL. There are some benefits to this, like the ability to bookmark and email the URL to friends.
When you pass a RouteValueDIctionary to the UrlHelper.Action() method, any parameters in the dictionary that are not part of the route will be added into the query. So you could do this:
return Redirect(Url.Action("myaction", "mycontroller",
new { album = selectedAlbumVariable, track = selectedTrackVariable }));
And them retrieve them in the action by adding them to the action parameters like this:
public ActionResult SomeAction(string album, string track) { ... }
You would have to check for null on album and track before using them.
You can follow what pmarflee suggested, here is a litle example, using TempData:
public ActionResult Step1()
{
var MyObject = new List<string>();
//Some Logic
//Set the TempData
TempData["data"] = MyObject;
return RedirectToAction("Step2");
}
public ActionResult Step2()
{
//Get the Data From the TempData and Cast it
var MyObject = (List<string>)TempData["data"];
//Continue working
return View();
}
Just remember that this data will be available just for 1 more action, if you want to continue passing data you must set the data again in the TempData Dictionary.
You can also use another approach and serialize the data into a hidden field, this approach is cleaner but require more work, if you just want to save a couple of fields, TempData is good to go.

Resources