So i am currently building an application that allows a group of users to view all emails from a certain email address. This all works correctly. The problem I am encountering comes when i am trying to get the attachments.
I am relatively new to this area and used the example from Microsoft found here. Compare this to my code below:
protected internal override Stream GetAttachmentStreamFinal(MailAttachmentDetails attachment)
{
var response = m_service.GetAttachments(new[] { attachment.Id }, BodyType.Text, Enumerable.Empty<PropertyDefinitionBase>());
if (response.OverallResult != ServiceResult.Success)
{
if (response.Count > 0)
{
var ex = new MailException(response[0].ErrorMessage);
ex.Data.Add(response[0].ErrorCode, response[0].ErrorMessage);
foreach (var ed in response[0].ErrorDetails)
{
ex.Data.Add(ed.Key, ed.Value);
}
throw ex;
}
throw new MailException("Error occurred while fetching the attachment from the mail service.");
}
foreach (var attachmentResponse in response)
{
if (attachmentResponse.Attachment is FileAttachment)
{
var fa = attachmentResponse.Attachment as FileAttachment;
var cs = new MemoryStream(fa.Content);
fa.Load(cs);
cs.Seek(0, SeekOrigin.Begin);
return cs;
}
}
return null;
}
As you can see both sets of code are very similar. However when I step through and get to the attachmentResponse.Attachment is FileAttachment line I get this error thrown
Attempt by method 'Mail.ExchangeEmailService.GetAttachmentStreamFinal(Mail.MailAttachmentDetails)' to access method 'Microsoft.Exchange.WebServices.Data.GetAttachmentResponse.get_Attachment()' failed.
Everything is being passed in correctly and the response returns as success.
I have noticed when stepping through my code that Attachment shows as a non-public member. But as this is encapsulated in Microsofts class im unsure as to why that is the case or what i can do?
I just want to expand on #Jason Johnstons answer.
For some reason the version of EWS in NuGet is not correct. It throws the error that you are experiencing.
A workaround is to remove the reference to the NuGet package via
Uninstall-Package Microsoft.Exchange.WebServices
Then download and run the MSI file here
https://www.microsoft.com/en-us/download/details.aspx?id=42951
This will install the DLLs you require to the default location of
[ C:\Program Files\Microsoft\Exchange\Web Services\2.2 ]
Then simply copied they into your lib directory (or such) and created references to the DLLs directly instead.
Credit: http://www.resolvinghere.com/sm/microsoftexchangewebservicesdatagetattachmentresponsegetattachment-failed.shtml
As the other answers already mentioned, the nuget package from Microsoft is not up to date. I also had the same problem as the OP.
First I solved it by following the answer of Daniel - SDS Group. But then I found the nuget package Exchange.WebServices.Managed.Api from marklamley. It is the current version 2.2.1.1 of the ews-managed-api GitHub project.
Make sure you have the latest version of the Microsoft.Exchange.WebServices.dll. Older versions didn't return the actual attachment data when calling that particular overload of the GetAttachments method.
Related
I am working on converting an application to .Net Core 3.1, and in my class library I am generating a PDF form from an existing template, and filling that form with data. In ITextSharp, the predecessor to IText7, the PdfAcroForm static method ".GetAcroForm()" worked perfectly, but in the current version of iText7 (7.1.12) a Null Reference Exception is thrown. I have followed the documentation to the best of my ability, but I am unsure how to continue. Any suggestions would be appreciated.
NOTE: The template path exists, the new document shows that it has been filled properly, and it is impossible to "new" a PdfAcroForm, you are required to use the static .GetAcroForm() method.
A null check will not solve this issue, as the object should never be null. The documentation indicates that the .GetAcroForm() method will create a new form if the parameter "createNotExist" is set to true, which I have done here.
I have researched and have located an issue on the iText GitHub that indicates that this issue was "fixed" around a year ago: https://github.com/itext/itext7/pull/44#issue-351612749
The following is the method which prepares the forms:
public string DocumentGenerator(string templatePath, FormFieldSet[] formFieldSet, bool useSpecailOutputPath)
{
if(!File.Exists(templatePath))
{
throw new Exception("The template file provided does not exist: MC-071(iText)");
}
string newFile = useSpecailOutputPath ?
m_SpecialOutputPath :
Path.GetTempPath() + Guid.NewGuid().ToString() + ".pdf";
try
{
PdfDocument newDocument = new PdfDocument(new PdfReader(templatePath), new PdfWriter(newFile));
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(newDocument, true); // <=== Exception Thrown Here
foreach (FormFieldSet fs in formFieldSet)
{
acroForm.GetField(fs.FieldName).SetValue(fs.FillValue);
}
// Sets form flattening
acroForm.FlattenFields();
// Closes and writes the form
newDocument.Close();
return newFile;
}
catch { return string.Empty; };
}
Any suggestions would be greatly appreciated
I had the same problem, and after digging down all the way to iText7's internal objects and methods, I finally "solved" my problem.
Apparently iText has some internal errors/exceptions that they are just sort of "skipping" and "pushing past", because I realized by accident that I had "Enable Just My Code" in Visual Studios disabled, and so my system was trying to debug iText7's code as well as mine. The moment that I re-enabled it in my Visual Studio settings (Tools > Options > Debugging > General > Enable Just My Code checkbox), the problem magically went away.
So I spent four hours trying to troubleshoot a problem that was in THEIR code, but that they apparently found some way to work around and push through the method anyways even on a null reference failure.
My convert to PDF function is now working just fine.
Just an update to anyone looking for this issue. This is a known issue and is fixed in the current development branch. You are safe to bypass the exception in visual studio until it is corrected. This has no negative impact on the functionality and is the result of a misplaced return in the original iText7 source.
I am attempting to automate partition refreshes in Azure Analysis Services via C#. I have installed and referenced the latest 'Microsoft.AnalysisServices. ..' assemblies found here:
https://learn.microsoft.com/en-us/azure/analysis-services/analysis-services-data-providers.
I then have the following code:
using System;
using Microsoft.AnalysisServices.Tabular;
public void Run()
{
Server asSrv = new Server();
try
{
asSrv.Connect(ASConnectionString);
Database db = asSrv.Databases.FindByName("HospoIQTabular");
Model m = db.Model;
// only refresh 2017 partitions
m.Tables["Sales"].Partitions["Sales - Post 2017"].RequestRefresh(RefreshType.Full);
m.Tables["Payments"].Partitions["Payments - Post 2017"].RequestRefresh(RefreshType.Full);
db.Model.SaveChanges(); // commit which will execute the refresh
}
catch (Exception e)
{
OnEventLog(e.Message);
}
finally
{
asSrv.Disconnect();
asSrv = null;
}
}
Connect to the server and database itself works fine. However, attempting to reference 'db.Model' throws the following exception:
The value '2' is unexpected for type 'DataSourceType'.
I've looked but can't find any help anywhere on this. Any thoughts??
For me, the path that worked was C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies
but only after reading Andrae comment which sent me on the right direction
The problem is similar with the NuGet package Microsoft.AnalysisServices.Tabular (v13)
Fortunately you can use the NuGet packages listed here: https://learn.microsoft.com/en-us/azure/analysis-services/analysis-services-data-providers.
In Visual Studio NuGet lists this package as Microsoft.AnalysisServices.retail.amd64
I've encountered a problem when I try to retrieve the valid states of all features within an MSI package using the Microsoft.Deployment.WindowsInstaller.Installer class.
I want to copy the ValidStates property of each FeatureInfo within a Session. However when doing so I get a "Handle is in an invalid state." exception.
If I print each of these values out using Console.WriteLine() or step through the code in Visual Studio there is no exception.
I am at a loss as to what is preventing me from doing this.
Thanks in advance!
My Code:
var featureDictionary = new Dictionary<string, string[]>();
if (string.IsNullOrWhiteSpace(mPath))
return featureDictionary;
try
{
Installer.SetInternalUI(InstallUIOptions.Silent);
using (var session = Installer.OpenPackage(mPath, true))
{
foreach (var feature in session.Features)
{
try
{
var states = feature.ValidStates.Select((state) => state.ToString());
featureDictionary.Add(feature.Name, states.ToArray());
}
catch (InstallerException ex)
{
Debug.WriteLine(ex.Message);
}
}
}
}
catch (InstallerException) { }
return featureDictionary;
The basic problem appears to be that you are opening the MSI as a file. Since you haven't posted its declaration, or how it is set, I'm assuming that mpath means it's a path to the file. Your OpenPackage method parameters seem to indicate this too. You're getting that error because you are trying to open the MSI file as a file during the actual install, and failing.
The way to get hold of the database for the running install is to use Session.Database.
You can't open the running MSI as a file during the install perhaps for the same reason you can't run an MSI file that you have open with Orca, a simple file sharing violation. When you step through with Visual Studio you're simply accessing the static file and getting default values and the file isn't being used for an install. The other issue is that there can only be one Session object per process (as the OpenPackage docs say) and you are attempting to get a second one while there is already a Session object associated with the handle of the install.
As a custom action it needs to be sequenced after CostFinalize.
Windows Installer conditional expressions such as !feature-state will tell you what state the feature is in, because it's usually better to avoid code where Windows Installer will just give you the answer.
I am using DotNetCharting version 4.2. I am trying to create a chart, save it to disk and return the path as a string. Here is a simplified version of my code thus far.
Chart aChart = new Chart();
aChart aChart.Title = "Some Title";
aChart aChart.ChartArea.Background = new Background(Color.White);
aChart.TempDirectory = "C:\\temp\\"
aChart.Width = chartWidth;
aChart.Height = chartHeight;
imageName = aChart.FileManager.SaveImage();
I got this from this dotnetCharting support page. It is very straightforward code.
Here is the problem: The code above actually DOES create an image in the appropriate directory. This is NOT a directory permissions issue. When I add my actual data to the aChart, it actually DOES add it and an image is created. However, the SaveImage() method always throws an exception of "Failed to map the path '/'." The SaveImage() method is supposed to return a String, however, it always returns "" and the exception is thrown.
More Info: I am doing this in a WCF Service. Is it possible that since it's in a service the dotNetCharting DLL is having trouble with some internal MapPath?
I just upgraded the DotNetCharting to the latest version (7.0) and now it works fine. I believe that it was an issue with the old version of the DLL. I'll leave this here in case anyone else has this issue.
Summary: application will not accept the ExchangeServiceBinding command.
Details:
I am trying to loop through a very large mailbox, so I am using an index to break the inbox into 200 email chunks. The only example I could find (shown below) keeps returning
the type or namespace name “ExchangeServiceBinding” could not be found (are you missing a using directive or an assembly reference? )
Which I find strange, because I am using it using Microsoft.Exchange.WebServices;. Any ideas or help is greatly appreciated. I am running Windows 7 and Visual Studio 2010 and trying to access Exchange 2007 mailboxes.
Things I've tried:
searching Google
searching Stack Overflow
searching MSDN
slamming my head on my desk
trial and error
Code:
// Create binding variable to be used for GetItemsFromInbox().
// Set up the binding with credentials and URL.
ExchangeServiceBinding binding = new ExchangeServiceBinding();
binding.Credentials = new NetworkCredential(dUser, dPassword, dDomain);
binding.Url = new Uri("https://" + ExchangeServerName + "/EWS/Exchange.asmx");
// Set up the binding for Exchange impersonation.
binding.ExchangeImpersonation = new ExchangeImpersonationType();
binding.ExchangeImpersonation.ConnectingSID = new ConnectingSIDType();
binding.ExchangeImpersonation.ConnectingSID.PrimarySmtpAddress = "mailboxnamehere”;
// Call GetItemsFromInbox()
int index = 0;
bool looping = true;
while (looping)
{
List<ItemType> items = GetItemsFromInbox(binding, index, 200, index);
if (items == null || items.count == 0)
{
looping = false;
break;
}
// Do your work here
}
Instead of the Exchange Web Services, use the Exchange Managed API.
SDK: http://msdn.microsoft.com/en-us/library/dd633710(v=exchg.80).aspx
Download: http://www.microsoft.com/download/en/details.aspx?id=13480
It's much easier to use than the WebServices.
I found my error. This methodology only works for Exchange 2010. Since I am running Exchange 2007 I will have to figure out a completely different way to make this work.
Thank you everyone for you help, I really appreciate it.
You should add a WebReference to your solution to the exchange WebService.
https://exchaneServerName/EWS/Exchange.asmx
ExchangeServiceBinding is contained into the ews.dll. According to your error, you didn't add a reference to this DLL file.
More information about Generating Exchange Web Services Proxy Classes:
So now you have a code file with the autogenerated proxies. Next, you compile your code file into an assembly for use in your Exchange Web Services projects. The C# compiler is available with the Visual Studio 2005 Command Prompt. Assuming that you named your code file EWS.cs, you can run the following command at the command prompt to compile your code into an assembly:
csc /target:library /out:EWS.dll EWS.cs
Notice that EWS.dll is the name of the compiled assembly. This is how EWS.dll is created.