Retrieve XML from HTTP POST Request Payload - asp.net

I have an ActiveX that POSTs to the server (HTTP Handler) with a payload of a certain XML document.
Is there a better way to retrieve the payload into XML than the below?
private static byte[] RequestPayload()
{
int bytesToRead = HttpContext.Current.Request.TotalBytes;
return (HttpContext.Current.Request.BinaryRead(bytesToRead));
}
using (var mem = new MemoryStream(RequestPayload()))
{
var docu = XDocument.Load(mem);
}
Once I have the "docu" I can query using LINQ to XML.
Thanks

Simply load the XML from the InputStream of the Request e.g.
XDocument doc;
using (Stream input = HttpContext.Current.Request.InputStream)
{
doc = XDocument.Load(input);
}
there is no need for a MemoryStream in my view.

Related

Store Image to table field returned by HTTP GET Response

I'm trying to get Image from Azure Storage Container by HTTP GET request.
I want to then save the image returned by the GET Response into Table field and then populate into SSRS report.
Need some inputs on how to handle the response to extract the image and then store it in table field.
Here's my incomplete code:
class Class1
{
public static void main(Args _args)
{
xml response = "";
System.Net.HttpWebRequest httpRequest = null;
System.Net.HttpWebResponse httpResponse = null;
CLRObject clro = null;
System.IO.Stream stream = null;
System.IO.StreamReader streamReader = null;
System.Byte[] bytes = null;
System.Text.Encoding encoding = null;
try
{
new InteropPermission(InteropKind::ClrInterop).assert();
httpRequest = System.Net.WebRequest::Create("https://storage.blob.core.windows.net/productimages/Products/10101001_000_001.jpg");
httpResponse = httpRequest.GetResponse();
stream = httpResponse.GetResponseStream();
streamReader = new System.IO.StreamReader(stream);
response = streamReader.ReadToEnd();
CodeAccessPermission::revertAssert();
}
catch(Exception::CLRError)
{
throw error(AifUtil::getClrErrorMessage());
}
}
}
Edit1:
Instead of troubleshooting the code I ended up following this, simply paste the URL in SSRS report image box, it fetches the image from the URL on its own.
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/5dc6cf93-34cb-4e52-a95c-d478e143dce7/ssrs-fetching-image-from-url?forum=sqlreportingservices#:~:text=Generally%2C%20in%20SSRS%2C%20we%20are,%3EExternal%2D%3Eadd%20URL.&text=Hope%20this%20helps.&text=Please%20remember%20to%20click%20%22Mark,Unmark%20as%20Answer%22%20if%20not.

Unsupported Media Types when POST to web api

Here is the client :
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost/MP.Business.Implementation.FaceAPI/");
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));
using (var request = new HttpRequestMessage(HttpMethod.Post, client.BaseAddress + "api/Recognition/Recognize"))
{
request.Content = new ByteArrayContent(pic);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
await client.PostAsync(request.RequestUri, request.Content);
}
}
and the server :
[System.Web.Http.HttpPost]
public string Recognize(byte[] img)
{
//do someth with the byte []
}
I am getting error:
415 Unsupported Media Type
all the time - The request entity's media type 'application/octet-stream' is not supported for this resource. What can i do about it? I've found some answered threads here , but it didnt help.
While byte[] would be a great way to represent application/octet-stream data, this is not the case by default in Web API.
My workaround is in ASP.NET Core 1.1 - the details may be different in other variants.
In your controller method, remove the img parameter. Instead, refer to the Request.Body, which is a Stream. e.g. to save to a file:
using (var stream = new FileStream(someLocalPath, FileMode.Create))
{
Request.Body.CopyTo(stream);
}
The situation is similar for returning binary data from a GET controller method. If you make the return type byte[] then it is formatted with base64! This makes it significantly larger. Modern browsers are perfectly capable of handling raw binary data so this is no longer a sensible default.
Fortunately there is a Response.Body https://github.com/danielearwicker/ByteArrayFormatters:
Response.ContentType = "application/octet-stream";
Response.Body.Write(myArray, 0, myArray.Length);
Make the return type of your controller method void.
UPDATE
I've created a nuget package that enables direct use of byte[] in controller methods. See: https://github.com/danielearwicker/ByteArrayFormatters

Serializing using protobuf-net and sending as postdata in http

