Xdocument.Load(XMLReader.Read()) Is giving me erros - asp.net

I am trying to load a document see the code below
try
{
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
XmlReader responseReader = XmlReader.Create(response.GetResponseStream());
XDocument docs = XDocument.Load(responseReader.Read());
The above line is telling me xdocument.Load has some invalid arguments.
//XDocument docs = XDocument.Load(response.GetResponseStream());
This line is not loading anything Docs is empty
XDocument docs = XDocument.Load(responseReader);
This line is not giving any overload errors but returning nothing.
List<string> books = docs.Descendants("Test")....."Remaining QQuery"

Change
XDocument docs = XDocument.Load(responseReader.Read());
to
XDocument docs = XDocument.Load(responseReader);
The method for XDocument will accept an XmlReader which is what responseReader is, however you are calling the .Read() method on which only returns a boolean which is why you are getting that error.

Firstly, you almost had it without the XmlReader; you can't load the response straight into the XDocument, but, most of the time you can do:
XDocument docs = XDocument.Load(new StreamReader(response.GetResponseStream()));
Then check docs.Nodes.Count.
If docs is still empty, it's time to look at the response itself. Look at the response.ContentType - what is it?
Assuming the response isn't too large, look at it! You can do:
StreamReader reader = new StreamReader(response.GetResponseSteam());
string text = reader.ReadToEnd();
You can dump that string anywhere. Alternatively, if it is very big, you can save the response to disk, using either a FileStream with your Response, or, more simply WebClient.DownloadFile(url, path_to_save)
Either should be good enough to get you one step closer.

Related

Reading posted JSON data in ASP.NET

I subscribe to a mass email service which, when an error occurs at their end, posts to a page on my website as an endpoint to notify me that an email has bounced.
They describe it as follows:
The event data is sent in the POST request body using a JSON object.
What I need to know is how can I capture the info posted to me?
Currently I'm pointing them to a generic handler, a .ashx page, this can be changed to whatever as long as it's in .NET.
In 10 years working with first classic ASP and now .NET I've never done this before and I must admit I don't even know where to start.
This is the code I used to achieve a similar thing - not sure where I got it originally.
C#
var strJSON = String.Empty;
context.Request.InputStream.Position = 0;
using (var inputStream = new StreamReader(context.Request.InputStream))
{
strJSON = inputStream.ReadToEnd();
}
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
object serJsonDetails = javaScriptSerializer.Deserialize(strJSON, typeof(object));
// go and process the serJsonDetails object
or VB
Dim strJSON = [String].Empty
context.Request.InputStream.Position = 0
Using inputStream = New StreamReader(context.Request.InputStream)
strJSON = inputStream.ReadToEnd()
End Using
Dim javaScriptSerializer As New JavaScriptSerializer()
Dim serJsonDetails As Object = javaScriptSerializer.Deserialize(strJSON, GetType(Object))
' go and process the serJsonDetails object
You could just read the Request stream (Request.GetRequestStream) and use Json.NET to deserialize to an object.
You could use MVC4 and the built in object mapping.
There's many options. Perhaps you should read up on them more so that you have an idea of their capabilities and drawbacks.
Probably Request.Form (here) will help you get the JSON, if you know the content of the post, and then you need something like json.net library to get the object, or you can simply search the string using regex or keywords
Or if you can direct the post to a web service(asmx) instead of a web page, those services will parse the json for you
If you need to read raw post data twice or many times, i advice you to use this code.
string postBodyJson = null;
MemoryStream ms = new MemoryStream();
Request.InputStream.Position = 0;
Request.InputStream.Seek(0, SeekOrigin.Begin);
Request.InputStream.CopyTo(ms);
ms.Position = 0;
ms.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(ms))
{
postBodyJson = reader.ReadToEnd();
}

Need Help in converting Classic ASP Code to ASP.NET code

Set xml = Server.CreateObject("Microsoft.XMLHTTP")
xml.Open "GET", "http://www.indexguy.com/request_server.cfm?member_id=15893&id="+request.querystring("id")+"&"+request.querystring, False
xml.Send
How can I build the querystring parameter to a string object in C#/VB.NET
"member_id=15893&id="+request.querystring("id")+"&"+request.querystring"
If you are looking to build a querystring, String.Format("{0}", arg) might be a cleaner method to construct it.
For ASP.NET, you're going to want to replace the Server.CreateObject("Microsoft.XMLHTTP") with HttpWebRequest.
As for building the query string, that's still identical. You can still retrieve query string parameters by indexing into Request.QueryString. If you're using C# you can keep the + for string concatenation but might be more acceptable to use & in VB.
In ASP.NET the Page class exposes a Request property which provides access to a QueryString property - this is a NameValueCollection that lets you get values out in much the same way as in your existing example, by specifying keys:
var id = Page.Request.QueryString("id");
var newQuery = string.Format("?member_id=15893&id={0}&", id);
The above can easily be expanded to build more into your required query string.
As for the request you're initiating, that can be achieved using a WebRequest instance; to alter the sample from MSDN only slightly, here is an example:
WebRequest request = WebRequest.Create(yourUrl + newQuery);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Response.Write(response.StatusDescription);
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader (dataStream);
string responseFromServer = reader.ReadToEnd();
Response.Write(responseFromServer);
reader.Close();
dataStream.Close();
response.Close();

