I want to know how to create an image object having the "src info from an email". I already manage to get read the inbox, and to parse the html of it, and get out all of the "src = foo" from all the images in the email. My question is how do I then proceed to create an image using the information taken out from "src" in the of the html. I need this object in order to store it in a sharepoint picture library. Just want to know how to create the image object of the image stored in the html of the email.
Not sure about how to put it in SharePoint, but assuming you have a src in an extractedSrc variable:
WebClient webClient = new WebClient();
webClient.DownloadFile(extractedSrc, localFileName)
I guess there are two basic cases you have to consider, 1. The src attribute points to an external image (ie. image stored on a web site), 2. Src points to an image attached in the email.
For case 1. You need to download the image from the external server and then you can save it in your share point
For case 2. You have to decode the attachment sections of the email to extract the file data and then you can save it to your library
Related
we are trying to get the content of the attachment's of the in the rtf mail but I have tried to search using different terms but have not found any reliable solution . can someone please help me to get the source of the attachment's as we get them in the html format.
The Outlook object model doesn't provide any property or method for getting the attachment content. To get the file attached you need to save it to the disk and then read the content from the there.
Also you may consider using a low-level API on which Outlook is based on - Extended MAPI. It allows getting the binary data of the attached file. Try using the Attachment.PropertyAccessor.GetProperty method while passing in the value "http://schemas.microsoft.com/mapi/proptag/0x37010102" (PR_ATTACH_DATA_BIN).
set msg = Application.ActiveExplorer.Selection(1)
set attach = msg.Attachments(1)
set ps = attach.PropertyAccessor
v = ps.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x37010102")
debug.print ps.BinaryToString(v)
On the low level (Extended MAPI in C++ or Delphi), you need to open the PR_ATTACH_DATA_OBJ property as IStorage and extract the data from there (it depends on the actual type of the attachment). You can see the data in the streams in OutlookSpy (I am its author) - select the message, click IMessage button on the OutlookSpy ribbon, go to the GetAttachmentTable tab, double click on the attachment to open it, select the PR_ATTACH_DATA_OBJ property, right click, select IMAPIProp::OpenProperty, then IStorage. Raw data will be there as well as an image representing the attachment (so that Outlook won't have to start the host app when rendering the message).
If using Redemption is an option (I am also its author, it can be used from any language including C# and VBA), its version of RDOAttachment.SaveAsFile method handles OLE attachments for most popular formats (Word, Excel, bitmap, Power Point, Adobe PDF, etc.) - create an instance of the RDOSession object (using either CrealeOleObject or RedemptionLoader) and use RDOSession.GetRDOObjectFromOutlookObject method (pass either MailItem or Attachment object) to get back RDOMail or RDOAttachment object respectively.
i have been found a solution for getting the images content from the rtf mail directly whiteout hitting the low level api or anything.
the solution is not a straight forward one
save the mail to the disk using oDoc.SaveAs2(filepath, WdSaveFormat.wdFormatFilteredHTML);
after saving the mail you will get the folder which you save a .htm doc
now read the .htm doc
get the all the image nodes of the .htm doc
using the image nods you can get src attribute of the image node
using the src value of the image you get the image directly from the disk itself and you can use that image
I'm writing a WinForms application. I created a Google Doc template file that contains placeholders like {{name}} for various text elements. I can successfully make a copy of this document and use the BatchUpdateDocumentRequest to modify them just fine.
However, I also have an embedded image in the document. I can obtain the objectId for this image just fine. I either want to replace this image with another or remove it from my template and then append my new image to the end of the document. In both cases, the InsertInlineImage or ReplaceImage classes require a URI of the image to insert or replace with. This is where I have an issue.
The image itself has been captured from a control on the WinForms. Its actually a chart. I've saved the image in PNG format since I know that is one of the formats supported by Google drive/docs. I figured in order to use it in the batch update, I would need to upload it first, so I did and got its file id and webcontentlink back in the response.
I'm not locked into any particular way of doing this. I originally tried creating an HTML file, uploading but then it would strip the image from it, so became useless, so I switched gears to using a Google Doc as my template and just try to replace elements in it instead. This went well until I got to the image.
Essentially no matter what I try to specify as the URI, it says the file in not in a supported format.
As far as I can tell, Google expects the URI to actually end in .png or be a real link versus a download URL you'd get from Google Drive.
Here is an example of the code I'm using to attempt to replace the image. The strImageObjectId is the objectId of the Embedded Object image in the template document copy that I want to replace. The Uri is what Google needs to pull the new image from. I'm happy to pull it from my local computer or Google Drive if only I could get it to accept it somehow.
BatchUpdateDocumentRequest batchUpdateRequest = new BatchUpdateDocumentRequest {
Requests = new List<Google.Apis.Docs.v1.Data.Request>()
};
request = new Google.Apis.Docs.v1.Data.Request {
ReplaceImage = new ReplaceImageRequest() {
ImageObjectId = strImageObjectId,
Uri = strChartWebContentLink
}
};
batchUpdateRequest.Requests.Add(request);
DocumentsResource.BatchUpdateRequest updateRequest =
sDocsService.Documents.BatchUpdate(batchUpdateRequest, strCopyFileId);
BatchUpdateDocumentResponse updateResponse = updateRequest.Execute();
I'm happy to use whatever method will get me to a point where I an end up with a Google Doc on Google Drive that was based on a template in which I can replace various text elements, but most importantly add/replace an image.
Thanks so much for the advice.
I got to the point were I believe I was specifying the URI correctly, but then I started getting an access forbidden error instead.
I didn't have time to hunt this one down, so I went back to creating an HTML template with my image, uploading as a Google Doc, exporting to PDF, and then uploading as a PDF. This ended up working because originally I was using a BMP as the file format and that is not supported by Google Docs, so I changed to a PNG instead and it worked just fine.
I think Google Docs needs to add the ability to add an image using a MemoryStream or some other programmatic base64 resource instead of purely being based on URIs and running into temporary upload or permission issues.
Hey I'm doing the same thing with you,
and I got this, by modify the download link format.
from this:
https://docs.google.com/uc?export=download&id={{YOUR GDRIVE IMAGE
ID}
to this
https://docs.google.com/uc?export=view&id={{YOUR GDRIVE IMAGE ID}
e.g :
uri: "https://docs.google.com/uc?export=view&id=1cjgyHqtYSgS0CBT4x-9eQIHRzOIfGgv-"
but the image should be set for public privilege
I would like to receive files from an asp.net website but I would like to verify the request with data in a database before serving the file to the client.
For images I would be loading using a standard html image tag like this:
'<img src="/Uploads/RANDOMGUID/img.aspx" alt="The Moon" title="The Moon">
The requests will have a random GUID in the path which maps to a field in the database for the stored image.
I would like to have one entry point for all the requests this could be an aspx or ashx page for example [unless there there is a better way], this would then:
Parse the GUID out of the request path
Verify if the requester has access to the requested image or file using database data
Return an error image or file if not authorized
If authorized return the file contents and set the content type
How should I implement such functionality? Do I need a site wide file extension which is handled in an aspx file and returns a custom file content type?
First, put image files into directory that can't be accessed by user directly.
Then change path like this:
<img src="/Uploads/img.aspx?id=RANDOMGUID" alt="The Moon" title="The Moon">
That way, you can get ID from Request.QueryString["id"] and do the checking.
It's much easier than path you wanted because it will always go to same aspx page. With original path you would have to do path mapping and complicate your life without need.
After checking in database you can use Response.WriteFile to send appropriate file. Check https://msdn.microsoft.com/en-us/library/dyfzssz9%28v=vs.110%29.aspx for details.
EDIT: This was regarding getting ID of image. As #mason pointed out, you should register handler and use .ashx extension as you don't really need view.
I'm currently using an html embed tag to display a pdf file that is saved on the local server. Is there a wayo to display a pdf file on my page without having to save it to the local file system of the server? I just wand to pass it to the view from the controller in such a way that it can be displayed as a pdf in the page without having it stored on the file system directly.
Alternatively, is there a way to call a method to delete the pdf file from the server once the user has navigated away from the page they are viewing? How do I tell if th euser has navicated away from the page and how do i cause that to trigger a method that will delete the file?
I created a MVC class called PdfResult that returns a byte array as a PDF file.
The purpose is as follows (can't upload the source code, sorry):
PdfResult inherits from FileStreamResult
Set the Content-Type header to application/pdf
Set the Content-Disposition to either attachment or inline, and set an appropriate file name
Convert your data to a Stream -- if your data is a byte array, then write it to a MemoryStream.
See https://stackoverflow.com/a/16673120/272072 for a good example of how to do this.
Then, your embed code just needs to point to the action method, as if it was a PDF file.
Here's an example:
public ActionResult ShowPdf() {
// Note: the view should contain a tag like <embed src='MyController/GetPdf'>
return View();
}
public ActionResult GetPdf() {
byte[] pdfBytes = dataRepo.GetPdf(...);
return new PdfResult(pdfBytes, "Filename.pdf", false) ;
}
Here is a link to a CodeProject article and code sample titled Download and Upload Images from SQL Server via ASP.NET MVC. This gives an example of an efficient method to stream content to and from SQL Server via MVC.
You can easily adapt the code to stream your PDF file downloads.
UPDATE
The article uses a DataReader, but it can easily be adapted to Linq2Sql or EF. As an example, here is the Read method where I am reading from the database and copying to the stream:
public override int Read(byte[] buffer, int offset, int count)
{
result = _attachments.ExecuteStoreQuery<byte[]>(
"SELECT SUBSTRING(AttachmentBytes, " + position.ToString() +
", " + count.ToString() + ") FROM Attachments WHERE Id = {0}",
id).First();
var bytesRead = result.Length;
Buffer.BlockCopy(result, 0, buffer, 0, bytesRead);
position += bytesRead;
return (int)bytesRead;
}
You can read the PDF as a bytestream from the database and save it to the http response stream. If you have set the content type correctly to application/pdf, then the browser will load the document in the PDF plugin.
Update (14/Oct/2011): You need to write the bytestream to the Response.OutputStream object. How you create and write the byte stream is dependent on how you have stored in the database and how you are retrieving it. The following code snippet is from an article we have on our website - Generate PDF Forms In ASP.NET Using PDFOne .NET v3.
// Get the page's output stream ready
Response.Clear();
Response.BufferOutput = true;
// Make the browser display the forms document
// using a PDF plug-in. (If no plug in is available,
// the browser will show the File -> Save As dialog box.
Response.ContentType = "application/pdf";
// Write the forms document to the browser
doc.Save(Response.OutputStream);
doc.Close();
doc.Dispose();
The doc object is from our component. You need not use that. This code snippet is only for your understanding. For your requirement, you may have to something like bytestream.save(Response.OutputStream) I guess. BTW, this code is for ordinary ASP.NET, not MVC.
DISCLAIMER: I work for Gnostice.
If you want to create the PDF 100% dynamically, you would generate it completely in memory then stream it out directly to the requesting web browser without saving it as a file. This is very easy to do with the right tools. I would recommend AspPDF from Persits.com as a way to do this very easily. Take a look at their online documentation to see how simple this is to do without creating a bunch of rendered PDF files all over your server.
If you cannot do something like that, then simply incorporate a process to cleanup your "expired" PDF files from your server's filesystem based on their age. For example, after you have created your local PDF file, you just look through the folder containing your temporary PDF's and delete any you find over a certain age. You cannot reliably tell if or when a user has navigated away from your page or site.
For the first part of your question, like mentioned in the comments, use some type of stream object to pass the PDF data around. Right now, you are streaming the file to the local file system, then streaming it once again to the embedded tag for display. Just do away with the intermediate step of saving to the file system, and do the whole thing in memory (although, that's not really a model of efficiency, and might not scale well).
Regarding the second part of your question, that's not as straightforward. MVC really has no concept of state (viewstate, etc.), so it doesn't have events that can be fired from a state change (say, navigating away from a page).
You could use Javascript to detect a user navigating away from your page (windows.onunload), that calls a (C#/VB) method to remove the file from the file system. You would probably have to use AJAX to communicate back to the server, using an HTTP POST method, and have something listening at that URL endpoint to fire your method that removes the file.
I store emails and their attachments in a database. I'm using a WPF WebBrowser and the NavigateToString method to display the html body of emails. It works but when emails use embedded images with a content id (cid), i can't display them. I saved all embedded images as attachments when i save emails in database. I could create and store images in temporary files of the current user and replace cid references with an absolute path on user's disk but i think it's not the best way...
Have you got some ideas ?
I finally found a good way :
I replaced the cid references of all images with base64 image data (RFC 2557) like this :
<img src="data:image/png;base64,RAAAtuhhx4dbgYKAAA7...more data....." alt="test">
You can use the following code to generate the base64 string :
string base64Str = Convert.ToBase64String(File.ReadAllBytes(#"C:\Temp\test.png"));
Remarks : doesn't work with IE6