Removing null/empty keys from a query string in asp.net MVC - asp.net

Is there a way I can remove null or empty keys from a query string in asp.net MVC? For example I have a page where I filter data on a results table, if I search for John the query string would be redisplayed as:
candidates?FirstName=John&LastName=&Credit=false&Previous=false&Education=&Progress=
and not
candidates?FirstName=John
I looked at URL routing but I wasn't sure if it was something that should be used for cosmetic things like this or if it is possible to achieve what I'm asking using it.

How are you generating that URL? With Routing, if those are meant to be in the query string, it should work fine. We only generate query string parameters for RouteValues that you specify.
One thing I've done in the past is to write my own helper method for specific links where I might pass in an object for route values, but want to clear out the values that I don't need before passing it to the underlying routing API. That worked well for me.

Whatever URL generator, or control you are using would need special logic to strip these unwanted tags from the list. It's not obvious to a generic URL generator or control that Credit=false is useless -- couldn't it be Credit=true is the default? Similarly an empty string can mean something. (Also, Lastname= is different from Lastname.

I sometimes need to work on my route values in partials that are used by variuos views.
Then I usualy access the routeDictionary and change it. The benefit you get is, that there is a good chance that the code will survive changes in the routing and that you can use routeValues in multiple generated URL.
Most people would argue that the best place for this code is not the view. But hopefully you get the idea.
The view code:
RouteValueDictionary routeValues = ViewContext.RouteData.Values;
routeValues.Remove(...);
routeValues.Add(...);
routeValues["Key"] = ...;
<%
using (Html.BeginForm(
Url.RequestContext.RouteData.GetRequiredString("Action"),
Url.RequestContext.RouteData.GetRequiredString("Controller"),
routeValues,
FormMethod.Get))
{ %>

Maybe use this Querystring Builder - iterate querystrings in the Request.QueryString dictionary and build a new one using the builder (or just string-concat them)?

Related

asp.net webapi mapping a string param that has a querystring

I need to map a string param with a webapi method. Something easy:
/api/mycontroller/this_is_my_input_param
I know how to do it and it's working fine. However, problem is that my input param can have a query string. Something like:
/api/mycontroller/term?p=1&n=value
and I want that webapi map the entire "term?p=1&n=value" with the input param in the method. I just wanna tell webapi "ey, just take all the string you have after /api/mycontroller/ and send it to the action as input parameter"
I know that probably is not the best architectural thing, but I need it that way. Also, I don't know how many params and names I can have, so I can't use a complex type. I also need it as a GET. I know how to do it with a POST, but I need a GET if it's possible.
Many thanks.
Can you able to add that querystring to body and then by using (frombody/ fromuri) attributes
to grab the querystring and do whatever you want
Route[api/mycontroller/term]
public HttpResponseMessage myController([fromBody] querystring)
{
// do something for that querystring
}
please check webapi attributes from this link
enter link description here
Finally what I'm doing is mapping the entire HttpRequest, that way I can work with the full requestted URL and get all that I have after the Controller name:
public async Task<string> Get(HttpRequestMessage request)
I know would be better to create a custom ModelBinder or something like that, but in my case is enough doing it that way.
thanks for your help.

Symfony2: Why weren't query string parameters included in the routing component?

I am porting a legacy application to Symfony2 and I am struggling because routing doesn't include query string parameters. Some quick examples: Suppose you have a search page for books where you can filter results based on criteria:
http://www.bookstore.com/books?author=Stephen+King&maxPrice=20
The nice thing about query string parameters in a case like this is you can have any number of filters, use the ones you want for any given request, and not crowd the URL with filters you're not using.
Let's say we rewrote the routing for the above query using the Symfony2 routing component. It might look like this:
http://www.mybookstore.com/book/any_title/stephen%20king/any_release_date/max_price_20/any_min_price/any_format/any_category
Even not taking into account how arbitrarily long an unclean that URL is I still don't think it is as intuitive because each 'segment' of that route is not a key value pair but instead just a value (e.g. author=Stephen+King > /stephen%20king/).
You can of course access query string parameters in the controller by passing the Request object into the action method (e.g. indexAction(Request $request) {) but then validating them and passing them into other parts of the application becomes a hassle (i.e. where I find myself now). What if you are using the Knp Menu Bundle to build your sidebar and you want parts to be marked as .current based on query string parameters? There is no functionality for that, just functionality to integrate with Symfony2 routes.
And how to validate that your query string parameters are acceptable? I am currently looking at validating them like a form to then pass them into the database to generate a query. Maybe this is the way the Symfony2 team envisioned handling them? If so I'd just really like to know why. It feels like I'm fighting the application.
I ended up actually asking Fabien this question at Symfony Live San Francisco 2012. There was another talk at the same conference in regards to this question and I will share with you the slides here:
http://www.slideshare.net/Wombert/phpjp-urls-rest#btnNext
Basically in the slides you can see that the author agrees with me in that query string parameters should be used for filtering. What they should not be used for is determining a content source. So a route should point to a product (or whatever) and query string parameters should then be used in your controller to apply whatever logic you require to filter that content source (as per Fabien).
I ended up creating an entity in my application that I bind all my query string parameters to and then manipulate, much the same way forms are handled. In fact when you think about it it's basically the same thing.
Like in Symfony1, query strings are independent from the route parameters.
If you have a path defined as #Route("/page/{id}", name="single_page"), you can create a path in your view like this:
{{ path('single_page', { id: 3, foo: "bar" }) }}
The resulting URL will be /page/3?foo=bar.

ASP.net Routing - using database queries in order to determine the physical file, and add extra route data from query results

My question is regarding Page Routing in an ASP.net (VB) Web Forms website.
I need to route to 2 .aspx pages in multiple ways e.g.
routes.MapPageRoute("SEO", "{Title}/{Id}", "~/PageA.aspx")
routes.MapPageRoute("Catalogue", "Issue{IssueNumber}-{PageNumber}", "~/PageA.aspx")
but I need to implement some logic involving database queries (LINQ to SQL) on both routes e.g.
Route 1) Check a bit field, if false then physical file = PageA.aspx, true then PageB.aspx
Route 2) Lookup IssueNumber and PageNumber, retrieve PageId and add to RouteData, set physical file = PageA.aspx
I think the best way of doing this, is to implement an IRouteHandler class but I've not been able to determine:
Where to write the database queries in such class
How to set the physical file in the class
Where/how to add a new value to the route data i.e. PageId
Where to check that Id and Number fields are actually integers (constraints?)
I can't find any useful VB.net documentation, any suggestions?
If not I'm going to have to resort to an intermediate .aspx page i.e. Transfer.aspx and then do the database queries and then store return values in session variables and then do a Server.Transfer(PageA.aspx), but this seems like an old-fashioned and inelegant way of doing it. Please help!
Instead of writing your own IRouteHandler I'd suggest implementing your Route class. Override GetRouteData and setup the RouteData object that you return according to your needs.
Where to write the database queries in such class
As mentioned above, GetRouteData is the place you are looking for.
How to set the physical file in the class
On the RouteData object you return, set RouteHandler to a new PageRouteHandler instance. You can pass the physical path to PageRouteHandler's constructor.
Where/how to add a new value to the route data i.e. PageId
Use the Values property of the RouteData object.
Where to check that Id and Number fields are actually integers (constraints?)
This should be done with route constraints. The sixth parameter to MapPageRoute for example is a RouteValueDictionary with contraints. To simple check that a parameter is an integer, use a regular expression, like so:
routes.MapPageRoute("RouteName", _
"product/{id}", "~/Products.aspx", _
True, New RouteValueDictionary(), _
New RouteValueDictionary() From { {"id", "\d+"} })
See the "\d+" at the end? This is the regular expression that the id parameter needs to match.
If you need more complex constraints you can do that as well, see e.g. http://stephenwalther.com/blog/archive/2008/08/07/asp-net-mvc-tip-30-create-custom-route-constraints.aspx

What's the difference between Request() and Request.Form()?

Been working on a classic asp page. I've been using Request.Form("x") and saw that I can also use Request("x") to accomplish the same result.
What is the difference between the two? If they're the same I'll just use the later as it saves me some typing :)
The HttpRequest.Item property will search for the specified key in the QueryString, Form, Cookies, or ServerVariables collections.
The HttpRequest.Form property will only search among form variables.
Related resources:
HttpRequest Class
Request.Form(x) will check only the posted data whereas Request(x) checks the query string as well.

