Help reading JSON from HttpContext.InputStream - asp.net

I have created a HttpModule to capture requests for auditing purposes.
For Ajax requests to a web method I would like to also log the JSON data associated with the request.
E.g Request
POST /MyPage.aspx/AddRecord HTTP/1.1
x-requested-with: XMLHttpRequest
Accept-Language: en-gb
Referer: http://fiddlerlocal:5000/AddRecord.aspx
Accept: application/json, text/javascript, /
Content-Type: application/json; charset=utf-8
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Host: fiddlerlocal:5000
Content-Length: 287
Connection: Keep-Alive
Pragma: no-cache
Cookie: .....
{"id":"282aa3b5-b55f-431c-916e-60433fdb61c0","date":"8-6-2010"}
I have tried a variety of methods to read the JSON ({"id":"282aa3b5-b55f-431c-916e-60433fdb61c0","date":"8-6-2010"}) from the HttpContext.InputStream.
Example 1:
StreamReader reader = new StreamReader(request.InputStream);
string encodedString = reader.ReadToEnd(); -- ReadToEnd returns an empty string
Example 2:
using (MemoryStream ms = new MemoryStream())
{
byte[] buffer = new byte[request.ContentLength];
request.InputStream.Read(buffer, 0, request.ContentLength);
ms.Write(buffer, 0, request.ContentLength); -- The byte array contains the correct number of bytes but each byte has a value of 0 - encoded some how?
return Convert.ToBase64String(ms.ToArray()); -- doesn't do anything
return Encoding.UTF8.GetString(ms.ToArray()); -- doesn't do anything
}
How can I successfully extract the data from HttpContext.InputStream?
Thanks in advance.

I needed to reset the position of the stream before reading...
request.InputStream.Position = 0;
using (StreamReader inputStream = new StreamReader(request.InputStream))
{
return inputStream.ReadToEnd();
}

The stream can't be read as far as i know. You might write you own handler, then buffer the stream, by reading and writing to another stream.
To parse the JSON part you might try
System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(string input);

Related

How http request with "Sec-Fetch-Mode: no-cors" in Blazor Webassembly

How is it possible to make a request by HttpClient with the HTTP request header Sec-Fetch-Mode: no-cors in Blazor Webassembly?
My actuel code is :
var hc = new HttpClient();
var responseHTTP = await hc.GetAsync("https://www.somedomain.com/api/");
But this produces the following HTTP request headers :
:authority: www.somedomain.com
:method: GET
:path: /api/json?input=test&key=AIzaSyDqWvsxxxxxxxxxxxxxxxxx1R7x2qoSkc&sessiontoken=136db14b-88bd-4730-a0b2-9b6c1861d9c7
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
origin: http://localhost:5000
referer: http://localhost:5000/places
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36
x-client-data: CJS2yQxxxxxxxxxxxxxxxxxxxxxxxxygEI7bXKAQiOusoBCObGygE=
To specifically answer your question, you need to create a HttpRequestMessage first.
e.g.
var request = new HttpRequestMessage(HttpMethod.Get, "https://www.somedomain.com/api/");
request.SetBrowserRequestMode(BrowserRequestMode.NoCors);
request.SetBrowserRequestCache(BrowserRequestCache.NoStore); //optional
using (var httpClient = new HttpClient())
{
var response = await httpClient.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
}
This will correctly set the sec-fetch-mode header to no-cors
I've found however, that the response comes back as empty even though upon inspection in fiddler the response is there.
The closest I got to understanding the problem is through this issue here but unfortunately the bug was closed.

Kendo upload not working in IE 8

