Adding multiple files to attachments using WebClient - c#

I m trying to send email having multiple attachments from my website dashboard. However, my code is only able to attach the last file. I m using **WebClient()** to download files from Cloud system and then adding them as attachments.
This is the code I have written:
foreach (var link in attachments)
{
var uri = new Uri(link);
var s = uri.Segments[1];
var tempDirectory = #"c:\tempFolder\" + #"\"+ s;
WebClient webClient = new WebClient();
webClient.DownloadFile(link, tempDirectory);
Attachment attachment = new Attachment(tempDirectory);
attachment.ContentDisposition.Inline = true;
attachment.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
attachment.ContentId = model.Id.ToString();
attachment.ContentType.Name = s;
email.Attachments.Add(attachment);
}
Any help would be appreciated
EDITED:
I attached two files, so getting these links in each loop:
Loop 1:
abc.com/TestEmail1.txt
Loop 2:
abc.com/TestEmail2.txt

Removing these lines has solved my problem
attachment.ContentDisposition.Inline = true;
attachment.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
attachment.ContentId = model.Id.ToString();
attachment.ContentType.Name = s;

Related

Using Webclient with Foreach Loop to Download Webpages About 100,000

I am trying to build a small application where when I enter the a list of around 100,000 to 200,0000 urls it should go and download the html and save it in a relative folder.
I have 2 solution but each a some problems I have trying to figure out the best approach.
First Solution: Synchronize Method
Below is the code I am using
currentline = 0;
var lines = txtUrls.Lines.Where(line => !String.IsNullOrWhiteSpace(line)).Count();
string urltext = txtUrls.Text;
List<string> list = new List<string>(
txtUrls.Text.Split(new string[] { "\r\n" },
StringSplitOptions.RemoveEmptyEntries));
lblStatus.Text = "Working";
btnStart.Enabled = false;
foreach (string url in list)
{
using (WebClient client = new WebClient())
{
client.DownloadFile(url, #".\pages\page" + currentline + ".html");
currentline++;
}
}
lblStatus.Text = "Finished";
btnStart.Enabled = true;
the code works fine however it's slow and also randomly after 5000 urls it's stops working and the process says it's completed. (Please note I am using this code on background worker but make this code simpler to view I am showing only the relevant code.)
Second Solution : Asynchronize Method
int currentline = 0;
string urltext = txtUrls.Text;
List<string> list = new List<string>(
txtUrls.Text.Split(new string[] { "\r\n" },
StringSplitOptions.RemoveEmptyEntries));
foreach (var url in list)
{
using (WebClient webClient = new WebClient())
{
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
webClient.DownloadFileAsync(new Uri(url), #".\pages\page" + currentline + ".html");
}
currentline++;
label1.Text = "No.of Lines Completed: " + currentline;
}
this code works super fast but most of the time I am getting downloaded files with 0KB and I am sure the network is fast since I am testing in OVH Dedi server.
Can anyone point what I am doing wrong ? or tips on improving it or entirely different solution to this problem.
Instead of using DownloadFile() try use
public async Task GetData()
{
WebClient client = new WebClient();
var data = await client.DownloadDataTaskAsync("http://xxxxxxxxxxxxxxxxxxxxx");
}
you will get data formated in byte[]. Then you just call:
File.WriteAllBytes() to save them to disk.

Can't upload file to Document Library using CSOM

I am trying to upload multiple file to a Document Library and also update its coloumn values.
List(Doc Lib) already exists but I am stuck with uploadinf the file
I've tried these methods
using lists.asmx
NetworkCredential credentials = new NetworkCredential("user", "Pass", "domain");
#region ListWebService
ListService.Lists listService = new ListService.Lists();
listService.Credentials = credentials;
List list = cc.Web.Lists.GetByTitle(library);
listService.Url = cc.Url + "/_vti_bin/lists.asmx";
try
{
FileStream fStream = System.IO.File.OpenRead(filePath);
string fName = fStream.Name.Substring(3);
byte[] contents = new byte[fStream.Length];
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
string attach = listService.AddAttachment(library, itemId.ToString(), Path.GetFileName(filePath), contents);
}
#endregion
catch (System.Web.Services.Protocols.SoapException ex)
{
CSVWriter("Message:\n" + ex.Message + "\nDetail:\n" +
ex.Detail.InnerText + "\nStackTrace:\n" + ex.StackTrace, LogReport);
}
It gives a error ServerException :To add an item to a document library, use SPFileCollection.Add() on AddAttachment()
Using
List lib = cc.Web.Lists.GetByTitle("TestLib");
FileCreationInformation fileInfo = new FileCreationInformation();
fileInfo.Content = System.IO.File.ReadAllBytes("C:\\Users\\AJohn\\Desktop\\sample.docx");
fileInfo.Url = "https://serverm/sites/Testing1/TestLib/sample.docx";
fileInfo.Overwrite = true;
Microsoft.SharePoint.Client.File upFile = lib.RootFolder.Files.Add(fileInfo);
cc.Load(upFile);
cc.ExecuteQuery();
I was able to upload once using this method, but now I am getting ServerException :To add an item to a document library, use SPFileCollection.Add() on cc.ExecuteQuery()
But if at all this method works, what I want is that I should update the coloumn values related to this file. In first method I get item.ID so from there I can update the Coloumn Values
Regarding the second method, the following example demonstrates how to upload a file into Documents library and set it's properties (e.g. Category text field)
using (var ctx = new ClientContext(webUri))
{
var targetList = ctx.Web.Lists.GetByTitle("Documents");
var fileInfo = new FileCreationInformation
{
Url = System.IO.Path.GetFileName(sourcePath),
Content = System.IO.File.ReadAllBytes(sourcePath),
Overwrite = true
};
var file = targetList.RootFolder.Files.Add(fileInfo);
var item = file.ListItemAllFields;
item["Category"] = "User Guide";
item.Update();
ctx.ExecuteQuery();
}

Outlook Redemption With Embedded Image

I use outlook Redemption dll for creating outlook message template with c# language.
Below is my code:
RedemptionLoader.DllLocation64Bit = Server.MapPath("~/bin/dlls/Redemption64.dll");
RedemptionLoader.DllLocation32Bit = Server.MapPath("~/bin/dlls/Redemption.dll");
Interop.Redemption.RDOSession session = RedemptionLoader.new_RDOSession();
var msg = session.GetMessageFromMsgFile(templatePath);
msg.Subject = String.Format("Report");
String ImageString = Server.MapPath("~\\FolderName") + "\\" + ImageName;
RDOAttachment Attach = msg.Attachments.Add(ImageString);
Attach.ContentID = "image1";
String htb = "<html><head><title>The Title</title></head><body><h1>This is some text</h1>Image 1<br /><img src=cid:image1><br /></body></html>";
msg.HTMLBody = htb;
msg.Save();
msg.SaveAs(newPath);
Everything work and image is saved to new location. But when i check that message template, i could not see Image anywhere. instead of image it gives me error.
Update
Instead of embedded image , I tried just to attach this file. But when I open file I didn't see any attachment. I check Total Attachments with OutlookSpy, It shows me 0 attachment. Does my code wrong for attachment?
I found solution for this. I need to call session two time. First time to save attachment to my template file and than again to create new instance of it. Below is my code:
RedemptionLoader.DllLocation64Bit = Server.MapPath("~/bin/dlls/Redemption64.dll");
RedemptionLoader.DllLocation32Bit = Server.MapPath("~/bin/dlls/Redemption.dll");
Interop.Redemption.RDOSession session1 = RedemptionLoader.new_RDOSession();
var msg1 = session1.GetMessageFromMsgFile(templatePath);
msg1.Subject = String.Format("Report");
String ImageString = Server.MapPath("~\\FolderName") + "\\" + ImageName;
RDOAttachment Attach = msg1.Attachments.Add(ImageString);
Attach.ContentID = "image1";
String htb = "<html><head><title>The Title</title></head><body><h1>This is some text</h1>Image 1<br /><img src=cid:image1><br /></body></html>";
msg1.HTMLBody = htb;
msg1.Save();
Interop.Redemption.RDOSession session = RedemptionLoader.new_RDOSession();
var msg = session.GetMessageFromMsgFile(templatePath);
msg.SaveAs(newPath);
This works for me.

how to attach the file using telerik Rad Async Upload to a mail

Please tell me hoe to attach the file using telerik rad upload in a mail and send the mail.
I tried differrent scenarios to attach the file to the mail but it doesn't get attached.
Here is the scenario: I used target folder to save it on the webserver and attach the file from that location.
if (rdtxtAdditionalEmail.Text != "")
{
char[] delimiterChars = { ';' };
string text = rdtxtAdditionalEmail.Text;
string[] words = text.Split(delimiterChars);
foreach (string s in words)
{
newEmail.To = dr["Email"].ToString();
newEmail.From = "sy#mydomain.com";
newEmail.Subject = rdtxtSubject.Text;
newEmail.BodyFormat = MailFormat.Html;
newEmail.Body = rdtxtSubject.Text;
List<EmailAttachment> attachments = new List<EmailAttachment>();
foreach (EmailAttachment attach in attachments)
{
System.Net.Mail.Attachment attachFile = new Attachment("C:/Inetpub /wwwroot/DotNetNuke/Data/" + attach.fileName);
newEmail.Attachments.Add(attachFile);
}
for (int i = 0; i < rdauAttachments.UploadedFiles.Count; i++)
{
UploadedFile file = rdauAttachments.UploadedFiles[i];
EmailAttachment attachment = new EmailAttachment();
attachment.filePath = "C:/Inetpub/wwwroot/DotNetNuke/Data/" + rdauAttachments.UploadedFiles[i].GetName();
attachment.fileName = rdauAttachments.UploadedFiles[i].GetName();
newEmail.Attachments.Add(attachment);
}
SmtpMail.Send(newEmail);
}
}
I also try to do it using the demo exapmle in telerik pages but it didnot workout.
Please help me.
Thanks,
Sravanthi
string filename = string.Empty;
string path = string.Empty;
MailMessage mailMsg = new MailMessage();
if (AsyncUpload1.UploadedFiles.Count > 0)
{
foreach (UploadedFile file in AsyncUpload1.UploadedFiles)
{
filename = file.FileName;
path = System.IO.Path.GetFileName(filename);
string Withoutext = System.IO.Path.GetFileNameWithoutExtension(filename);
file.SaveAs(Server.MapPath("~/AttachMents/") + path);
FileStream fs = new FileStream(Server.MapPath("~/AttachMents/") + filename,
FileMode.Open, FileAccess.Read);
System.Net.Mail.Attachment a = new System.Net.Mail.Attachment(fs, filename,
MediaTypeNames.Application.Octet);
mailMsg.Attachments.Add(a);
}
}

updated listitem attributes aren't commiting changes to sharepoint

i'm uploading a document to sharepoint.. however i would like to provide a custom name rather than it inherit the name of the file which im uploading.
my code was based on this solution: http://www.codeproject.com/Articles/103503/How-to-upload-download-a-document-in-SharePoint-20.aspx
however this doesnt work.
Additionally, i would also like to provide a title of the file:
so i wanted to update the title:
uploadFile.ListItemAllFields.FieldValues["Title"] = "my custom title";
However, once the file has completed its upload..i login to sharepoint and notice the title hasnt been applied.
how can i intergrate uploading the file and applying a new name?
many thanks,
EDIT:
using (var clientContext = GetNewContext())
{
var uploadLocation = string.Format("{0}{1}/{2}", SiteUrl, Helpers.ListNames.RequestedDocuments, Path.GetFileName(document));
//Get Document List
var documentslist = clientContext.Web.Lists.GetByTitle(Helpers.ListNames.RequestedDocuments);
var fileCreationInformation = new FileCreationInformation
{
Content = System.IO.File.ReadAllBytes(document), //Assign to content byte[] i.e. documentStream
Overwrite = true, //Allow owerwrite of document
Url = uploadLocation //Upload URL,
};
var uploadFile = documentslist.RootFolder.Files.Add(fileCreationInformation);
uploadFile.ListItemAllFields.FieldValues["Title"] = title;
uploadFile.ListItemAllFields.Update();
clientContext.ExecuteQuery();
}
site.SubmitChanges(ConflictMode.FailOnFirstConflict, true);
You are missing a call to clientContext.Load after you add the file to the Files collection. See these blog posts for more information:
https://www.c-sharpcorner.com/code/965/programmatically-upload-document-using-client-object-model-in-sharepoint.aspx
https://zimmergren.net/sp-2010-uploading-files-using-the-client-om-in-sharepoint-2010/
This code sample is from the first blog post linked above:
public Boolean UploadDocument(String fileName, String filePath, List metaDataList)
{
SP.ClientContext ctx = new SP.ClientContext("http: //yoursharepointURL");
Web web = ctx.Web;
FileCreationInformation newFile = new FileCreationInformation();
newFile.Content = System.IO.File.ReadAllBytes(#"C: \TestFile.doc");
newFile.Url = " / " + fileName;
List docs = web.Lists.GetByTitle("Shared Documents");
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
context.Load(uploadFile);
context.ExecuteQuery();
SPClient.ListItem item = uploadFile.ListItemAllFields;
//Set the metadata
string docTitle = string.Empty;
item["Title"] = docTitle;
item.Update();
context.ExecuteQuery();
}
Are you calling Update after setting the field values?
uploadFile.ListItemAllFields.Update();
instead of setting:
uploadFile.ListItemAllFields.FieldValues["Title"] = title;
uploadFile.ListItemAllFields.Update();
set it as follows:
uploadFile.ListItemAllFields["Title"] = title;
uploadFile.ListItemAllFields.Update();

Categories