Web beacon trafficking with MimeKit - c#

Is there any possible way to create a web beacon/bug with mimekit? I have taken a look on how to embed images within the message body in MimeKit but I can't seem to figure out how to transform this into a web beacon/bug, does anybody know a way how to do this?
My code:
private string makeMailContents(Klant klant, Mail mail)
{
var builder = new BodyBuilder();
var path = Path.Combine("wwwroot/trackers/track_open.png");
var img = builder.LinkedResources.Add(path);
byte[] data = Convert.FromBase64String(mail.Content);
string decoded = Encoding.UTF8.GetString(data);
Type mt = mail.GetType();
PropertyInfo mp;
string code;
string final = "";
img.ContentId = MimeUtils.GenerateMessageId();
return string.Format(#"<img src=""cid:{0}"">", img.ContentId);// this does not load anything, I want this to be the url to the image
}

fixed it, I just had to return the following:
return string.Format(#"<img src=""{0}"">", "http://localhost:5000/api/mail/track/open");
for some reason this only works with string.Format. You don't need MimeKit related functions to do this.
NOTE
The request only works once, at least in chrome, I believe that this is because of the cache

Related

Convert XmlWriter to Stream / char / byte []

I have an asp.net/C#/Blazor environment, where a button generates an XML with a specific class. With XML Writer, I can make the file, and even can save/download it, but it goes to the server-side (It must to be downloaded on client-side. please, do not argue about it).
I know Blazor implemented some instant download (https://learn.microsoft.com/en-us/aspnet/core/blazor/file-downloads?view=aspnetcore-6.0) and it works perfect with blank/new files, but the problem is, I don't know how to "pass" or convert my previously generated XML with XML Writer method, because Blazor method(s) only allow Stream, char or byte Arrays downloads.
When I tried to convert it, the error
Some of my code is:
protected async Task CreateXmlFile(int correlativo,string idDocumento, string siglaDocumento, List<DocumentoXML> documentos = null, List<SignersXML> signersXMLs = null,
List<ContentXMLComplemento> complementos = null,
List<SignersXMLComplemento> signersComplemento = null)
{
_xmlWriterSettings = new XmlWriterSettings
{
Indent = true,
Encoding = new UTF8Encoding(false)
};
string fullPath= "";
XmlWriter writer;
XmlSerializer serializer;
var documentoIngresoRaiz = new DocumentoIngresoRaiz
{
Content_XML = new List<ContentXML>
{
new ContentXML
{
sve_XML = new List<sveXML>
{
new sveXML
{
Documento_XML = documentos
}
}
}
},
Signers_XML = signersXMLs
};
fullPath = $"{mainPath}Ingreso-{correlativo}.xml";
var fileName = $"Ingreso-{correlativo}.xml";
writer = XmlWriter.Create(fullPath, _xmlWriterSettings);
serializer = new XmlSerializer(typeof(DocumentoIngresoRaiz));
serializer.Serialize(writer, documentoIngresoRaiz);
writer.Close();
//I've been trying with these 3 Blazor method lines, to send my xml as stream
var fileStream = new MemoryStream(writer);
using var streamRef = new DotNetStreamReference(stream: fileStream);
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
}
Error CS1503: Argument 1: cannot convert from 'System.Xml.XmlWriter' to 'byte[]'
I've been looking all around StackOverflow and the Internet with no success.
I found some similar posts (I want to download XML file in C# which I created using XmlWriter.Create() on user's system) (How to get a Stream from an XMLWriter?), but they couldn't solve my problem. Any help or tip is welcome. Thank you in advance!
Since there was no way to convert the already generated XML file to byte/stream/char array, I found out that the solution was:
saving this XML file on server-side
and then immediately download it to local machine, via JavaScript code (pasted below), passing the fileURL (location of file on the server) and fileName (name of the file)
await JS.InvokeVoidAsync("triggerFileDownload", fileName, fileURL);
function triggerFileDownload(fileName, url) {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}

Cannot embed inline image in outlook when image is in barcode

I have created one barcode image and convert it in data stream and embed it inline and pass it through smtp mail. Now recipient can able to see that barcode in webmail, but cannot able to see it outlook it is coming as red cross (x).
Any help is highly appreciated.
private string MyMethod(string myInputStr)
{
var myBarcodeObj = new Barcode();
string myString = string.Format("{0}\t", myInputStr);
byte[] myGeneratedCode = myBarcodeObj.GenerateCode(myString);
string myBase64ImageString = ConvertBytesToBase64(myGeneratedCode );
objBEorder.ERPOrder.ImgBarcode = new System.Web.UI.WebControls.Image()
{
ImageUrl = "data:image/jpg;base64," + myBase64ImageString
};
}
private string ConvertBytesToBase64(byte[] imageBytes)
{
return Convert.ToBase64String(imageBytes);
}
HTML images are rendered by Word in Outlook, and it does not support embedded ("data:image/jpg;base64) images.
Add the image as an attachment and set its Content-ID MIME header. The HTML body should refer to the image thorugh the cid attribute (<img src="cid:xyz">)

How to Download File

I have been following these links all listed below, i found the best way to write this SMALL create Excel and Download function. ( Using EPPlus for Excel )
Download file of any type in Asp.Net MVC using FileResult? + How to convert an Stream into a byte[] in C#?
Using a FileStreamResult with a MemoryStream in ASP.NET MVC 3
Writing A Custom File Download Action Result For ASP.NET MVC
It runs through the code perfectly without error every time I run this but does not "Kick out" the file to be downloaded ( in a save as dialogue or w/e ).
public ActionResult ShowReport()
{
using (var stream = new MemoryStream())
{
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("Sample1");
ws.Cells["A1"].Value = "Sample 1";
ws.Cells["A1"].Style.Font.Bold = true;
var shape = ws.Drawings.AddShape("Shape1", eShapeStyle.Rect);
shape.SetPosition(50, 200);
shape.SetSize(200, 100);
shape.Text = "Sample 1 text text text";
var fileDownloadName = "sample.xlsx";
var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";//System.Net.Mime.MediaTypeNames.Application.Octet
var fileStream = new MemoryStream();
pck.SaveAs(fileStream);
fileStream.Position = 0;
var fsr = new FileStreamResult(fileStream, contentType);
fsr.FileDownloadName = fileDownloadName;
byte[] fileBytes = ReadToEnd(fileStream);
string fileName = "example";
return File(fileBytes, contentType, fileName);
}
}
What am I doing wrong / missing? - Must i write that Dialogue myself?
PN: I have also attempted this way
byte[] fileBytes = ReadToEnd(fileStream);
string fileName = "example";
return File(fileBytes, contentType, fileName);
ofcourse i had to figure out how to convert Stream to Byte but it also did not show anything.
Image of Chrome's Network Development Tool
Sorry about the small image ( if you can't see it scroll in with ctl+MouseWheel ) if your in a supporting browswer.
(In response to the comment thread above.)
From the image posted it looks like the actual file request (the last one in the list) is coming from JavaScript code instead of from a normal document-level request. Given this, it's highly likely that the server-side code is working correctly and returning the correct response.
However, since it's an AJAX request, the browser doesn't actually know what to do with the response. There are some potential solutions here. Ideally, you'll want to make this a normal request and remove AJAX from the picture if possible. If that's not an option, you can still initiate a document-level request from JavaScript. Something as simple as this:
window.location = '#Url.Action("Method", "Controller")';
This would be initiated from JavaScript code as it currently is, but would be for the whole browser instead of an AJAX request. That should do the trick.
Using the memory stream you have you can simple pass that to the Response object once you have saved the Excel Package
Code:
Response.AddHeader("content-disposition", "attachment;filename=FILENAME.xlsx")
Response.Charset = String.Empty
Response.ContentType = "application/ms-excel"
Response.BinaryWrite(stream.ToArray())
Response.End()

Reading iso-8859-1 rss feed C# WP7

I'm trying to read a rss feed which uses the iso-8859-1 encoding.
I can get all elements fine, the problem is when I put it in a textblock it will not show all characters. I'm not sure what i'm doing wrong. i've tried a few solutions I found on google but this didn't work for me. I must be missing something.. It's also the first time I really work with anything other than utf-16. I never had to convert anything before.
The app works as follows I downloadstring async(WebClient). So when that is called I get a string containing the complete rss feed.
I have tried getting the bytes, then encoding.convert.. But I must be missing something.
Like this is a sample
WebClient RSS = new WebClient();
RSS.Encoding = Encoding.GetEncoding("ISO-8859-1");
RSS.DownloadStringCompleted += new DownloadStringCompletedEventHandler(RSS_DSC);
RSS.DownloadStringAsync(new Uri("some rss feed"));
public void RSS_DSC(object sender, DownloadStringCompletedEventArgs args)
{
_xml = XElement.Parse(args.Result);
foreach(XElement item in _xml.Elements("channel").Elements("item"))
{
feeditem.title = item.Element("title").Value;
// + all other items
}
}
I've tried this aswell
private void RSS_ORC(object sender, OpenReadCompletedEventArgs args)
{
Encoding e = Encoding.GetEncoding("ISO-8859-1");
Stream ez = args.Result;
StreamReader rdr = new StreamReader(ez, e);
XElement _xml = _xml = XElement.Parse(rdr.ReadToEnd());
feedlist = new List<Code.NewsItem>();
XNamespace dc = "http://purl.org/dc/elements/1.1/";
foreach (XElement item in _xml.Elements("channel").Elements("item"))
{
Code.NewsItem feeditem = new Code.NewsItem();
feeditem.title = item.Element("title").Value;
feeditem.description = item.Element("description").Value;
feeditem.pubdate = item.Element("pubDate").Value;
feeditem.author = item.Element(dc + "creator").Value;
feedlist.Add(feeditem);
}
listBox1.ItemsSource = feedlist;
}
Though titles contain characters that are not displayed well either. Like.. I can get the encoding to partially work. Instead of having these characters: the square with a question mark, a question mark or the singe square.
Don't get me wrong I'm a total beginner on this. But the solutions that has been posted on the web do not solve it for me.
Note that I removed the encoding part because it wasn't working :/
If someone would be able to help me that would be amazing.
You can specify an encoding by setting encoding before calling client.DownloadStringAsync:
webClient.Encoding = Encoding.GetEncoding("iso-8859-1")
In your code sample you do not create the XML doc anywhere. Are some code missing? You should initialize it with something like:
var xml = XDocument.Load((string)args.Result);
If it helps, you can use:
var myString = HttpUtility.HtmlDecode(feeditem.description);
This way every special character will be decode, you can then display myString correctly
Windows Phone 7 and Silverlight does not support other encodings such as ISO-8859-1, they only support ASCII and the Unicode encoders. For anything else you will need to use OpenReadAsync to get a stream of bytes then apply your own implementation of an encoding.
This blog might be helpful to you in creating one.
ISO-8859-1 most definitely is supported in WP7. It is the only one of the ISO-8859-* encodings that is. I use an XmlReader to deserialize RSS streams and UTF-* and ISO-8859-1 are the only encodings that are supported by that class (windows-* and ISO-8859-2 and above throw exceptions in the XmlReader c'tor).
Try using an XmlReader like this (without specifying the encoding):
using (XmlReader reader = XmlReader.Create(stream))
{
...
}
The XmlReader will get the encoding from the xml declaration in the stream.
You may still have problems displaying the upper half of the characters (above 0x80). I had this problem in feed me (my WP7 app) and used this little hack to fix things up:
public static string EncodeHtml(string text)
{
if (text == null) return string.Empty;
StringBuilder decodedText = new StringBuilder();
foreach (char value in text)
{
int i = (int)value;
if (i > 127)
{
decodedText.Append(string.Format("&#{0};", i));
}
else
{
decodedText.Append(value);
}
}
return decodedText.ToString();
}
It only works in a WebBrowser control of course, but that is the only place that I ever saw an incorrect display.
Hope this helps,
Calum
This worked for me when needing to decode the rss xml. It's generic enough so that it will support all encryption types supported by .NET
WebClient wcRSSFeeds = new WebClient();
String rssContent;
// Support for international chars
Encoding encoding = wcRSSFeeds.Encoding;
if (encoding != null)
{
encoding = Encoding.GetEncoding(encoding.BodyName);
}
else
{
encoding = Encoding.UTF8; // set to standard if none given
}
Stream stRSSFeeds = wcRSSFeeds.OpenRead(feedURL); // feedURL is a string eg, "http://blah.com"
using (StreamReader srRSSFeeds = new StreamReader(stRSSFeeds, encoding, false))
{
rssContent = srRSSFeeds.ReadToEnd();
}

Uploading files to Sharepoint (WSS 3.0) document library using HTTP PUT

Hi I have the following piece of code to upload a file to Sharepoint. It uses HTTP PUT:
public static string UploadFile(string destUrl, string sourcePath)
{
try
{
Uri destUri = new Uri(destUrl);
FileStream inStream = File.OpenRead(sourcePath);
WebRequest req = WebRequest.Create(destUri);
req.Method = "PUT";
req.Headers.Add("Overwrite", "F");
req.Timeout = System.Threading.Timeout.Infinite;
req.Credentials = CredentialCache.DefaultCredentials;
Stream outStream = req.GetRequestStream();
string status = CopyStream(inStream, outStream);
if (status == "success")
{
outStream.Close();
WebResponse ores = req.GetResponse();
return "success";
}
else
{
return status;
}
}
catch (WebException we)
{
return we.Message;
}
catch (System.Exception ee)
{
return ee.Message;
}
}
When I run this code I get the exception:
"The remote server returned an error: (409) Conflict."
Does anyone have any ideas as to where I am going wrong?
Thanks,
Alex
I've had this issue when I was referencing the url of the document library and not the destination file itself.
i.e. try http://server name/document library name/new file name.doc
No clue. But why dont you use Remote Procedure Calls (RPC) thats how i usually do it.
I found this example that might get you started http://geek.hubkey.com/2007/11/upload-file-to-sharepoint-document.html
Try:
void StorePlainFile(string target_url, string filename, byte[] file_bytes)
{
string url = target_url + "/" + filename;
System.Net.WebClient client = new System.Net.WebClient();
client.Credentials = System.Net.CredentialCache.DefaultCredentials;
client.Headers.Add("Overwrite", "F");
byte[] response = client.UploadData(url, "PUT", file_bytes);
}
I haven't solved my problem yet, that's why I'm here, but I know why you're getting this error.
The error results because you are not setting a hidden, but required, field. In my case, I had no columns, and certainly none that were required. However, there is a versioning field that is in conflict.
My intent is to 1) upload the document, and 2) set the document's metadata. 1) and 2) occur over separate HTTP calls. Ideally, I want to do this in a single call, but I don't know how to do this.
To accomplish this, 1) succeeds, so the document appears in the library. Then when I try to update the metadata, that's when I get the 409 error.
I'm pretty sure that I first need to insert a step in between 1) and 2) which first downloads the document's list (or manifest) which would in theory contain the needed versioning information. All I would need to do is set the metadata fields I need, and send back to the server.
No, we don't want to use the Sharepoint API because there are no libraries for it in Java. ;-)
Is there a paticular reason you can't just use the Sharepoint API (eg. SPFolder.Files.Add) to upload the file? As follows:
http://msdn.microsoft.com/en-us/library/ms454491.aspx
public void UploadFile(string srcUrl, string destUrl)
{
if (! File.Exists(srcUrl))
{
throw new ArgumentException(String.Format("{0} does not exist",
srcUrl), "srcUrl");
}
SPWeb site = new SPSite(destUrl).OpenWeb();
FileStream fStream = File.OpenRead(srcUrl);
byte[] contents = new byte[fStream.Length];
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
EnsureParentFolder(site, destUrl);
site.Files.Add(destUrl, contents);
}
Alex,
This happened to me too. You probable should create another another lit or document library and upload files into it to test.
You may want to check the variable "destUri" to see if it points to exactly the expected sharepoint list.
My situation is I firstly created a document library "Requrements", there is a typo mistake, then i changed the title to "Requirements". You should notice that sharepoint still keeps the URL to this list as http://server:port/Requrements
This is an exeption. Hopefully it helps.

Categories

Resources