Context
I am using asynchronous Kendo UI Upload (docs) in my application with HTML frontend and Java servlet at server side. When servlet returns nothing in response, it’s working perfectly. Uploading triggers progress change to “Done” on success, complete callback method is called.
Problem
I need to return some data such as GUID="SDR2334" from the server on successful upload. When I send response from the servlet, Kendo UI Upload control does not work/render as expected/as shown in Kendo demo site at all.
progress not getting changed to “Done” when uploading
complete method not being called
Attempted solution
I tried to add GUID with response header instead of response body. Still it’s not working.
Code I used
<form method="post" action="submit" style="width:45%">
<div class="demo-section">
<input name="files" id="files" type="file" />
</div>
</form>
$("#files").kendoUpload({
async: {
saveUrl: "http:111.11.11.111/fileupload",
autoUpload: false
},
multiple: false,
showFileList: true,
upload: function (e) {
e.data = { sessionid: CurrentSession.sessionId };
},
complete: function (e) {
alert(e.data);
$(".k-widget.k-upload").find("ul").remove();
}
});
Request header
Key Value
Request POST /services/fileUploadWithoutResponse HTTP/1.1
Accept application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer http://111.11.11.11:8090/WebClient/
Accept-Language en-US
User-Agent Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Content-Type multipart/form-data; boundary=---------------------------7de38b1219073a
Accept-Encoding gzip, deflate
Host 172.16.17.100:8090
Content-Length 114034
DNT 1
Connection Keep-Alive
Cache-Control no-cache
Response header
Key Value
Response HTTP/1.1 200 OK
Server Apache-Coyote/1.1
X-Powered-By Servlet 2.5; JBoss-5.0/JBossWeb-2.1
Access-Control-Allow-Origin *
guId f6ac7203-5bd6-433b-a632-548ca5b048cf
Content-Type application/json;charset=utf-8
Content-Length 0
Date Fri, 03 Jan 2014 13:00:19 GMT
Notice the guId header here.
I made it by setting the response content-type to text/plain.
Also I realized I need success event instead of complete event to get the contents of response body (e.response).

ASP.NET when responding with JSON, getting a <pre> tag

EDIT 2: Some response I found mention modifying the 'datatype', is that a header? i did try modifying the Content-Type to application/json which didn't help.
EDIT: I am still having this issue, just to add to this information I am sending a file as input, here are the HTTP headers that i am sending, I know the 'Accept' header is not an issue since I have another request that is not causing any isses:
Host: localhost:26479 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://localhost:26479/Home/FileUploadBrowser Content-Type: multipart/form-data; boundary=---------------------------41184676334 Content-Length: 1104
I have the following controller method ( still a work in progress):
Function uploadFileToAmazon(ByVal key As String) As ActionResult
Dim incomingStream As Stream = Me.Request.InputStream
Dim bucketName As String = ""
Dim accessKey As String = ""
Dim secretKey As String = ""
ConnectToAmazon(bucketName, accessKey, secretKey)
Dim client As AmazonS3 = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey, RegionEndpoint.USEast1)
Dim titledRequest As PutObjectRequest
titledRequest = New PutObjectRequest
With titledRequest
.WithBucketName(bucketName)
.WithKey(key)
.WithInputStream(incomingStream)
End With
Dim response As S3Response = client.PutObject(titledRequest)
Return Json(New With {Key .success = "true", Key .msg = "uploaded"})
End Function
Original question:
Here is the problem that I'm having, for some reason it is sending the following message to the front end after completing <pre>{"success":"true","msg":"uploaded"}</pre>. I am confused, where is this <pre> tag is coming from and how to I get rid of it? Thank you

Cannot open a PDF on iPad from ASP.NET

