EWS C# Attachment can't be updated - exchange-server

I'm trying to rename an Attachment in an EmailMessage object.
msg.Attachments.Where(c => c.Name == attachmentPdfFullNames[0]).FirstOrDefault().Name = "NEW NAME ATTACHMENT";
But it throw Exception Attachment can't be updated. I tried to copy and change name then remove and re-add attachment, but same :
Attachment a = msg.Attachments.Where(c => c.Name == attachmentPdfFullNames[0]).FirstOrDefault();
Attachment b = a;
b.Name = "NEW NAME ATTACHMENT";
msg.Attachments.Remove(a);
msg.Attachments.AddFileAttachment("./" + b.Name);
Thanks

You can't rename an attachment in EWS (there is no operation to do this just Create and Delete). So you will need to remove the Attachment you want to rename and Re-Attach it.
With your code you need to Call update on the Message (which means the code performs the operation) after your remove and before you re-add the attachment then after you add the new attachment eg
msg.Attachments.Remove(a);
msg.Update(ConflictResolutionMode.AlwaysOverwrite);
msg.Attachments.AddFileAttachment("./" + b.Name);
msg.Update(ConflictResolutionMode.AlwaysOverwrite);

Related

Which Assembly contains LINQ extension method Delete?

I am trying to delete a row from an entity named xyz in CRM using the following code in LINQPAD
var d = from z in xyz
where z.exch_ZipCode == "60069"
&& z.exch_zipcodeId.Value== new Guid("c6e88a07-b4a2-e211-b8d2-bc305befb465")
select new
{
zipId = z.exch_zipcodeId.Value,
zip = z.exch_ZipCode,
};
d.AsEnumerable().ToList().ForEach(row=>row.Delete());
I have added System.Data.DataSetExtensions.dll but I get the following error
'AnonymousType#1' does not contain a definition for 'Delete' and no extension method 'Delete' accepting a first argument of type 'AnonymousType#1' could be found (press F4 to add a using directive or assembly reference)
If this is LinqToSql then to delete rows you use DeleteOnSubmit or DeleteAllOnSubmit.
For example, if you want to delete all rows in xyz matching your criteria, you can do something like :
var query = (from z in xyz
where z.exch_ZipCode == "60069"
&& z.exch_zipcodeId.Value== new Guid("c6e88a07-b4a2-e211-b8d2-bc305befb465")
select z);
xyz.DeleteAllOnSumit(query);
SubmitChanges();

Display newly created record in Formview

I have this form on VS2012 with asp.net. First I do search for the patron, then go to verify information for that patron. This patron information is displayed in ItemTemplate(ReadOnly). If that is not the patron they are looking for then they can add a new patron with "New button" (asp.net code). I am able to get the id of the new Patron(which is PK). However I am not able to display this newly created record on the form after inserting. It still displays the record which was on display. Since this a formview I did not enable "Paging".
Is it possible to call the pageload event from datasource_inserted event? Then I can pass the new patron ID for display. I declared this ID as global variable?
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim lvPatronID As String
lvPatronID = Request.QueryString("value1")
If lvPatronID = "" Then
frmPatronView.ChangeMode(FormViewMode.Insert)
Else
frmPatronView.ChangeMode(FormViewMode.ReadOnly)
GvPatronID = lvPatronID
lblPatronID.Text = GvPatronID
End If
Protected Sub PatronDS_Inserted(sender As Object, e As SqlDataSourceStatusEventArgs) Handles PatronDS.Inserted
NewID = e.Command.Parameters("#PatronID").Value.ToString
GvPatronID = NewID
End Sub
Well I answered part of my own question. The following change to the Inserted event will let me view the newly inserted data. I have another button to add new record in the emptytemplate of the search form. This is why I am changing the mode to insert as the default mode is readonly. This will let me insert the data but after inserting it doesn't display the form at all. Not sure why Inserted event is not kicking in properly.
Protected Sub PatronDS_Inserted(sender As Object, e As SqlDataSourceStatusEventArgs) Handles PatronDS.Inserted
Dim NewID As String = Nothing
Try
NewID = e.Command.Parameters("#PatronID").Value.ToString
PatronDS.SelectCommand = "SELECT * FROM tblPatron WHERE PatronID='" & NewID & "'"
lblPatronID.Text = NewID.Trim()
frmPatronView.DataBind()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub

Linq - Updating all the properties but not the key one

