I have a custom comment activity which I'm updating in code and this used to work but has started failing recently. It creates the activity but when I try to retrieve it or execute SetStateResponse on it, I get "tk_comment With Id = 9a1686d1-7d9d-e611-80e3-00155d001104 Does Not Exist" - which doesn't make sense as I've just created it! The activity record shows up against the account but I can't click on it there or do anything (Record is unavailable - The requested record was not found or you do not have sufficient permissions to view it.).
This is the code I'm using. I'd love you to tell me I've made some simple mistake :)
using (_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig))
{
_serviceProxy.EnableProxyTypes();
try
{
tk_comment comment = new tk_comment();
int maxLength = 190; //subject has a max length of 200 characters
if (subject.Length > maxLength)
{
comment.Subject = subject.Substring(0, maxLength);
comment.Description = subject.Substring(maxLength, subject.Length - maxLength);
}
else
{
comment.Subject = subject;
}
comment.RegardingObjectId = entity.ToEntityReference();
comment.ActualStart = CommentDate;
comment.ActualEnd = CommentDate;
comment.ScheduledStart = CommentDate;
comment.ScheduledEnd = CommentDate;
Guid commentID = _serviceProxy.Create(comment);
try
{
tk_comment aComment = (tk_comment)_serviceProxy.Retrieve(tk_comment.EntityLogicalName, commentID, new ColumnSet(allColumns: true));
}
catch (Exception ex)
{
SingletonLogger.Instance.Error("Always an error here " + ex.Message);
}
Account test = (Account) _serviceProxy.Retrieve(Account.EntityLogicalName, entity.Id, new ColumnSet(allColumns: true));
// tk_comment newComment = (tk_comment)_serviceProxy.Retrieve(tk_comment.EntityLogicalName, commentID, new ColumnSet(allColumns: true));
SetStateRequest request = new SetStateRequest();
request.EntityMoniker = new EntityReference(tk_comment.EntityLogicalName, commentID);
request.State = new OptionSetValue((int) tk_commentState.Completed); //completed
request.Status = new OptionSetValue(2); //completed
SetStateResponse response = (SetStateResponse)_serviceProxy.Execute(request); //always an error here too
}
Appreciate any suggestions
Cheers, Mick
It seems like you don't have proper read permission of this custom activity entity.
OR You need to validate all the permissions of this custom entity.
Related
We have a plugin that uses the BookRequest & RescheduleRequest Methods to schedule Appointment & RecurringAppointmentMaster entities.
Recently I was tasked with implementing the ability to schedule multiple appts in a given timeslot.
So in researching this, I found some posts referring to resource capacity (in work hours) & setting the Effort field of the ActivityParty to 1.0 in the Appointment.
I thought, great this will be easy.
So I changed the plugin to store the effort:
activityParty = new Entity("activityparty");
activityParty["partyid"] = new EntityReference("systemuser", apptCaregiverId);
activityParty["effort"] = (Double)1.0;
But when I ran the code, the BookRequest returned this error that confused me: ErrorCode.DifferentEffort
I searched for ErrorCode.DifferentEffort, 2139095040, BookRequest, you name it found nothing useful.
What exactly does this error mean?
Why is it so difficult to schedule concurrent appointments in CRM?
This is what I learned the hard way, so maybe it will spare someone else some frustration.
I looked in the database & noticed that the activityparty entities associated with appointments all had the effort field set to 2139095040 and I wondered where that number was coming from? In a post unrelated to CRM, I found out the 2139095040 means 'positive infinity'.
I revisited the posts where they talk about setting the effort to 1.0 & realized that they were all referring to the ServiceAppointment entity (not Appointment) and then I finally stumbled on the list of error codes
Scheduling Error Codes
DifferentEffort = The required capacity of this service does not match the capacity of resource {resource name}.
Not exactly the truth, but whatever.
The real issue is the Appointment entity does not reference a Service, therefore the capacity of the non-existent service is ‘Positive Infinity’ (2139095040).
Setting the Effort equal to anything but 2139095040 throws this error.
It isn’t really checking the capacity of the resource here, it’s just saying that the non-existent service capacity must be = 2139095040
Anyway to get around this I removed the logic that sets the effort = 1.0 and when BookRequest or RescheduleRequest returns ErrorCode.ResourceBusy, I check the Capacity vs the # appts scheduled in that timeslot & if there is capacity left over, I force it to overbook by using Create or Update.
private Guid BookAppointment(Entity appointment, bool setState, out List<string> errors)
{
Guid apptId = Guid.Empty;
try
{
BookRequest request = new BookRequest
{
Target = appointment
};
BookResponse booked = (BookResponse)this.orgService.Execute(request);
apptId = ParseValidationResult(booked.ValidationResult, setState, appointment, true, out errors);
}
catch (Exception ex)
{
errors = new List<string> { ex.GetBaseException().Message };
}
return apptId;
}
private Guid RescheduleAppointment(Entity appointment, out List<string> errors)
{ // used to reschedule non-recurring appt or appt in recurrence
Guid apptId = Guid.Empty;
try
{
RescheduleRequest request = new RescheduleRequest
{
Target = appointment
};
RescheduleResponse rescheduled = (RescheduleResponse)this.orgService.Execute(request);
apptId = ParseValidationResult(rescheduled.ValidationResult, false, appointment, false, out errors);
}
catch (Exception ex)
{
errors = new List<string> { ex.GetBaseException().Message };
}
return apptId;
}
private Guid ParseValidationResult(ValidationResult result, bool setState, Entity appointment, Boolean addNew, out List<string> errors)
{
Guid apptId = result.ActivityId;
errors = new List<string>();
if (result.ValidationSuccess == true)
{
if (setState == true)
{
SetStateRequest state = new SetStateRequest();
state.State = new OptionSetValue(3); // Scheduled
state.Status = new OptionSetValue(5); // Busy
state.EntityMoniker = new EntityReference("appointment", apptId);
SetStateResponse stateSet = (SetStateResponse)this.orgService.Execute(state);
}
}
else
{
String error;
String errortxt;
Boolean overbookAppt = true;
foreach (var errorInfo in result.TraceInfo.ErrorInfoList)
{
bool unavailable = false;
if (errorInfo.ErrorCode == "ErrorCode.ResourceNonBusinessHours")
{
errortxt = "{0} is being scheduled outside work hours";
}
else if (errorInfo.ErrorCode == "ErrorCode.ResourceBusy")
{
errortxt = "{0} is unavailable at this time";
unavailable = true;
}
else
{
errortxt = "failed to schedule {0}, error code = " + errorInfo.ErrorCode;
}
Dictionary<Guid, String> providers;
Dictionary<Guid, String> resources;
DateTime start = DateTime.Now, end = DateTime.Now;
Guid[] resourceIds = errorInfo.ResourceList.Where(r => r.EntityName == "equipment").Select(r => r.Id).ToList().ToArray();
if (unavailable == true)
{
if (appointment.LogicalName == "recurringappointmentmaster")
{
start = (DateTime)appointment["starttime"];
end = (DateTime)appointment["endtime"];
}
else
{
start = (DateTime)appointment["scheduledstart"];
end = (DateTime)appointment["scheduledend"];
}
Dictionary<Guid, Boolean> availability = GetAvailabilityOfResources(resourceIds, start, end);
resourceIds = availability.Where(a => a.Value == false).Select(t => t.Key).ToArray(); // get ids of all unavailable resources
if (resourceIds.Count() == 0)
{ // all resources still have capacity left at this timeslot - overbook appt timeslot
overbookAppt = true;
} // otherwise at least some resources are booked up in this timeslot - return error
}
if (errortxt.Contains("{0}"))
{ // include resource name in error msg
if (resourceIds.Count() > 0)
{
LoadProviderAndResourceInfo(resourceIds, out providers, out resources);
foreach (var resource in providers)
{
error = String.Format(errortxt, resource.Value);
errors.Add(error);
}
foreach (var resource in resources)
{
error = String.Format(errortxt, resource.Value);
errors.Add(error);
}
}
}
else
{ // no place for name in msg - just store it
errors.Add(errortxt);
break;
}
}
if (overbookAppt == true && errors.Count() == 0)
{ // all resources still have capacity left at this timeslot & no other errors have been returned - create appt anyway
if (addNew)
{
appointment.Attributes.Remove("owner"); // Create message does not like when owner field is specified
apptId = this.orgService.Create(appointment);
if (setState == true)
{
SetStateRequest state = new SetStateRequest();
state.State = new OptionSetValue(3); // Scheduled
state.Status = new OptionSetValue(5); // Busy
state.EntityMoniker = new EntityReference("appointment", apptId);
SetStateResponse stateSet = (SetStateResponse)this.orgService.Execute(state);
}
}
else
{
this.orgService.Update(appointment);
}
}
}
return apptId;
}
private Dictionary<Guid, Boolean> GetAvailabilityOfResources(Guid[] resourceIds, DateTime start, DateTime end)
{
Dictionary<Guid, Boolean> availability = new Dictionary<Guid, Boolean>();
QueryMultipleSchedulesRequest scheduleRequest = new QueryMultipleSchedulesRequest();
scheduleRequest.ResourceIds = resourceIds;
scheduleRequest.Start = start;
scheduleRequest.End = end;
// TimeCode.Unavailable - gets appointments
// TimeCode.Filter - gets resource capacity
scheduleRequest.TimeCodes = new TimeCode[] { TimeCode.Unavailable, TimeCode.Filter };
QueryMultipleSchedulesResponse scheduleResponse = (QueryMultipleSchedulesResponse)this.orgService.Execute(scheduleRequest);
int index = 0;
TimeInfo[][] timeInfo = new TimeInfo[scheduleResponse.TimeInfos.Count()][];
foreach (var schedule in scheduleResponse.TimeInfos)
{
TimeInfo resourceCapacity = schedule.Where(s => s.SubCode == SubCode.ResourceCapacity).FirstOrDefault();
Int32 capacity = (resourceCapacity != null) ? (Int32)resourceCapacity.Effort : 1;
Int32 numAppts = schedule.Where(s => s.SubCode == SubCode.Appointment).Count();
// resource is available if capacity is more than # appts in timeslot
availability.Add(resourceIds[index++], (capacity > numAppts) ? true : false);
}
return availability;
}
This is really a better solution than setting the Effort = 1 anyway because now we don’t need a one-time on-demand workflow to update existing data.
I hope this helps save you some time if you ever need to do this.
I am seeing errors while exporting email in office 365 account using ews managed api, "The server cannot service this request right now. Try again later." Why is that error occurring and what can be done about it?
I am using the following code for that work:-
_GetEmail = (EmailMessage)item;
bool isread = _GetEmail.IsRead;
sub = _GetEmail.Subject;
fold = folder.DisplayName;
historicalDate = _GetEmail.DateTimeSent.Subtract(folder.Service.TimeZone.GetUtcOffset(_GetEmail.DateTimeSent));
props = new PropertySet(EmailMessageSchema.MimeContent);
var email = EmailMessage.Bind(_source, item.Id, props);
bytes = new byte[email.MimeContent.Content.Length];
fs = new MemoryStream(bytes, 0, email.MimeContent.Content.Length, true);
fs.Write(email.MimeContent.Content, 0, email.MimeContent.Content.Length);
Demail = new EmailMessage(_destination);
Demail.MimeContent = new MimeContent("UTF-8", bytes);
// 'SetExtendedProperty' used to maintain historical date of items
Demail.SetExtendedProperty(new ExtendedPropertyDefinition(57, MapiPropertyType.SystemTime), historicalDate);
// PR_MESSAGE_DELIVERY_TIME
Demail.SetExtendedProperty(new ExtendedPropertyDefinition(3590, MapiPropertyType.SystemTime), historicalDate);
if (isread == false)
{
Demail.IsRead = isread;
}
if (_source.RequestedServerVersion == flagVersion && _destination.RequestedServerVersion == flagVersion)
{
Demail.Flag = _GetEmail.Flag;
}
_lstdestmail.Add(Demail);
_objtask = new TaskStatu();
_objtask.TaskId = _taskid;
_objtask.SubTaskId = subtaskid;
_objtask.FolderId = Convert.ToInt64(folderId);
_objtask.SourceItemId = Convert.ToString(_GetEmail.InternetMessageId.ToString());
_objtask.DestinationEmail = Convert.ToString(_fromEmail);
_objtask.CreatedOn = DateTime.UtcNow;
_objtask.IsSubFolder = false;
_objtask.FolderName = fold;
_objdbcontext.TaskStatus.Add(_objtask);
try
{
if (counter == countGroup)
{
Demails = new EmailMessage(_destination);
Demails.Service.CreateItems(_lstdestmail, _destinationFolder.Id, MessageDisposition.SaveOnly, SendInvitationsMode.SendToNone);
_objdbcontext.SaveChanges();
counter = 0;
_lstdestmail.Clear();
}
}
catch (Exception ex)
{
ClouldErrorLog.CreateError(_taskid, subtaskid, ex.Message + GetLineNumber(ex, _taskid, subtaskid), CreateInnerException(sub, fold, historicalDate));
counter = 0;
_lstdestmail.Clear();
continue;
}
This error occurs only if try to export in office 365 accounts and works fine in case of outlook 2010, 2013, 2016 etc..
Usually this is the case when exceed the EWS throttling in Exchange. It is explain in here.
Make sure you already knew throttling policies and your code comply with them.
You can find throttling policies using Get-ThrottlingPolicy if you have the server.
One way to solve the throttling issue you are experiencing is to implement paging instead of requesting all items in one go. You can refer to this link.
For instance:
using Microsoft.Exchange.WebServices.Data;
static void PageSearchItems(ExchangeService service, WellKnownFolderName folder)
{
int pageSize = 5;
int offset = 0;
// Request one more item than your actual pageSize.
// This will be used to detect a change to the result
// set while paging.
ItemView view = new ItemView(pageSize + 1, offset);
view.PropertySet = new PropertySet(ItemSchema.Subject);
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
view.Traversal = ItemTraversal.Shallow;
bool moreItems = true;
ItemId anchorId = null;
while (moreItems)
{
try
{
FindItemsResults<Item> results = service.FindItems(folder, view);
moreItems = results.MoreAvailable;
if (moreItems && anchorId != null)
{
// Check the first result to make sure it matches
// the last result (anchor) from the previous page.
// If it doesn't, that means that something was added
// or deleted since you started the search.
if (results.Items.First<Item>().Id != anchorId)
{
Console.WriteLine("The collection has changed while paging. Some results may be missed.");
}
}
if (moreItems)
view.Offset += pageSize;
anchorId = results.Items.Last<Item>().Id;
// Because you’re including an additional item on the end of your results
// as an anchor, you don't want to display it.
// Set the number to loop as the smaller value between
// the number of items in the collection and the page size.
int displayCount = results.Items.Count > pageSize ? pageSize : results.Items.Count;
for (int i = 0; i < displayCount; i++)
{
Item item = results.Items[i];
Console.WriteLine("Subject: {0}", item.Subject);
Console.WriteLine("Id: {0}\n", item.Id.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine("Exception while paging results: {0}", ex.Message);
}
}
}
I need to get the master appointment of the meeting series, when an appointment instance is opened.
I have tried the following (currentAppointment variable is of type AppointmentItem)
DateTime sd = currentAppointment.GetRecurrencePattern().PatternStartDate;
DateTime st = currentAppointment.GetRecurrencePattern().StartTime;
AppointmentItem ai = currentAppointment.GetRecurrencePattern().GetOccurrence(sd+st.TimeOfDay);
However, while this gets me the first appointment in the series, it has a RecurrenceState of olApptOccurrence.
How can I get a reference to the olApptMaster - ie the meeting series?
AppointmentItem.Parent will return the parent AppointmentItem for the recurrence instances and exceptions.
I have a method to create an appointment item with recurrence, but it´s almost the same as modifying one, tell me if that helps you and if you need further information.
Here is the code in C#
private void CreateNewRecurringAppointment(Outlook._Application OutlookApp)
{
Outlook.AppointmentItem appItem = null;
Outlook.RecurrencePattern pattern = null;
try
{
appItem = OutlookApp.CreateItem(Outlook.OlItemType.olAppointmentItem)
as Outlook.AppointmentItem;
// create a recurrence
pattern = appItem.GetRecurrencePattern();
pattern.RecurrenceType = Outlook.OlRecurrenceType.olRecursWeekly;
pattern.StartTime = DateTime.Parse("9:00:00 AM");
pattern.EndTime = DateTime.Parse("10:00:00 AM");
// we can specify the duration instead of using the EndTime property
// pattern.Duration = 60;
pattern.PatternStartDate = DateTime.Parse("11/11/2011");
pattern.PatternEndDate = DateTime.Parse("12/25/2011");
appItem.Subject = "Meeting with the Boss";
appItem.Save();
appItem.Display(true);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
if (pattern != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pattern);
if (appItem != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(appItem);
}
}
source: http://www.add-in-express.com/creating-addins-blog/2011/11/07/outlook-recurring-appointment/
I'm trying to implement windows azure table storage...but I'm getting 'Table Not Found'
Here is my connection string(How post I xml here?)(sorry for links)
ServiceConfiguration.Cloud.cscfg:
http://pastebin.com/F9tuckfT
ServiceConfiguration.Local.cscfg:
http://pastebin.com/XZHEvv6g
and here there's a print screen from my windows azure portal
http://s20.postimage.org/nz1sxq7hp/print.png
The code(sorry for the longer code...but there's three pages...Login works, when I log in, go to main.aspx that call grid.aspx ...In grid.aspx I get the error "Table not found" All this code is important for the question.....) http://pastebin.com/RnuvvqsM
I have tried
private void popula()
{
var account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("Conn"));
account.CreateCloudTableClient().CreateTableIfNotExist("fiscal");
var context = new CRUDManifestacoesEntities(account.TableEndpoint.ToString(), account.Credentials);
Hashtable ht = (Hashtable)ViewState["filtro"];
if (ht == null)
GridView1.DataSource = context.SelectConc(ViewState["x"].ToString());
else
GridView1.DataSource = context.SelectConc(ht);
GridView1.DataBind();
}
but it doesn't work too
Other error similar is when I try to add a USER in table
public string addusr(string nome, string cidade, string cpf, string email, string telefone)
{
try
{
if (nome.Length == 0)
return "f:Preencha o campo nome.";
if (cidade.Length == 0)
return "f:Preencha o campo cidade.";
if (cpf.Length == 0)
return "f:Preencha o campo cpf.";
if (!Valida(cpf))
return "f:CPF Invalido.";
if (email.Length == 0)
return "f:Preencha o campo email.";
Regex rg = new Regex(#"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)#([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$");
if (!rg.IsMatch(email))
{
return "f:Email Invalido";
}
List<UserEntity> lst = new List<UserEntity>();
var _account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("Conn"));
_account.CreateCloudTableClient().CreateTableIfNotExist("fiscal");
var _context = new CRUDUserEntities(_account.TableEndpoint.ToString(), _account.Credentials);
var account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("Conn"));
account.CreateCloudTableClient().CreateTableIfNotExist("fiscal");
var context = new CRUDUserEntities(account.TableEndpoint.ToString(), account.Credentials);
UserClientEntity entity = new UserClientEntity() { nome = nome, cidade = cidade, cpf = cpf, email = email, telefone = telefone };
context.ADDUSociate(entity);
context.SaveChanges();
return "k";
}
I'm getting this error:
f:An error occurred while processing this request.| at System.Data.Services.Client.DataServiceContext.SaveResult.HandleBatchResponse()
at System.Data.Services.Client.DataServiceContext.SaveResult.EndRequest()
at System.Data.Services.Client.DataServiceContext.SaveChanges(SaveChangesOptions options)
at AzureTableLayer.CRUDUserEntities.ADDUSociate(UserClientEntity entity)
at mobile.Service1.addusr(String nome, String cidade, String cpf, String email, String telefone)
I believe that the two problems are related
EDIT: I have debugged and discovered that the StorageClient framework could not be loaded...
I'm getting this error Could not load file or assembly Microsoft.WindowsAzure.StorageClient, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
How to solve?
How are you trying to work with Table Storage? Trought the .NET SDK? PHP? Java? Node? ... Typically if you get this error it means that... the table does not exist.
Check the SDK you're using for a method similar to CreateIfNotExists in order to create the table before you start using it.
Edit:
The issue probably happens here:
var account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("Conn"));
var context = new CRUDManifestacoesEntities(account.TableEndpoint.ToString(), account.Credentials);
Hashtable ht = (Hashtable)ViewState["filtro"];
if (ht == null)
GridView1.DataSource = context.SelectConc(ViewState["x"].ToString());
else
GridView1.DataSource = context.SelectConc(ht);
Add the following code after the var account = ... line:
account.CreateCloudTableClient().CreateTableIfNotExist("<name of your table>");
The API has been changed. you need to do it like this:
var key = CloudConfigurationManager.GetSetting("Setting1");
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(key);
var client = storageAccount.CreateCloudTableClient();
CloudTable table = client.GetTableReference(ContactTableName);
table.CreateIfNotExists();
I'm trying to upload photos into Facebook by using MVC3 C#. The code is running successfully but the photos are not uploaded into Facebook. I'm having add ID and App Secret. I tried many ways and for many days I worked hard, but the result is zero. Here is the code of my controller
[HttpPost][HttpGet]
public ActionResult Profile(HttpPostedFileBase file, FacebookOAuthResult facebookOAuthResult) {
dynamic args = new ExpandoObject();
args = new Dictionary<string, object>();
args["message"] = "hi";
args["picture"] = "http://apps.facebook.com/Uploads/photos";
string accesstoken=FacebookWebContext.Current.AccessToken;
FacebookClient fbApp = new FacebookClient(accesstoken);
try {
fbApp.Post("MYAPPID" + "/Photos", args);
} catch (FacebookOAuthException ex) {
//
}
// Verify that the user selected a file
if (file != null && file.ContentLength > 0) {
var path1 = Path.Combine(Server.MapPath("~/Content/uppoads"), file.FileName);
//file.SaveAs(path1);
fbApp.Post("MYAPPID" + "/photos", path1);
}
// redirect back to the index action to show the form once again
return RedirectToAction("Profile");
}
Could anyone help me to find the solution? Thanks in advance.
You are Post the local path of the photo to Facebook, FB doesn't know what it is.
You should post the photo as binary in the Post body.
var media = new Facebook.FacebookMediaObject();
var filebytes = System.IO.File.ReadAllBytes(path1);
media.SetValue(filebytes);
fbApp.Post("248050331932489" + "/photos", media);