I'm using Protobuf-net to try and send a serialized object to a webapplication that I'm running in another project. The Serializer.Serialize<T>() method takes a Stream (to write to) and and instance of T (in this case, a list of a few objects that I set up to work with protobuf-net)
How do I go about doing this? Do I need to write to a file or can I send the stream as postdata somehow? Below you can see I'm using a string as the postdata.
My execute post method
public static void ExecuteHttpWebPostRequest(Uri uri,string postdata, int requestTimeOut, ref string responseContent)
{
if (string.IsNullOrEmpty(uri.Host))// || !IsConnectedToInternet(uri))
return;
var httpWebReq = (HttpWebRequest)WebRequest.Create(uri);
var bytePostData = Encoding.UTF8.GetBytes(postdata);
httpWebReq.Timeout = requestTimeOut*1000;
httpWebReq.Method = "POST";
httpWebReq.ContentLength = bytePostData.Length;
//httpWebReq.ContentType = "text/xml;charset=utf-8";
httpWebReq.ContentType = "application/octet-stream";
//httpWebReq.TransferEncoding=
//httpWebReq.ContentType = "application/xml";
//httpWebReq.Accept = "application/xml";
var dataStream = httpWebReq.GetRequestStream();
dataStream.Write(bytePostData, 0, bytePostData.Length);
dataStream.Close();
var httpWebResponse = (HttpWebResponse)httpWebReq.GetResponse();
// Get the stream associated with the response.
var receiveStream = httpWebResponse.GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
var readStream = new StreamReader(receiveStream,Encoding.Default);
responseContent = readStream.ReadToEnd();
httpWebResponse.Close();
}
You can just serialize to the request:
Serializer.Serialize(dataStream, obj);
And equally, you can deserialize from receiveStream, if you choose.
Note, however, that protobuf data is not text, and should not be treated as such - very bad things happen if you try that.

c# how to get a stream processed by httpResponse.BinaryWrite

I have the following method that writes a stream in a HttpResponse object.
public HttpResponse ShowPDF(Stream stream)
{
MemoryStream memoryStream = (MemoryStream) stream;
httpResponse.Clear();
httpResponse.Buffer = true;
httpResponse.ContentType = "application/pdf";
httpResponse.BinaryWrite(memoryStream.ToArray());
httpResponse.End();
return httpResponse;
}
In order to test it, I need to recover the processed stream.
Is there someway to read the stream from the httpResponse object?
I have two ideas... one to mock the HttpResponse, and the other is to simulate a web server.
1. Mocking HttpResponse
I wrote this before I knew which mocking framework you used. Here's how you could test your method using TypeMock.
This assumes that you pass your httpResponse variable to the method, changing the method as follows:
public void ShowPDF(Stream stream, HttpResponse httpResponse)
Of course you would change this to passing it to a property on your Page object instead, if it is a member of your Page class.
And here's an example of how you could test using a fake HttpResponse:
internal void TestPDF()
{
FileStream fileStream = new FileStream("C:\\deleteme\\The Mischievous Nerd's Guide to World Domination.pdf", FileMode.Open);
MemoryStream memoryStream = new MemoryStream();
try
{
memoryStream.SetLength(fileStream.Length);
fileStream.Read(memoryStream.GetBuffer(), 0, (int)fileStream.Length);
memoryStream.Flush();
fileStream.Close();
byte[] buffer = null;
var fakeHttpResponse = Isolate.Fake.Instance<HttpResponse>(Members.ReturnRecursiveFakes);
Isolate.WhenCalled(() => fakeHttpResponse.BinaryWrite(null)).DoInstead((context) => { buffer = (byte[])context.Parameters[0]; });
ShowPDF(memoryStream, fakeHttpResponse);
if (buffer == null)
throw new Exception("It didn't write!");
}
finally
{
memoryStream.Close();
}
}
2. Simulate a Web Server
Perhaps you can do this by simulating a web server. It might sound crazy, but it doesn't look like it's that much code. Here are a couple of links about running Web Forms outside of IIS.
Can I run a ASPX and grep the result without making HTTP request?
http://msdn.microsoft.com/en-us/magazine/cc163879.aspx

Stuck Streaming Xml

This is the code i have written to get the xml of one url but it says
"Data at the root level is invalid" with any url.. Can someone specify why?
XmlDocument xdoc = new XmlDocument();//xml doc used for xml parsing
xdoc.LoadXml("http://latestpackagingnews.blogspot.com/feeds/posts/default");//loading XML in xml doc
XmlNodeList xNodelst = xdoc.DocumentElement.SelectNodes("entry");//reading node so that we can traverse thorugh the XML
Response.Write(xNodelst);
You need to first download your xml data using WebClient class
string downloadedString;
System.Net.WebClient client = new System.Net.WebClient();
downloadedString = client.DownloadString("http://latestpackagingnews.blogspot.com/feeds/posts/default");
//Now write this string as an xml
//I think you can easily do it with XmlDocument class and then read it
The xdoc.LoadXml can not for read url, change it to xdoc.Load and it will work.
You can also read : Using Returned XML with C#
XmlDocument.LoadXml method awaits XML-text, but not the source URL.
First, download page content into string and then pass it to LoadXml. Here is how you can download:
public string GetUrlContent(string url)
{
var request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)request.GetResponse();
var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
var content = reader.ReadToEnd();
reader.Close();
response.Close();
return content;
}
In your case it would be:
var content = GetUrlContent("http://latestpackagingnews.blogspot.com/feeds/posts/default");
var doc = new XmlDocument();
doc.LoadXml(content);

Resources