How to view contents of HTMLTextWriter? - asp.net

I have an HtmlTextWriter object (theWriter) being passed into a method. This method is in the middle tier. I'd like to read the contents of the theWriter in debug mode. The method is:
protected override void Render (HtmlTextWriter theWriter) {...}
which inherits from Panel:WebControl.
I've tried
theWriter.Flush();
theWriter.InnerWriter.ToString();
but that only outputs the object type: "System.Web.HttpWriter". I've seen some examples use methods on the Response object. But I don't have access to Response in this layer. Any ideas?

The InnerWriter is a TextWriter-derived class, which writes to a stream. You will have to open that stream and read data from it. Whether you can open and read from that stream is an open question, and depends very much on what type of stream it is.
So to use your example, theWriter.InnerWriter is an object derived from TextWriter. But you don't know what kind, and TextWriter itself doesn't expose the underlying stream.
Now, if InnerWriter is a StreamWriter, then you might be able to write:
var sWriter = theWriter.InnerWriter as StreamWriter;
var stream = sWriter.BaseStream;
var savePosition = stream.Position;
stream.Position = 0;
// now, you can read the stream
// when you're done reading the stream, be sure to reset its position
stream.Position = savePosition;
You have to be very careful, though. If you get the base stream and then open it with a StreamReader, closing the StreamReaderwill close the underlying stream. Then your HtmlTextWriter will throw an exception the next time you try to write to it.
It's also possible that you won't be able to read the stream. If the base stream is a NetworkStream, for example, you can't read it. Or it could be a FileStream that was open for write only. There's no good general way to do this, as it entirely depends not only on the specific TextWriter-derived class, but also on the stream that the TextWriter is writing to.
For example, the HtmlTextWriter could be writing to a StreamWriter, which is connected to a BufferedStream connected to a GZipStream, which finally writes to a MemoryStream.
So, in general, I'd recommend that you look for some other solution to your problem. Unless you know for sure what the underlying stream is, and that you can read it ... and that things won't change on you unexpectedly.

Related

Progress while deserializing JSON

I'm deserializing a huge JSON (1.4 GB) via a stream, because I don't want to load the whole content into memory in advance just for parsing. That's working fine, but it takes ~80 seconds, so I want to display a progress.
public JObject DeserializeViaStream(string filename)
{
object obj;
var serializer = new JsonSerializer();
using (var sr = new StreamReader(new FileStream(filename, FileMode.Open)))
{
using (var jsonTextReader = new JsonTextReader(sr))
{
obj = serializer.Deserialize(jsonTextReader);
}
}
return (JObject) obj;
}
I have not yet tried but only one idea: I could implement my own stream reader which keep track of the bytes being read and comparing that to the file length.
Is there a built-in option or easier way to do this?
I ended up using the idea I had. Luckily there's already a ProgressStream available by Mel Green (archive.org). The original URL is no longer available.
Please note:
this approach may not work for all situations and with all libraries forever. This is due to the fact that the Seek() operation provides random access, and someone could read the file multiple times.
I can't post the source code here, because it was released under an unclear license.

Read Request Body in ASP.NET