How to create a unique web page address in ASP.NET

Is there a standard way to create unique web page address in ASP.NET? I'm sending surveys to customers and will be including a link to the web page. For example:
http://www.mysurveypages.foo/survey/UniqueID
I would then customize the survey based on who I sent it to. I know it can be done by passing in a unique parameter to a page but I curious about doing it this way.
You can use Routing to map your url structure onto a particular page and parameter collection. Essentially, it allows you to convert parts of the url into url parameters for your page. This works in standard WebForms and is the basis upon which MVC chooses the appropriate controller/action signature to invoke.
Yup like dcp said GUID is a reasonable solution http://mywebsite.com/survey.aspx?ID=GUID
Suppose you are going to sent the survey to a list of users.
List<User> users = GetSurveyUsers();
foreach(User u in users)
{
Guid guid = Guid.NewGuid();
//Then store the user-guid pair into DB or XML...
}
The simplest solution would seem to be making UniqueID an incrementing field that can be used to get the appropriate user information out of the database. You could use numbers, or a Guid, or some alpha-numeric value, it really doesn't matter.
If you go with ASP.Net MVC then it is quite easy to map the Url (like the one you specified) to a controller action which gets the ID passed in as a parameter. Otherwise you will probably want to look into some sort of Url rewriting to make sure the Url can be nice and pretty.
A GUID approach is safest, if you're able to store it somewhere. If not you could use some existing unique data (e.g. customer id or email address) either directly (but be careful about leaking sensitive data) or hashed (but need to consider collisions).

Resources