I am downloading a PDF (and others types but lets focus on PDF) through an IIS ASP.NET web application. The download works on every other platform except Safari on iPad and iPhone 4S. I know that iOS does not support document downloads, but Safari does not open the PDF either. Clicking the link has no response on the devices. I have tried a couple of solutions listed below (take out/replace headers mostly):
http://nilangshah.wordpress.com/2007/05/28/successfully-stream-a-pdf-to-browser-through-https/ and
PHP: Download file script not working on iPad
I can see no errors on the device other than a "expected MIME" type but I also see that in the desktop browser versions and it doesn't stop the download. I am running through a proxy and can see the device receives a 200 response with the proper headers. I have successfully opened a PDF from other sites with the device.
I am just getting started reacquainted with ASP and iOS so any debug insights would also be appreciated.
Here is what the code looks like:
context.Response.Buffer = false;
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.ClearContent();
context.Response.ContentType = "application/pdf";
string fileName = "thefile.pdf";
System.Web.HttpBrowserCapabilities browser = context.Request.Browser;
//I have tried with and without all the possbilities in the condition below
if (!browser.Browser.Equals("iPad"))
{
if (isDownload || viewers.Length == 0)
context.Response.AppendHeader("Content-Disposition",
string.Format("attachment; filename=\"{0}\"", fileName));
else
context.Response.AppendHeader("Content-Disposition", "filename=" + fileName);
}else
{
//context.Response.AppendHeader("Content-Disposition", string.Format("inline; filename=\"{0}\"", fileName));
}
FileStream iStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
long fileSize = iStream.Length;
long fileLengthToRead = fileSize;
int chunckSize = 10000;
byte[] buffer = new byte[chunckSize];
context.Response.AppendHeader("Content-Length", fileSize.ToString());
context.Response.AppendHeader("X-Content-Type-Options", "nosniff");
try
{
while (fileLengthToRead > 0 && context.Response.IsClientConnected)
{
int read = iStream.Read(buffer, 0, chunckSize);
context.Response.OutputStream.Write(buffer, 0, read);
context.Response.Flush();
fileLengthToRead = fileLengthToRead - read;
}
}
catch (HttpException) { }
finally
{
iStream.Close();
iStream.Dispose();
}
break;
And here is what the headers look like:
GET http://sample.com/sample.pdf HTTP/1.1
Host: sample.com
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/5.0 (iPad; U; CPU OS 4_3_4 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8K2 Safari/6533.18.5
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Referer: http://sample.com/sample.aspx
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 218882
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-Content-Type-Options: nosniff
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 01 Aug 2012 15:41:06 GMT

VS Builtin web server sends images as octet-stream

I am debugging an ASP.NET website which has a lot of javascripts and images using Visual Studio 2008 development web server.
One of the many scripts try to create an <img> tag on the fly and supply it with a proper src attribute. However, none of the images are loaded and instead alt text are displayed in Firefox, IE and Opera.
Digging further, I copied one of the image link and then paste it in Firefox's address bar and this is what comes up in live headers window:
GET /images/nav/zoomin.png HTTP/1.1
Host: localhost:7777
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
HTTP/1.x 200 OK
Server: ASP.NET Development Server/9.0.0.0
Date: Wed, 25 Feb 2009 16:59:23 GMT
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: application/octet-stream
Content-Length: 292
Connection: Close
The problematic part is the Content-Type header which is somehow set to "application/octet-stream" forcing a download operation instead of showing normally inside the <img> tag.
I am quiet sure that it isn't the javascript that is the problem, because it is code that has been copied verbatim from another application that worked just fine.
I believe I might have misconfigured something somewhere. But I could be wrong, so here's the code that create the HTML tag:
var zin = document.createElement("img");
zin = $Img.Png(zin, Settings.ImageHost + "zoomin.png");
zin.style.top = (this.y + zoomPaddingY) + "px";
zin.style.left = (this.x + zoomPaddingX) + "px";
zin.style.position = "absolute";
$Img.Swap(zin, Settings.ImageHost + "zoomin.png", Settings.ImageHost + "zoomin_active.png");
zin.alt = zin.title = "zoom in";
zin.style.cursor = this.hand;
$Evt.addListener(zin, "click", this.zoomIn, this, true);
// long long scroll ...
controlDiv.appendChild(zin);
The $Img.Png part is working fine for other PNG images, so it shouldn't be the source of the problem.
What did I did wrong?!?
Thanks for any help!
It's already midnight here... and I'm still working on this little app...
Are you using a GenericHandler that renders the image?
It would seem like an easy choice to do so.
Eg.
public class RenderImage : IHttpHandler, IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/png";
context.Response.Clear();
// TODO: Write image data
Bitmap bitmap = ...
bitmap.Save(Response.OutputStream,ImageFormat.Png);
context.Response.End();
}
public bool IsReusable { get { return false; } }
}

Resources