I've an 'product' object that has to update a record in db.
Through a 'productCode' I retrieve the object to update using Linq.
Which is the most elegant way to overwrite alle the property but not the key one and then save changes?
You will need to access each property anyways, as you fetch a record manually. my recommendation for easiest, fastest and cleanest code:
code = productCode_toChange
using(Entity ent = new Entity())
{
var update = (from x in ent.Products where x.productCode == code select x).First();
update.property1 = product.property1;
update.property2 = product.property2;
// and so on for each property you change
ent.SaveChanges();
}
you could of course try:
using(Entity ent = new Entity())
{
var update = (from x in ent.Products where x.productCode == code select x).First();
update = product;
ent.SaveChanges();
}
but i can almost guarantee this will not work, as product will certainly have an id-property it will try to write to update, which will throw an exception, given the case product is the LINQ-generated type for the table-instance.
Be careful to check for type-conformity. also note, that you the SQL-Type of product code should not be text, as this type is incomparable

Adding a relationship with an entity which is in the Deleted state is not allowed

I am trying to remove a reference to an Entity in a One-To-Many relationship in the following manner, but am receiving an error when I try to attach the object 'o' to my DbContext. The error is:
"Adding a relationship with an entity which is in the Deleted state is not allowed."
I have also tried the following in place of setting the EntityState:
_db.OrganizationMetrics.Remove(om)
What is the right way to remove this?
<HttpPost()>
Function Edit(ByVal ovm As OrganizationViewModel)
Dim o As Organization
o = AutoMapper.Mapper.Map(Of OrganizationViewModel, Organization)(ovm)
For Each om In o.OrganizationMetrics
_db.OrganizationMetrics.Attach(om)
If om.Value = "removeMe" Then
_db.Entry(om).State = EntityState.Deleted
ElseIf om.Id = 0 Then
_db.Entry(om).State = EntityState.Added
Else
_db.Entry(om).State = EntityState.Modified
End If
Next
_db.Organizations.Attach(o) 'Error is thrown here
If (ModelState.IsValid) Then
_db.Entry(o).State = EntityState.Modified
_db.SaveChanges()
Return RedirectToAction("Index")
Else
Return View(ovm)
End If
End Function
UPDATE:
This is my now functioning code. The key is to not map the children entities back to the parent entity model from the view model, so that I can deal with them individually.
<HttpPost()>
Function Edit(ByVal ovm As OrganizationViewModel)
Dim o As Organization
o = AutoMapper.Mapper.Map(Of OrganizationViewModel, Organization)(ovm) //The Automapper code ignores the OrganizationMetrics members
_db.Organizations.Attach(o)
For Each om In ovm.OrganizationMetrics
_db.OrganizationMetrics.Attach(om)
If om.Value = "removeMe" Then
_db.Entry(om).State = EntityState.Deleted
ElseIf om.Id = 0 Then
_db.Entry(om).State = EntityState.Added
Else
_db.Entry(om).State = EntityState.Modified
End If
Next
If (ModelState.IsValid) Then
_db.Entry(o).State = EntityState.Modified
_db.SaveChanges()
Return RedirectToAction("Index")
Else
Return View(ovm)
End If
End Function
When you attach o with _db.Organizations.Attach(o), it goes through all its children and finds that some of them are deleted. When it tries to attach them, you get the error you're showing. It makes perfect sense.
Step back and figure out what it is you want to do. The easiest way to delete something is to get it and then delete it. Something like:
context.DeleteObject(context.MyEntity.Single(r => r.Id == myId));
If you want, you can mock the MyEntity object with just its key and then delete that object, it will work as well and save you a select query.

Redemption using filter on a custom datetime field in contacts

I'm having a problem using a filter on a custom date in contacts.
RDOItems Contacts = null;
string strSearch = string.Empty;
strSearch = AddQuotes("http://schemas.microsoft.com/mapi/string/{01234567-8901-2345-C678-901234567801}/CustomFieldString");
strSearch += " <> '' ";
strSearch += " AND ";
strSearch += AddQuotes("http://schemas.microsoft.com/mapi/string/{01234567-8901-2345-C678-901234567802}/CustomFieldDate");
strSearch += " < ";
strSearch += "'2010-04-28 18:00'";
Contacts = (RDOItems)synContacts.Items.Restrict(strSearch)
When i use only the first part of the filter (CustomFieldString) i get the right contacts, but when i expand the filter with the datetime field no contacts are returned.
Thanks,
Spitje
If the named MAPI property has a string as anid (as oppoosed to an integer), there is no way to specify the property type in the DASL name, so Redemption assumes string.
If the property was added to the folder fields, the property definition will be stored in a hidden message in that folder, and you can use just the property name (CustomFieldDate)
Otherwise you can you call GetIdsFromNames to figure out the property tag, "or" it with the appropriate type (PT_SYSTIME), then contruct the DASL name that looks like a regular (not named) MAPI property:
e.g. http://schemas.microsoft.com/mapi/proptag/0x80650040
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

Resources