views:

1021

answers:

9

In my asp.net mvc page I create a link that renders as followed:

http://localhost:3035/Formula/OverView?colorId=349405&paintCode=744&name=BRILLANT%20SILVER&formulaId=570230

According to the W3C validator, this is not correct and it errors after the first ampersand. It complains about the & not being encoded and the entity &p not recognised etc.

AFAIK the & shouldn't be encoded because it is a separator for the key value pair.

For those who care: I send these pars as querystring and not as "/" seperated values because there is no decent way of passing on optional parameters that I know of.

--EDIT--
To put all the bits together:

  • an anchor (<a>) tag's href attribute needs an encoded value
  • & encodes to &amp;
  • to encode an '&' when it is part of your parameter's value, use %26
A: 

& should be &amp;

EDIT: made it easier to read.

Kyle West
Tom
+2  A: 

The HTML source should have those ampersands encoded to &amp;

Michael Haren
+4  A: 

Entities which are part of the attributes should be encoded, generally. Thus you need &amp; instead of just &

It works even if it doesn't validate because most browsers are very, very, very lenient in what to accept.

In addition, if you are outputting XHTML you have to encode every entity everywhere, not just inside the attributes.

Vinko Vrsalovic
You need to encode every entity in all HTML documents (with a few exceptions, such as inside script tags). Setting the doctype to XHTML will not cause his page to validate.
Illandril
I didn't mean that changing doctype to XHTML would fix it, but, as you are right that entities inside attributes should be encoded in all HTML variations, I changed the answer to reflect that.
Vinko Vrsalovic
+1  A: 

All HTML attributes need to use character entities. You only don't need to change & into &amp; within script blocks.

<a href="http://localhost:3035/Formula/OverView?colorId=349405&amp;amp;paintCode=744&amp;amp;name=BRILLANT%20SILVER&amp;amp;formulaId=570230"&gt;Whatever&lt;/a&gt;

Anywhere in an HTML document that you want an & to display directly next to something other than whitespace, you need to use the character entity &amp;. If it is part of an attribute, the &amp; will work as though it was an &. If the document is XHTML, you need to use character entities everywhere, even if you don't have something immediately next to the &. You can also use other character entities as part of attributes to treat them as though they were the actual characters.

If you want to use an ampersand as part of a URL in a way other than as a separator for parameters, you should use %26.

As an example...

<a href="http://localhost/Hello?name=Bob&amp;amp;text=you%20%26%20me%20&amp;quot;forever&amp;quot;"&gt;Hello&lt;/a&gt;

Would send the user to http://localhost/Hello, with name=Bob and text=you & me "forever".

Illandril
except for the slimy example, thx for the detailed info ;)
borisCallens
I couldn't think of anything better at the time that had a good reason to use spaces, an ampersand, and another character entity :)
Illandril
A: 

If I understand what you want to do and you have

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

in your Global.asax (which is the default), then you may just need to change around your RegisterRoutes().

Pyrolupus
A: 

Wouldn't encoding the ampersand into & make it part of my parameter's value? I need it to seperate the second variable from the first

borisCallens
This post is referring to Illandril's post. It should have been a comment to that post.
Tom
Illandril
+1  A: 

This is a slightly confusing concept to some people, I've found. When you put &amp; in a HTML page, such as in <a href="abc?def=5&amp;ghi=10">, the URL is actually abc?def=5&ghi=10. The HTML parser converts the entity to an ampersand.

Think of exactly the same as how you need to escape quotes in a string:

// though you define your string like this:
myString = "this is \"something\" you know?"

// the string is ACTUALLY: this is "something" you know?

// when you look at the HTML, you see:
<a href="foo?bar=1&amp;baz=2">

// but the url is ACTUALLY: foo?bar=1&bar=2
nickf
I did know that, but the Asp.net MVC HTML helper generated this code for me so I presumed it was correct.I'll have to look into it when I'm at work again (damn, just checked the clock, work's in 4 hours, better go to sleep)
borisCallens
now I think of it, you're probably right. I think I got things mixed up there...
borisCallens
A: 

@nickF I checked what you said and indeed, by encoding my href value, I get rid of the errors. What I'm wondering now however is what to do if for example my colorId would be "123&456", where the ampersand is part of the value. Since the separator has to be encoded, what to do with encoded ampersands. Do they need to be encoded twice so to speak?

So to get the url:

www.mySite.com/search?query=123&amp;456&page=1

What should my href value be?

Also, I think I'm about the first person in the world to care about this.. Go check the www and count the pages that get their query string validated in the W3C validator..

borisCallens
Tom
A: 

Instead of encoding manually, use HttpUtility.HtmlAttributeEncode.

orip