My concept is downloading a image from url and sending the image(Linked Resource)to mail message to MSMQ!, I can sucessfully download the image , but i cannot able to send it to MSMQ, i need to serialize the Alternative Views, which i could not able to do?
Here is the code
MailMessage m = new MailMessage();
string strBody="<h1>This is sample</h1><image src=\"cid:image1\">";
m.Body = strBody;
AlternateView av1 = AlternateView.CreateAlternateViewFromString(strBody, null, MediaTypeNames.Text.Html);
Here I am Downloading the Image from url
Stream DownloadStream = ReturnImage();
LinkedResource lr = new LinkedResource(DownloadStream, MediaTypeNames.Image.Gif);
lr.ContentId = "image1";
av1.LinkedResources.Add(lr);
m.AlternateViews.Add(av);
private Stream ReturnImage()
{
try
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(urlForImage);
webRequest.ProtocolVersion = HttpVersion.Version10;
webRequest.KeepAlive = false;
webRequest.Timeout = 1000000000;
webRequest.ReadWriteTimeout = 1000000000;
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
{
Stream k = webResponse.GetResponseStream();
MemoryStream ms = new MemoryStream();
int count = 0;
do
{
byte[] buf = new byte[1024];
count = k.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while (k.CanRead && count > 0);
return ms;
}
}
catch (WebException e)
{
return null;
}
Can you guys give solution for serializing the Alternative views so that i can able to send and Receive MSMQ !
I do not think that you should take this approach.
MSMQ is designed to be ligtwheight, so sending huge data like images was not the intention - although this is technically possible, of course.
Also bear in mind that MSQM has a limit of 4 MB per message. Depending on the size of your images this might become problematic (or might not).
Instead I suggest that you save the images to a place that can be accessed by all participating application/ services/ etc., e.g. a network share, file server, or web server, or ...
Then you send only the URIs in your MSMQ message. This will be very fast to process on both sender and receiver side. Also, this will be much, much lighter on the MSMQ infrastructure.
Related
I'm trying to play in Chrome Browser video with source from Web Api
<video id="TestVideo" class="dtm-video-element" controls="">
<source src="https://localhost:44305/Api/FilesController/Stream/Get" id="TestSource" type="video/mp4" />
</video>
In order to implement progressive downloading I'm using PushStreamContent in server response
httpResponce.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)new StreamService(fileName,httpResponce).WriteContentToStream);
public async void WriteContentToStream(Stream outputStream, HttpContent content, TransportContext transportContext)
{
//here set the size of buffer
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
//here we re using stream to read file from db server
using (var fileStream = IOC.Container.Resolve<IMongoCommonService>().GridRecordFiles.GetFileAsStream(_fileName))
{
int totalSize = (int)fileStream.Length;
/*here we are saying read bytes from file as long as total size of file
is greater then 0*/
_response.Content.Headers.Add("Content-Length", fileStream.Length.ToString());
// _response.Content.Headers.Add("Content-Range", "bytes 0-"+ totalSize.ToString()+"/"+ fileStream.Length);
while (totalSize > 0)
{
int count = totalSize > bufferSize ? bufferSize : totalSize;
//here we are reading the buffer from orginal file
int sizeOfReadedBuffer = fileStream.Read(buffer, 0, count);
//here we are writing the readed buffer to output//
await outputStream.WriteAsync(buffer, 0, sizeOfReadedBuffer);
//and finally after writing to output stream decrementing it to total size of file.
totalSize -= sizeOfReadedBuffer;
}
}
}
After I load page video start to play immediately, but I can not seek for previous (already played) seconds of video or rewind it as well in Google Chrome browser. When I try to do this, video goes back to the beggining.
But in Firefox and Edge it's working like it should be, I can go back to already played part. I don't know how to solve this issue in Google Chrome Browser
You should use HTTP partial content. As it described here:
As it turns out, looping (or any sort of seeking, for that matter) in elements on Chrome only works if the video file was served up by a server that understands partial content requests.
So there are some articles that may help you to implement it. Try these links:
HTTP 206 Partial Content In ASP.NET Web API - Video File Streaming
How to work with HTTP Range Headers in WebAPI
Here is an implementation of responding to Range requests correctly - it reads a video from a file and returns it to the browser as a stream, so it doesnt eat up your server's ram. You get the chance to decide the security you want to apply etc in code.
[HttpGet]
public HttpResponseMessage Video(string id)
{
bool rangeMode = false;
int startByte = 0;
if (Request.Headers.Range != null)
if (Request.Headers.Range.Ranges.Any())
{
rangeMode = true;
var range = Request.Headers.Range.Ranges.First();
startByte = Convert.ToInt32(range.From ?? 0);
}
var stream = new FileStream(/* FILE NAME - convert id to file somehow */, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) {Position = startByte};
if (rangeMode)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.PartialContent)
{
Content = new ByteRangeStreamContent(stream, Request.Headers.Range, MediaTypeHeaderValue.Parse(fileDetails.MimeType))
};
response.Headers.AcceptRanges.Add("bytes");
return response;
}
else
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(stream)
};
response.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(fileDetails.MimeType);
return response;
}
}
I am building a system with on one side an Android app, that uses an HTTPURLConnection to communicate with the other side, which is a C# HttpListener. Over this channel they communicate with XML data.
This works very well, except for some larger data. When I try to communicate that, I see the XML from Android arrives the C# application en the C# application does respond. However, before the data arrives the Android, I get a "Connection reset by peer." exception.
This is the Android code:
URL url = new URL(urlString);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
connection.setDoOutput(true);
connection.setFixedLengthStreamingMode(tel.length());
connection.setReadTimeout(30000);
// write our telegram...
OutputStream output = new BufferedOutputStream(connection.getOutputStream());
output.write(tel.getBytes());
output.flush();
and here is the reply read:
InputStream input = new BufferedInputStream(connection.getInputStream());
if (connection.getResponseCode() == HttpStatus.SC_OK) {
String r = null;
byte cbuf[] = new byte[connection.getContentLength()];
if (input.read(cbuf, 0, connection.getContentLength()) != -1) {
r = new String(cbuf);
}
reply = Telegram.fromString(r);
} else {
throw new ProtocolException("HTTP Error code: "+connection.getResponseCode());
}
and this is the C# code:
httpListener = new HttpListener();
httpListener.Prefixes.Add(String.Format("http://*:{0}/", port);
httpListener.Start();
Turns out, the connection.getContentLength() does not always match the number of bytes read in the input.read(), so the read call waits (and eventually, the server resets as it is done sending I guess).
To fix, I rewrote the receiving side to:
int bufs = 256, read;
ByteArrayOutputStream cbuf = new ByteArrayOutputStream(bufs);
byte[] tempbuf = new byte[bufs];
while ((read = input.read(tempbuf, 0, bufs)) != -1) {
Log.d(PocketApplication.TAG, "Read "+read+" bytes.");
cbuf.write(tempbuf);
}
and it works fine now. Making the size of bufs too large causes it to fail again (e.g. with 1024, the same problem occurs).
I'm using PUT method to update some data. But my below code is not working.
The code:
var schemaRequest = WebRequest.Create(new Uri(SchemaUri)) as HttpWebRequest;
schemaRequest.Method = "PUT";
schemaRequest.ContentType = "text/xml";
schemaRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
schemaRequest.Proxy = WebRequest.DefaultWebProxy;
schemaRequest.AddRange(1024);
string test = "<ArrayOfUpdateNodeRequest> <UpdateNodeRequest> <Description>vijay</Description> <Name>Publishing</Name></UpdateNodeRequest></ArrayOfUpdateNodeRequest>";
byte[] arr = new byte[1024];
arr = System.Text.Encoding.UTF8.GetBytes(test);
schemaRequest.ContentLength = arr.Length;
using (var dataStream = schemaRequest.GetRequestStream())
{
dataStream.Write(arr, 0, arr.Length);
}
I'm getting the exception "This stream does not support seek operations." at GetRequestStream().
The exception is pretty clear, the steam doesn't support seeking. Looking at the object in the debugger does not mean you need to seek--if you do, please provide an example. You should simply be able to write to the stream for it to be sent to the host. It doesn't make sense to be able to seek when you're sending a stream to a host (e.g, how do you seek back before a byte you've already sent over the wire to the host?).
If you need to seek locally, before sending to the host, create a memory stream and seek that way. For example:
using (MemoryStream memoryStream new MemoryStream())
{
// ... writes
memoryStream.Seek(0, SeekOrigin.Begin);
//... writes
memoryStream.CopyTo(schemaRequest.GetRequestStream());
}
I am referring to this article to understand file downloads using C#.
Code uses traditional method to read Stream like
((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0
How can I divide a file to be downloaded into multiple segments, so that I can download separate segments in parallel and merge them?
using (WebClient wcDownload = new WebClient())
{
try
{
// Create a request to the file we are downloading
webRequest = (HttpWebRequest)WebRequest.Create(txtUrl.Text);
// Set default authentication for retrieving the file
webRequest.Credentials = CredentialCache.DefaultCredentials;
// Retrieve the response from the server
webResponse = (HttpWebResponse)webRequest.GetResponse();
// Ask the server for the file size and store it
Int64 fileSize = webResponse.ContentLength;
// Open the URL for download
strResponse = wcDownload.OpenRead(txtUrl.Text);
// Create a new file stream where we will be saving the data (local drive)
strLocal = new FileStream(txtPath.Text, FileMode.Create, FileAccess.Write, FileShare.None);
// It will store the current number of bytes we retrieved from the server
int bytesSize = 0;
// A buffer for storing and writing the data retrieved from the server
byte[] downBuffer = new byte[2048];
// Loop through the buffer until the buffer is empty
while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
// Write the data from the buffer to the local hard drive
strLocal.Write(downBuffer, 0, bytesSize);
// Invoke the method that updates the form's label and progress bar
this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize });
}
}
you need several threads to accomplish that.
first you start the first download thread, creating a webclient and getting the file size. then you can start several new thread, which add a download range header.
you need a logic which takes care about the downloaded parts, and creates new download parts when one finished.
http://msdn.microsoft.com/de-de/library/system.net.httpwebrequest.addrange.aspx
I noticed that the WebClient implementation has sometimes a strange behaviour, so I still recommend implementing an own HTTP client if you really want to write a "big" download program.
ps: thanks to user svick
I have a monitoring system and I want to save a snapshot from a camera when alarm trigger.
I have tried many methods to do that…and it’s all working fine , stream snapshot from the camera then save it as a jpg in the pc…. picture (jpg format,1280*1024,140KB)..That’s fine
But my problem is in the application performance...
The app need about 20 ~30 seconds to read the steam, that’s not acceptable coz that method will be called every 2 second .I need to know what wrong with that code and how I can get it much faster than that. ?
Many thanks in advance
Code:
string sourceURL = "http://192.168.0.211/cgi-bin/cmd/encoder?SNAPSHOT";
byte[] buffer = new byte[200000];
int read, total = 0;
WebRequest req = (WebRequest)WebRequest.Create(sourceURL);
req.Credentials = new NetworkCredential("admin", "123456");
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
while ((read = stream.Read(buffer, total, 1000)) != 0)
{
total += read;
}
Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0,total));
string path = JPGName.Text+".jpg";
bmp.Save(path);
I very much doubt that this code is the cause of the problem, at least for the first method call (but read further below).
Technically, you could produce the Bitmap without saving to a memory buffer first, or if you don't need to display the image as well, you can save the raw data without ever constructing a Bitmap, but that's not going to help in terms of multiple seconds improved performance. Have you checked how long it takes to download the image from that URL using a browser, wget, curl or whatever tool, because I suspect something is going on with the encoding source.
Something you should do is clean up your resources; close the stream properly. This can potentially cause the problem if you call this method regularly, because .NET will only open a few connections to the same host at any one point.
// Make sure the stream gets closed once we're done with it
using (Stream stream = resp.GetResponseStream())
{
// A larger buffer size would be benefitial, but it's not going
// to make a significant difference.
while ((read = stream.Read(buffer, total, 1000)) != 0)
{
total += read;
}
}
I cannot try the network behavior of the WebResponse stream, but you handle the stream twice (once in your loop and once with your memory stream).
I don't thing that's the whole problem but I'd give it a try:
string sourceURL = "http://192.168.0.211/cgi-bin/cmd/encoder?SNAPSHOT";
WebRequest req = (WebRequest)WebRequest.Create(sourceURL);
req.Credentials = new NetworkCredential("admin", "123456");
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
Bitmap bmp = (Bitmap)Bitmap.FromStream(stream);
string path = JPGName.Text + ".jpg";
bmp.Save(path);
Try to read bigger pieces of data, than 1000 bytes per time. I can see no problem with, for example,
read = stream.Read(buffer, 0, buffer.Length);
Try this to download the file.
using(WebClient webClient = new WebClient())
{
webClient.DownloadFile("http://192.168.0.211/cgi-bin/cmd/encoder?SNAPSHOT", "c:\\Temp\myPic.jpg");
}
You can use a DateTime to put a unique stamp on the shot.