XPath with string or XmlDocument

I'm having trouble parsing the xml returned from a web service because it's really just a string. The web service doesn't contain any method to submit the request, nor an object to handle the response, so I'm just getting the xml as a string and trying to parse it to properties in an object I've created.
I was messing around with XPath, but I'm unable to figure out how to use a string, or an XmlDocument object with Xpath. I don't have an actual xml file, just a string that I've used to create an XmlDocument object.
private void SetProperties(string _xml)
{
XmlDocument _doc = new XmlDocument();
_doc.LoadXml(_xml);
}
Any ideas as to how I can query that XmlDocument object with XPath?
SelectNodes or SelectSingleNode is a good place to start. There are examples on those pages of selecting/querying node lists from an XmlDocument.
Have you tried calling the various methods on the XmlDocument object? For example, the SelectSingleNode method takes an xpath string and returns an xmlNode.
Also, check this site for additional information: http://www.w3schools.com/
You can create a new XPathExpression object which you then do a select against the XDoc with it. Adding onto the XDocument load code you started with:
XmlDocument _doc = new XmlDocument();
_doc.LoadXml(_xml);
XPathNavigator navigator = _doc.CreateNavigator();
XPathExpression expression = navigator.Compile("/foo/bar");
XPathNodeIterator iterator = navigator.Select(expression);
while (iterator.HasNext()) {
//Do Something With iterator.Current.Value;
}

ASP.NET: BOM in Server.Execute()

I'm using this to write to the Response stream:
using (var writer = new StringWriter())
{
context.Server.Execute(virtualpath, writer);
string s = writer.ToString().Replace(...);
context.Response.Write(s);
}
But I'm getting a byte order mark in the response. Am I screwing up the encoding? How do I NOT return the BOM?
EDIT: SOrry Rubens, my first example was incorrect.
Try this:
context.Server.Execute(virtualpath, context.Response.Output);
EDIT: So, try this to force your encoding:
MemoryStream ms = new MemoryStream();
StreamWriter writer = new StreamWriter(ms);
context.Server.Execute(virtualpath, writer);
context.Response.Write(Encoding.UTF8.GetString(ms.ToArray()).Replace(...));
Server.Execute() returns an encoded stream, but StringWriter() is intended to store simple .NET strings (which are 16-bit Unicode and don't have a BOM) and doesn't know how to decode the incoming bytes. So, the BOM in the response becomes literal characters in your string.
Try writing to a MemoryStream() instead, then decode that back into a string using whichever encoding (UTF-8 or whatever) that the Server.Execute() is passing back. Then you can parse it and write it back to your Response.

How can I make a VERY simple web proxy using ASP.NET?

I'm about to launch a site that was working well until I found the following hiccup:
I can't request a Yahoo! Pipe over SSL.
So the pages that require SSL are now missing a piece of their functionality unless I figure out a way around this; obviously, this could be done if I use an SSL-hosted page on my app to request the Yahoo! pipe for me.
I've seen solutions like http://www.iisproxy.net/license.html, but it seems to be a bit heavy for what I'm trying to do.
Can't I do this with a simple ASHX handler? Or is it more complex than that?
Thank you,
Michael
Thank you, John -- in case it's helpful to anyone else, here's the code I'm using in my ASHX file:
public override void ProcessRequest(HttpContext context)
{
var strURL = context.Server.UrlDecode(context.Request["url"]);
WebResponse objResponse = default(WebResponse);
WebRequest objRequest = default(WebRequest);
string result = null;
objRequest = HttpWebRequest.Create(strURL);
objResponse = objRequest.GetResponse();
StreamReader sr = new StreamReader(objResponse.GetResponseStream());
result = sr.ReadToEnd();
//clean up StreamReader
sr.Close();
//WRITE OUTPUT
context.Response.ContentType = "application/json";
context.Response.Write(result);
context.Response.Flush();
}
However, I was getting a couple extra characters (as opposed to the version that came direct from Yahoo! Pipes), so I had to remove those before parsing the JSON.
I guess if all you want to do is read the contents of a request you could use a WebRequest & WebResponse
here are some details on using that
http://www.west-wind.com/presentations/dotnetWebRequest/dotnetWebRequest.htm

Resources