3

What I'm trying to do is use an UriBuilder and HttpUtility.ParseQueryString to get the last page the user visited and then parse the URL to get just the productID. (The product ID is different on each page if that matters)

example URL: website.com/stuff/?referrerPage=1&productID=1234567&tab=Tile

and what I want is just the 1234567

Page_Load is where I parse the URL:

protected void Page_Load(object sender, EventArgs e) 
{ 
    NameValueCollection query = HttpUtility.ParseQueryString(uriBuilder.Query);
    //I want to take the parse string and get productID here, how?
} 

grabURL is where I get the last URL visited:

public grabUrl(string Uri) 
{ 
    UriBuilder uriBuilder = new UriBuilder(Request.UrlReferrer); 
    return uriBuilder.Uri; 
}

Am I on the right track with my code? How do I put the productID number in something so I can work with it? I'm very new to c# and this type of coding in general... when I say new I mean I've been doing it for about a week. So any detailed explanations or examples will be very much appriciated. Thanks everyone for being so helpful, I'm learning a lot from this site to get me on the right track.

JavaTheScript
  • 137
  • 3
  • 16
  • I don't really know what that means @Grant , could you explain please? thanks. – JavaTheScript May 10 '13 at 15:46
  • @JavaTheScript. I think Grant is asking why you have put the `string Uri` parameter into `Page_Load`. Normally `Page_Load` looks like this: `protected void Page_Load(object sender, EventArgs e)`. – Andy Brown May 10 '13 at 19:30
  • @JavaTheScript. Also, it is worth knowing about the [IsPostBack](http://msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx) property so you can decide to do work in Page_Load on first load, or on postbacks, but not both. – Andy Brown May 10 '13 at 19:31
  • @JavaTheScript. I'm adding a link to your original question so people can understand context a little better: http://stackoverflow.com/questions/16463786/find-the-referring-url-and-parse-it – Andy Brown May 10 '13 at 20:00

3 Answers3

2

From a NameValueCollection you can then do:

var id = query["ProductID"];

You can use int.TryParse to turn it into an integer proper.

int id = 0;
if (!string.IsNullOrEmpty(query["ProductID"]) && 
  int.TryParse(query["ProductID"], out id))  {
  // use id here..
}
Grant Thomas
  • 44,454
  • 10
  • 85
  • 129
1

Or you could just request the querystring value from your URL using Request.QueryString()

protected void Page_Load() 
{ 
    //save yourself the conversion to int and just save it as Int if you know for sure
    // it will always be int
    int _prodID= Request.Querystring["productID"];
    //validate _prodID
    if (!string.IsNullOrEmpty(_prodID.toString())) {//do something }
}
Marcianin
  • 461
  • 3
  • 8
  • Yeah It's always going to be an int. So I don't have to use NameValueCollection? I just use this piece instead and in the do something write code to only call the 7 numbers from the ProductID? – JavaTheScript May 10 '13 at 17:22
  • pretty much, this is the easiest way to solve your solution in my opinion. In the IF statement all you have to so id use the _prodID. How are you going to use this variable? are you going to enter it in a SQL statement? – Marcianin May 10 '13 at 17:55
  • I only use NameValueCollection when I dont know the names of the parameters sent on the Querystring, like when a user fills some textboxes on a form and some are left blank, I only send the ones that have values and with NameValueCollection I get the parameters and the Values, but if you now the name of the parameter you are looking for just requested it straight up – Marcianin May 10 '13 at 17:58
  • Oh yeah, I'm not doing anything like that. Basically I need it to throw the product ID into a freight estimator when they click the freight estimator button. The "button" takes them to a different website so I needed to retrieve the URL and parse the product ID out to do the calculations. – JavaTheScript May 10 '13 at 18:23
  • @Marcianin. For clarity: Are you parsing the uri of the current page request (in which case Request.Querystring is the way to go) or the "last page the user visited" as per your question (and in which case Request.Querystring may not work for you). – Andy Brown May 10 '13 at 18:26
  • The last page they visited. They are going to click a button on website1 which will take them to website2 (The one I am building) that will parse the productID out of the URL they came from and do calculations with it. – JavaTheScript May 10 '13 at 18:31
  • @JavaTheScript. If I've understood correctly then, Request.QueryString will work, and is the best approach if the productID is in the query string _of the current request you are dealing with_. But, your statement here is "_out of the URL they came **from**_" in which case you are talking about potentially using the URL in Request.UrlReferrer? It might be simpler to make sure your button link includes the productID in the website 2 url so you can use Request.QueryString. – Andy Brown May 10 '13 at 18:44
  • @AndyBrown. I guess I dont read questions literally and I just go straight for what I think the situation needs. when he explained the process he is utilizing I was assuming he is building some type of shopping cart that will send the user to a processing page with the itemID in the URL (which he then ratifies on his reply about the freight estimator) so I think he is talking about the current request, he will grab the parameter from the current URL and process it in the current page to display the calculation. – Marcianin May 10 '13 at 18:54
  • @Marcianin. Totally agree. If that is the case your solution is by far the best one (though you'll need the edit I've suggested). – Andy Brown May 10 '13 at 19:34
0

Could you use a regex to parse it instead?

string uri = "website.com/stuff/?referrerPage=1&productID=1234567&tab=Tile";
var rgx = new Regex("productID=(?<pid>[0-9]+)", RegexOptions.IgnoreCase);
string pid = rgx.Match(uri).Groups[1].Value;

Edit: Providing context as it has been suggested I should do:

The reason for mentioning this option is that while it doesn't use HttpUtility.ParseQueryString, your original question was very specific:

get just the productID

from

the last page the user visited

(which I understand to not be the uri of the current request). Additionally you provided the Uri was provided in a string format.

The approach in your question does this:

  • Takes Uri (a string variable)
  • Passes it to UriBuilder; UriBuilder in its constructor initialises a Uri, which itself does a ton of work to validate the uri, populate properties etc. by creating more strings, among other things
  • Then, from the Uri object generated, you now work with the Query property - this is one of the new strings that Uri has allocated
  • Passes that to HttpUtility.ParseQueryString. This creates a HttpValueCollection, which itself iterates character-by-character over the string you pass in to parse out the key-value pairs in the query string, and sticks them into a NameValueCollection, which ultimately stores your values in an ArrayList - one of the least efficient collections in .NET (see various references including this one - What's Wrong with an ArrayList?) as it stores everything in an object array, requiring casting every time you get things back out.
  • finally you then go and search that collection by a key to get your product id back out.

That's a whole lot of string and character allocations, casting to and from objects, putting things into indexed arrays which you then scan, etc. just to get:

  • a string which is identifiable by a pattern from another string.

While I admit that memory is cheap, it seems that there might be an equally good, or better, alternative. This is what regex was made for - find a pattern in a string, and allow you to get parts of that pattern back out.

So, your options:

  1. If you just want to get productID out of a uri in an exact form, and the uri is originally in a string, then I maintain that a regex is a very good, efficient choice. This will also work if you want to extract other patterns from your uri.
  2. If you want to know all the keys in your query string as well as values for specific keys, then use your HttpUtility.ParseQueryString approach; NameValueCollection allows you to get access to the keys through the AllKeys property.
  3. If you want to get the value of a query string parameter for the uri of your current request then Marcianin's answer is the simplest choice, and you can forget the first 2 options.

In all cases, once you have the string you can parse it using the parse methods on int, but if you use 2. or 3. your extracted id may not be a number (in the case of a malicious request) so make sure you use int.TryParse not int.Parse to convert from a string, and be careful to catch exceptions. You should always take care when taking input from query strings so as not to fall foul of malicious data in the query string (which will hit your website frequently once it is online).

The choice is personal preference.

  • The actual code you write is about the same - each approach takes up very few lines.
  • Code should never prematurely optimise, but it should also not be deliberately wasteful if it can help it. You could performance test one against the other, but that would be a waste of your time at this stage.
  • However, code should also convey intent. The Regex approach, even I would argue, doesn't convey your intent as well as the ParseQueryString approach.

Footnote: I would change the regex slightly to "[?&]productID=(?<pid>[0-9]+)" to ensure you pick up only "productID" and not "fooProductID"

Most importantly, you asked

Am I on the right track with my code?

I would say you are. Always weigh up different options as you proceed. Don't be afraid to try different things out. You say you are new to C#. The one thing you may have missed, in this case, is writing a test to help you on your way before you wrote your code: if the test passes, the code is correct, and the approach you chose is secondary to that. Visual Studio makes testing easy for you if you are using the latest version. If you get into good habits early on, it will pay dividends later on in your C# career.

How do I put the productID number in something so I can work with it?

Grant Thomas answered this perfectly - int.TryParse turns the string into a number.

Community
  • 1
  • 1
Andy Brown
  • 18,961
  • 3
  • 52
  • 62
  • Interested to know why the downvote - so I can learn for future answers. – Andy Brown May 10 '13 at 14:57
  • 1
    Regex, bad idea for this, and concerning that it's what comes to mind, for anybody. – Grant Thomas May 10 '13 at 18:22
  • @GrantThomas. Thank you, are you sure though? The exact scenario was "get just the productID" from "the last page the user visited ". UriBuilder -> HttpUtility.ParseQueryString does string -> object -> dictionary -> value retrieval for a key -> string. Regex does string -> string. Isn't that more succinct and efficient? – Andy Brown May 10 '13 at 18:32
  • I think there are better solutions than Regex when you want to query for a value in this situation. Like the one proposed by @GrantThomas (but I would have not given you a down vote though, maybe just a simple explanation) – Marcianin May 10 '13 at 18:57
  • @Marcianin. I suspect you are correct, the reason for the alternative was to highlight that for the specific scenario mentioned, there are other options. – Andy Brown May 10 '13 at 19:26
  • Thank you so much @AndyBrown for taking the time to write this! I appreciate it so much. ^__^ I don't have enough rep to up vote it but as soon as I do I will be back to do that ha. Seriously thank you that explained so much and so well. – JavaTheScript May 13 '13 at 13:15