ASP.Net menu databinding encoding problem - asp.net

I have a menu where I bind data through:
XmlDataSource xmlData = new XmlDataSource();
xmlData.DataFile = String.Format(#"{0}{1}\Navigation.xml", getXmlPath(), getLanguage());
xmlData.XPath = #"/Items/Item";
TopNavigation.DataSource = xmlData;
TopNavigation.DataBind();
The problem is when my xml has special characters, since I use a lot of french words.
As an alternative I tried using a stream instead and using encoding to get the special characters, with the following code:
StreamReader strm = new StreamReader(String.Format(#"{0}{1}\Navigation.xml", getXmlPath(), getLanguage()), Encoding.GetEncoding(1254));
XmlDocument xDoc = new XmlDocument();
xDoc.Load(strm);
XmlDataSource xmlData = new XmlDataSource();
xmlData.ID = "TopNav";
xmlData.Data = xDoc.InnerXml;
xmlData.XPath = #"/Items/Item";
TopNavigation.Items.Clear();
TopNavigation.DataSource = xmlData;
TopNavigation.DataBind();
The problem I'm having now is that my data doesn't refresh when I change the path where the stream gets read.
When I skip through the code it does, but not on my page.
So the thing is either, how do I get the data te be refreshed? Or (which is actually preferred) how do I get the encoding right in the first piece of code?
Help is highly apreciated!
EDIT:
I tried the CDATA solution, however i'm working with attributes so it's not possible to specify an element in an attribute, my xml:
<?xml version="1.0" encoding="utf-8" ?>
<Items Text="">
<Item Text="Actualités>"/>
<Item Text="Matériau">
<Item Text="Arsenal"/>
<Item Text="Vêtements"/>
</Item>
<Item Text="Links"/>
</Items>
Any other ideas?

Try to wrap french words with <![CDATA[....]]> tag
In this case XML will not parse your special characters

I solved my problem.
I changed the encoding of my xml file in notepad++ to UTF8 instead of ANSI (default), and it solved the problem.
Thanks for replies anyway

Related

How to retrieve the xml element attribute name in asp.net

I need to retrieve the xml attribute values in asp.net. Here i cant retrieve data from xml. Can anybody help me. Thanks in advance.
this might help you ....
Here is how my XML looks like:
<?xml version="1.0" encoding="utf-8"?>
<CategoryList>
<Category>
<MainCategory ID="1">VC++</MainCategory>
<Description>A list of VC</Description>
<Active>Yes</Active>
</Category>
</CategoryList>
add the value of the element MainCategory to the drop down list. I used the SelectNodes function to get the values and stored it while iterating through a loop. This looked like this:
XmlNodeList nodes = xmlDoc.SelectNodes("/CategoryList/Category");
for(int i=0;i<nodes.Count;i++)
{
ddlMainCategory.Items.Add(new ListItem(
nodes.Item(i).ChildNodes[0].InnerText,
nodes.Item(i).ChildNodes[0].Attributes["ID"].Value
));
}

Very confused about how to parse xml with namespace prefixes

So, I need to be able to parse xml files that could include namespace prefixes. I've tried doing this with a sample file and it gives me back null when trying to get a nodelist, even when I specify a node that has no attribute prefixes.
I've been trying to research this and it keeps coming back to the fact that without the namespace prefix defined, it won't work, so I've added code that I thought would do this, but it's still giving the same results. Here's some code I've added:
protected void Page_Load(object sender, EventArgs e)
{
xml.Load(Server.MapPath("~/SomeLesson/imsmanifest.xml"));
populateBaseNodes();
}
private void populateBaseNodes()
{
treeViewMenu.Nodes.Clear(); // Clear any existing items
TreeNode treenode = new TreeNode();
treenode.Text = "organizations";
XmlNodeList baseNodeList;
string xmlns = xml.DocumentElement.Attributes["xmlns"].Value;
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("adlcp", "http://www.adlnet.org/xsd/adlcp_v1p3");
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
nsmgr.AddNamespace("imscp", "http://www.w3.org/2001/XMLSchema-instance");
nsmgr.AddNamespace("imsss", "http://www.w3.org/2001/XMLSchema-instance");
nsmgr.AddNamespace("schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
baseNodeList = xml.SelectNodes("/manifest/organizations/organization/item", nsmgr);
TextBox1.Text = baseNodeList.Count.ToString();
foreach (XmlNode xmlnode in baseNodeList)
{
TreeNode treeNodeCatalog = new TreeNode();
treeNodeCatalog.Text = xmlnode.Attributes["identifier"].Value;
treeNodeCatalog.SelectAction = TreeNodeSelectAction.Expand;
treeViewMenu.Nodes.Add(treeNodeCatalog);
}
treeViewMenu.CollapseAll();
}
(marc_s) Here's the XML in question that needs to be parsed:
<manifest identifier="Navigating_in_QuickBooks_-_Introduction_MANIFEST" version="1.3"
xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:imscp="http://www.imsglobal.org/xsd/imscp_v1p1"
xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3"
xmlns:imsss="http://www.imsglobal.org/xsd/imsss"
xsi:schemaLocation=" http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd
http://www.imsglobal.org/xsd/imsss imsss_v1p0.xsd
http://www.adlnet.org/xsd/adlcp_v1p3 adlcp_v1p3.xsd
http://www.adlnet.org/xsd/adlseq_v1p3 adlseq_v1p3.xsd
http://www.adlnet.org/xsd/adlnav_v1p3 adlnav_v1p3.xsd">
<metadata>
<!-- not relevant here ... -->
</metadata>
<organizations default="TOC1">
<organization identifier="TOC1">
<title>Navigating in QuickBooks - Introductory Lesson</title>
<item identifier="I_SCO0" identifierref="SCO0">
<title>Navigating in QuickBooks - Introductory Lesson</title>
</item>
</organization>
</organizations>
<resources>
<!-- not relevant here ... -->
</resources>
</manifest>
You're not showing us what your XML looks like - but two comments:
you don't need to add the xsi prefix, and I'm not sure what the schemaLocation prefix is supposed to do ....
when you've defined the schema prefixes, you also need to use those prefixes in your XPath, of course!
Again, not knowing what your XML structure looks like, I cannot really tell what you need - but something along the lines of:
baseNodeList = xml.SelectNodes("/adlcp:manifest/adlcp:organizations/adlcp:organization/imscp:item", nsmgr);
or whatever other XML namespace prefixes your source XML requires.
Update: seeing your XML makes it clearer: see the root node - it has a default XML namespace (the one with xmlns="...." and no explicit prefix):
<manifest identifier="Navigating_in_QuickBooks_-_Introduction_MANIFEST" version="1.3"
xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" <=== DEFAULT namespace!!!
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:imscp="http://www.imsglobal.org/xsd/imscp_v1p1"
xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3"
xmlns:imsss="http://www.imsglobal.org/xsd/imsss"
................>
That means: ALL your subsequent nodes that don't have a specific XML prefix will be in that default namespace.
Unfortunately, .NET XML parsing has problem with defining a default namespace without prefix - so my best solution is to create a namespace with a prefix for the default namespace, and then use it:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable);
// add default namespace, with a prefix for .NET
nsmgr.AddNamespace("ns", "http://www.imsglobal.org/xsd/imscp_v1p1");
baseNodeList =
xml.SelectNodes("/ns:manifest/ns:organizations/ns:organization/ns:item", nsmgr);
Do you get any results now??
In the XML you posted the default namespace controlling all of the elements in your sample file is:
xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"
This namespace does not define a prefix so you must add this namespace to your namespace manager using a blank prefix. I think you should be able to use this code to define the default namespace (using String.Empty to specify a blank prefix):
nsmgr.AddNamespace(String.Empty, "http://www.imsglobal.org/xsd/imscp_v1p1");

How to ignore comments when parsing xml in asp.net

Seems like this should be easy, but I'm not finding a simple configuration setting. Basically I have a page that will be parsing xml files that may have some comment tags in them. I'm loading it as an xml doc and looping through a particular node of the document and I'm running into problems because it's counting the comment as a child node. Any way to tell asp.net not to look at comments other than writing my own check for <!-- ?
If you use XmlNode, then that has a NodeType property. Ignore the nodes where that has a value of "Comment".
An XNode has the same property.
Use XmlReaderSettings.IgnoreComments:
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.IgnoreComments = true;
using (XmlReader reader = XmlReader.Create("input.xml", readerSettings))
{
XmlDocument myData = new XmlDocument();
myData.Load(reader);
// etc...
}

ISO-8859-1 to UTF8 in ASP.NET 2

We've got a page which posts data to our ASP.NET app in ISO-8859-1
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<title>`Sample Search Invoker`</title>
</head>
<body>
<form name="advancedform" method="post" action="SearchResults.aspx">
<input class="field" name="SearchTextBox" type="text" />
<input class="button" name="search" type="submit" value="Search >" />
</form>
and in the code behind (SearchResults.aspx.cs)
System.Collections.Specialized.NameValueCollection postedValues = Request.Form;
String nextKey;
for (int i = 0; i < postedValues.AllKeys.Length; i++)
{
nextKey = postedValues.AllKeys[i];
if (nextKey.Substring(0, 2) != "__")
{
// Get basic search text
if (nextKey.EndsWith(XAEConstants.CONTROL_SearchTextBox))
{
// Get search text value
String sSentSearchText = postedValues[i];
System.Text.Encoding iso88591 = System.Text.Encoding.GetEncoding("iso-8859-1");
System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
byte[] abInput = iso88591.GetBytes(sSentSearchText);
sSentSearchText = utf8.GetString(System.Text.Encoding.Convert(iso88591, utf8, abInput));
this.SearchText = sSentSearchText.Replace('<', ' ').Replace('>',' ');
this.PreviousSearchText.Value = this.SearchText;
}
}
}
When we pass through Merkblätter it gets pulled out of postedValues[i] as Merkbl�tter
The raw string string is Merkbl%ufffdtter
Any ideas?
You have this line of code:-
String sSentSearchText = postedValues[i];
The decoding of octets in the post has happen here.
The problem is that META http-equiv doesn't tell the server about the encoding.
You could just add RequestEncoding="ISO-8859-1" to the #Page directive and stop trying to fiddle around with the decoding yourself (since its already happened).
That doesn't help either. It seems you can only specify the Request encoding in the web.config.
Better would be to stop using ISO-8859-1 altogether and leave it with the default UTF-8 encoding. I can see no gain and only pain with using a restrictive encoding.
Edit
If it seems that changing the posting forms encoding is not a possibility then we seem to be left with no alternative than to handle the decoding ourselves. To that end include these two static methods in your receiving code-behind:-
private static NameValueCollection GetEncodedForm(System.IO.Stream stream, Encoding encoding)
{
System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.ASCII);
return GetEncodedForm(reader.ReadToEnd(), encoding);
}
private static NameValueCollection GetEncodedForm(string urlEncoded, Encoding encoding)
{
NameValueCollection form = new NameValueCollection();
string[] pairs = urlEncoded.Split("&".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (string pair in pairs)
{
string[] pairItems = pair.Split("=".ToCharArray(), 2, StringSplitOptions.RemoveEmptyEntries);
string name = HttpUtility.UrlDecode(pairItems[0], encoding);
string value = (pairItems.Length > 1) ? HttpUtility.UrlDecode(pairItems[1], encoding) : null;
form.Add(name, value);
}
return form;
}
Now instead of assigning:-
postedValues = Request.Form;
use:-
postValues = GetEncodedForm(Request.InputStream, Encoding.GetEncoding("ISO-8859-1"));
You can now remove the encoding marlarky from the rest of the code.
I think adding your encoding into web.config like that will probably solve your problem :
<configuration>
<system.web>
<globalization
fileEncoding="iso-8859-1"
requestEncoding="iso-8859-1"
responseEncoding="iso-8859-1"
culture="en-US"
uiCulture="en-US"
/>
</system.web>
</configuration>
We had the same problem that you have. The topic is not straight-forward at all.
The first tip is to set the Response encoding of the page that posts the data (usually the same page as the one that receives the data in .NET) to the desired form post encoding.
However, this is just a hint to the user's browser on how to interpret the characters sent from the server. The user might choose to override the encoding manually. And, if the user overrides the encoding of the page, the encoding of the data sent in the form is also changed (to whatever the user has set the encoding to).
There is a small trick, though. If you add a hidden field with the name _charset_ (notice the underscores) in your form, most browsers will fill out this form field with the name of the charset used when posting the form. This form field is also a part of the HTML5 specification.
So, you might think your're good to go, however, when in your page, ASP.NET has already urldecoded all parameters sent in to the form. So when you actually have the value in the _charset_ field, the value of the field containing Merkblätter is already decoded incorrectly by .NET.
You have two options:
In the ASP.NET page in question, perform the parsing of the request string manually
In Application_BeginRequest, in Global.asax, parse the request parameters manually, extracting the _charset_field. When you get the value, set Request.ContentEncoding to System.Text.Encoding.GetEncoding(<value of _charset_ field>). If you do this, you can read the value of the field containing Merkblätter as usual, no matter what charset the client sends the value in.
In either of the cases above, you need to manually read Request.InputStream, to fetch the form data. I would recommend setting the Response Encoding to UTF-8 to have the greatest number of options in which characters you accept, and then treating the special cases when the user has overridden the charset especially, as specified above.
Function urlDecode(input)
inp = Replace(input,"/","%2F")
set conn = Server.CreateObject("MSXML2.ServerXMLHTTP")
conn.setOption(2) = SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS
conn.open "GET", "http://www.neoturk.net/urldecode.asp?url=" & inp, False
conn.send ""
urlDecode = conn.ResponseText
End Function
To speed this up, just create a table on your db for decoded and encoded urls and read them on global.asa application.on_start section. Later put them on the application object.
Then put a check procedure for that application obj. in above function and IF decoded url not exists on app array, THEN request it one time from remote page (tip: urldecode.asp should be on different server see: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316451) and insert it to your db and append to application array object, ELSE return the function from the application obj.
This is the best method I have ever found.
If anybody wants further details on application object, database operations etc. contact me via admin#neoturk.net
You can see above method successfully working at: lastiktestleri.com/Home
I also used, HeliconTech's ISAPI_Rewrite Lite version
usage is simple: url = Request.ServerVariables("HTTP_X_REWRITE_URL")
this will return the exact url directed to /404.asp
That's because you are encoding the string as ISO-8859-1 and decoding it as if it was a string encoded as UTF-8. This will surely mess up the data.
The form isn't posting the data as ISO-8859-1 just because you send the page using that encoding. You haven't specified any encoding for the form data, so the browser will choose an encoding that is capable of handling the data in the form. It may choose ISO-8859-1, but it may just as well choose some other encoding.
The data is send to the server, where it's decoded and put in the Request.Form collection, according to the encoding that the browser specifies.
All you have to do is to read the string that has already been decoded from the Request.Form collection. You don't have to loop through all the items in the collection either, as you already know the name of the text box.
Just do:
string sentSearchText = Request.Form("SearchTextBox");
What I ended up doing was forcing our app to be in ISO-8859-1. Unfortunately the underlying data may contain characters which don't fit nicely into that codepage so we go through the data before displaying it and convert everything about the character code of 127 into an entity. Not ideal but works for us...
I had the same problem, solved like this:
System.Text.Encoding iso_8859_2 = System.Text.Encoding.GetEncoding("ISO-8859-2");
System.Text.Encoding utf_8 = System.Text.Encoding.UTF8;
NameValueCollection n = HttpUtility.ParseQueryString("RT=A+v%E1s%E1rl%F3+nem+enged%E9lyezte+a+tranzakci%F3t", iso_8859_2);
Response.Write(n["RT"]);
A+v%E1s%E1rl%F3+nem+enged%E9lyezte+a+tranzakci%F3t will return "A vásárló nem engedélyezte a tranzakciót" as expected.

How to get server side variable value in xsl template?

I want use localized strings from resources in xsl template as in aspx page, like this:
<%=GetLocalizedString("grid_numberof_claim")%>. I am trying use
<xsl:text disable-output-escaping="yes">
<![CDATA[<%=GetLocalizedString("grid_numberof_claim")%>]]>
</xsl:text>
but it is not useful.
Actually i can pass localized strings inside XML node, for example "localization". But i am looking for way to get its value in aspx style.
Using ASPX style isn't possible.
You can use XsltArgumentList to send parameters to your XSLT template, as explained here: HOW TO: Execute Parameterized XSL Transformations in .NET Applications
EDIT: Yes, you can pass arguments client-side too.
xmldoc = ... // your xml document
var xslt = new ActiveXObject("Msxml2.XSLTemplate.4.0");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.4.0");
xslDoc.async = false;
xslDoc.load("YourTemplate.xsl");
xslt.stylesheet = xslDoc;
xslProc = xslt.createProcessor();
xslProc.input = xmldoc;
xslProc.addParameter("param1", 123);
xslProc.addParameter("param2", "abc");
xslProc.transform();
But client-side leads to another solution: You can rename your XSLT file to ASPX and to use <%= %> syntax

Resources