How does one read the request body in ASP.NET? I'm using the REST Client add-on for Firefox to form a GET request for a resource on a site I'm hosting locally, and in the Request Body I'm just putting the string "test" to try to read it on the server.
In the server code (which is a very simple MVC action) I have this:
var reader = new StreamReader(Request.InputStream);
var inputString = reader.ReadToEnd();
But when I debug into it, inputString is always empty. I'm not sure how else (such as in FireBug) to confirm that the request body is indeed being sent properly, I guess I'm just assuming that the add-on is doing that correctly. Maybe I'm reading the value incorrectly?
Maybe I'm misremembering my schooling, but I think GET requests don't actually have a body. This page states.
The HTML specifications technically define the difference between "GET" and "POST" so that former means that form data is to be encoded (by a browser) into a URL while the latter means that the form data is to appear within a message body.
So maybe you're doing things correctly, but you have to POST data in order to have a message body?
Update
In response to your comment, the most "correct" RESTful way would be to send each of the values as its own parameter:
site.com/MyController/MyAction?id=1&id=2&id=3...
Then your action will auto-bind these if you give it an array parameter by the same name:
public ActionResult MyAction(int[] id) {...}
Or if you're a masochist you can maybe try pulling the values out of Request.QueryString one at a time.
I was recently reminded of this old question, and wanted to add another answer for completeness based on more recent implementations in my own work.
For reference, I've blogged on the subject recently.
Essentially, the heart of this question was, "How can I pass larger and more complex search criteria to a resource to GET a filtered list of objects?" And it ended up boiling down to two choices:
A bunch of GET query string parameters
A POST with a DTO in the request body
The first option isn't ideal, because implementation is ugly and the URL will likely exceed a maximum length at some point. The second option, while functional, just didn't sit right with me in a "RESTful" sense. After all, I'm GETting data, right?
However, keep in mind that I'm not just GETting data. I'm creating a list of objects. Each object already exists, but the list itself doesn't. It's a brand new thing, created by issuing search/filter criteria to the complete repository of objects on the server. (After all, remember that a collection of objects is still, itself, an object.)
It's a purely semantic difference, but a decidedly important one. Because, at its simplest, it means I can comfortably use POST to issue these search criteria to the server. The response is data which I receive, so I'm "getting" data. But I'm not "GETting" data in the sense that I'm actually performing an act of creation, creating a new instance of a list of objects which happens to be composed of pre-existing elements.
I'll fully admit that the limitation was never technical, it was just semantic. It just never "sat right" with me. A non-technical problem demands a non-technical solution, in this case a semantic one. Looking at the problem from a slightly different semantic viewpoint resulted in a much cleaner solution, which happened to be the solution I ended up using in the first place.
Aside from the GET/POST issue, I did discover that you need to set the Request.InputStream position back to the start. Thanks to this answer I found.
Specifically the comment
Request.InputStream // make sure to reset the Position after reading or later reads may fail
Which I translated into
Request.InputStream.Seek(0,0)
I would try using the HttpClient (available via Nuget) for doing this type of thing. Its so much easier than the System.Net objects
Direct reading from the Request.InputStream dangerous because when re-reading will get null even if the data exists. This is verified in practice.
Reliable reading is performed as follows:
/*Returns a string representing the content of the body
of the HTTP-request.*/
public static string GetFromBodyString(this HttpRequestBase request)
{
string result = string.Empty;
if (request == null || request.InputStream == null)
return result;
request.InputStream.Position = 0;
/*create a new thread in the memory to save the original
source form as may be required to read many of the
body of the current HTTP- request*/
using (MemoryStream memoryStream = new MemoryStream())
{
request.InputStream.CopyToMemoryStream(memoryStream);
using (StreamReader streamReader = new StreamReader(memoryStream))
{
result = streamReader.ReadToEnd();
}
}
return result;
}
/*Copies bytes from the given stream MemoryStream and writes
them to another stream.*/
public static void CopyToMemoryStream(this Stream source, MemoryStream destination)
{
if (source.CanSeek)
{
int pos = (int)destination.Position;
int length = (int)(source.Length - source.Position) + pos;
destination.SetLength(length);
while (pos < length)
pos += source.Read(destination.GetBuffer(), pos, length - pos);
}
else
source.CopyTo((Stream)destination);
}

Dispose a stream in a BizTalk pipeline component?

I'm fairly new to BizTalk and creating a custom pipeline component. I have seen code in examples that are similar to the following:
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
{
Stream originalDataStream = pInMsg.BodyPart.GetOriginalDataStream();
StreamReader strReader = new StreamReader(originalDataStream);
string strOriginalData = strReader.ReadToEnd();
byte[] bufferOriginalMessage = new byte[strOriginalData.Length];
bufferOriginalMessage = ASCIIEncoding.Default.GetBytes(strOriginalData);
Stream ms = new MemoryStream();
ms.Write(bufferOriginalMessage, 0, strOriginalD
//other stuff here
ms.Seek(0, SeekOrigin.Begin);
pInMsg.BodyPart.Data = ms;
}
But nowhere in the method is the StreamReader being closed or disposed. The method simply exits.
Normally when using StreamReader and other classes, it is best practice to use a using statement so that the stream is automatically disposed.
Is there a particular reason (perhaps in BizTalk) why you wouldn't dispose this StreamReader?
I have not found any information on this point. Can anyone help?
In general, yes, it's a good practice to close readers and streams you don't need anymore. That said, there might not necessarily be 100% required everytime. For example, closing the reader would close the underlying stream normally, but chances are, something else is probably already aware of the stream and will close it at the right time on it's own.
What is good practice, however, is to add any streams you use in a pipeline component with a lifetime matching that of the message to the resource tracker, so that BizTalk can dispose them automatically when the pipeline execution finishes and the message has been processed.

Issue using SocketConnection with a Blackberry using MDS

I am currently writing an app on the Blackberry to do a simple send and receive of some raw data to another TCP based device on my network. I am having the same problem in the Blackberry simulator w/ an MDS simulator running and using a physical phone talking to my company's MDS server. Note this problem does not happen when using wifi directly and not via MDS.
The problem is that the available() function on the InputStream returns zero unless I call read() first. If I call read first (knowing there is some data available .. thank you wireshark) the data comes back, and the subsequent call to available() indicates what data is left that I did not read. The problem is that I am not always going to be guaranteed that data will be there and so I could block. Is anyone aware of this, and is this a problem or something that is by design?
Is anyone aware of a way to test if the read() method(s) will block before calling them aside from available?
Here is basically what I am doing:
SocketConnection s = (SocketConnection)Connector.open("socket://1.2.3.4:port;deviceside=false", Connector.READ_WRITE);
OutputStream o = ((StreamConnection)s).openOutputStream();
InputStream i = ((StreamConnection)s).openInputStream();
o.write("hello");
Thread.sleep(sometime);
if (i.available() > 0) {
byte[] data = new data[10];
int bytesRead = i.read(data);
System.out.println("Read [" + new String(data) + "] (bytes = " + bytesRead + ")");
}
I have to comment out the if conditional for this to work.
The general contract of the InputStream.available() method is that it "Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream." Hence in most implementations, it is no guarantee that it will return the Content Length of the stream that is being read. Hence it is better to read it in the following way
byte[] readFromStream(InputStream is) throws IOException
{
byte[] data = new byte[4096];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
int count = is.read(data, 0, data.length);
while (count != -1)
{
dos.write(data, 0, count);
count = is.read(data, 0, data.length);
}
data = baos.toByteArray();
return data;
}
You call the readFromStream() method and get the byte[] returned.
As I indicated in a comment above, I needed a way to determine if a device I am connecting to is not there, and I do that by seeing if our 'ping' returns any data. If the device is not there it will block. I cannot rely on that behavior. Another issue that crept up while solving this is that the read(...) methods of the RIM InputStream class block if you provide a buffer bigger than the data you want back. But how am I supposed to know how much data is there if available() returns 0? Reading byte-by-byte is about the only way to do this, but it still blocks if there is no data.
To address this I followed the theme of the 1st answer, but I put this method on its own thread and had it write to a separate byte buffer. I created a class that extended InputStream and implemented available() and read(...). Available returns how many bytes are in the byte buffer, and read only gives back however much is in the buffer or however much the caller requests, whichever is less.
This setup lets me use an InputStream interface, but behind the scenes it is just a continuously running reader thread that is alive until the connection is dropped. At that time the read, if blocked, will throw an exception to indicate the connection closed. This behavior is fine as it can be easily handled.
Thanks to all above who helped with this issue. Your thoughts help move towards the solution.

FileReference.save() duplicates ByteArray

I've encountered a memory problem using FileReference.save(). My Flash application generates of a lot of data in real-time and needs to save this data to a local file. As I understand, Flash 10 (as opposed to AIR) does not support streaming to a file. But, what's even worse is that FileReference.save() duplicates all the data before saving it. I was looking for a workaround to this doubled memory usage and thought about the following approach:
What if I pass a custom subclass of ByteArray as an argument to FileReference.save(), where this ByteArray subclass would override all read*() methods. The overridden read*() methods would wait for a piece of data to be generated by my application, return this piece of data and immediately remove it from the memory. I know how much data will be generated, so I could also override length/bytesAvailable methods.
Would it be possible? Could you give me some hint how to do it? I've created a subclass of ByteArray, registered an alias for it, passed an instance of this subclass to FileReference.save(), but somehow FileReference.save() seems to treat it just as it was a ByteArray instance and doesn't call any of my overridden methods...
Thanks a lot for any help!
It's not something I've tried before, but can you try sending the data out to a php application that would handle saving the ByteArray to the server, much like saving an image to the server, so then you'd use URLLoader.data instead, using something like this:
http://www.zedia.net/2008/sending-bytearray-and-variables-to-server-side-script-at-the-same-time/
It's an interesting idea. Perhaps to start you should just add traces in your extended ByteArray to see how the FileReference#save() functions internally.
If it has some kind of
while( originalByteArray.bytesAvailable )
writeToSaveBuffer( originalByteArray.readByte() );
functionality the overrides could just truncate the original buffer on every read like you say, something like:
override function readByte() : uint {
var b : uint = super.readByte();
// Truncate the bytes (assuming bytesAvailable = length - removedBytes)
length = length - bytesAvailable;
return b;
}
On the other hand, if this now works I guess the original byte array would not be available afterwards in the application anymore.
(i havn't tested this myself, truncating might require more work than the example)

Resources