Edit Existing Content Item
I'm trying to edit an existing Event through the fluent API. When I load the event properties in my custom form, they appear updated, but the changes are not showing up in the Sitefinity backend. Can someone point out what I am doing incorrectly? Here is my code used to update the event properties and resave them.
public
void
PersistEvent()
Guid id = calendarEvent.Id;
App.Prepare().SetContentProvider(contentProviderName)
.WorkWith().Events()
.Where(ev => ev.Id == id)
.ForEach(ev =>
ev.Title = eventDetailCtl.txtEventName.Text;
ev.Description = eventDetailCtl.txtDescription.Text;
ev.EventStart = eventDetailCtl.dtEventBegin.SelectedDate.HasValue ?
eventDetailCtl.dtEventBegin.SelectedDate.Value :
ev.EventStart;
ev.EventEnd = eventDetailCtl.dtEventEnd.SelectedDate.HasValue ?
eventDetailCtl.dtEventEnd.SelectedDate.Value :
ev.EventEnd;
ev.Street = eventDetailCtl.txtStreet.Text;
ev.City = eventDetailCtl.txtCity.Text;
ev.State = eventDetailCtl.txtState.Text;
ev.ContactEmail = eventDetailCtl.txtEmail.Text;
ev.ContactWeb = eventDetailCtl.txtWebsite.Text;
ev.ContactName = eventDetailCtl.txtContactName.Text;
ev.ContactPhone = eventDetailCtl.txtContactPhone.Text;
)
.SaveChanges();
Does anyone from Telerik have any input on this issue? Is the issue caused by something I am doing incorrectly or a bug in the API?
Thanks.
Hi Geoff,
Can you check whether the data is persisted inside [sf_events] table?
Greetings,
Ivan Dimitrov
the Telerik team
The fields are not updated in the [sf_events] table.
The updates do not appear in the Sitefinity backend, but they do appear on my frontend page. This applies to standard and custom fields. I assume the changes are being persisted in a different table, since they are applied to wherever my content is loaded from on the frontend page.
Thanks.
I had to do a database restore for another issue and decided to look at this issue again afterwards. The new values are now showing up in the sf_events table, for whatever reason. I'm not sure what I have changed that would have affected it. I'm not sure what information you want to see from the table, but I noticed approval_workflow_state is Published and content_state is NULL. A row with the previous value has content_state as Published.
What causes content_state to be set? Ideally the updated event would be resubmitted to my workflow for another approval.
Here is my current code:
public
void
PersistEvent()
Guid id = calendarEvent.Id;
App.Prepare().SetContentProvider(contentProviderName)
.WorkWith().Events()
.Where(ev => ev.Id == id)
.ForEach(ev =>
ev.Title = eventDetailCtl.txtEventName.Text;
ev.Description = eventDetailCtl.txtDescription.Content;
ev.EventStart = eventDetailCtl.dtEventBegin.SelectedDate.HasValue ?
eventDetailCtl.dtEventBegin.SelectedDate.Value :
ev.EventStart;
ev.EventEnd = eventDetailCtl.dtEventEnd.SelectedDate.HasValue ?
eventDetailCtl.dtEventEnd.SelectedDate.Value :
ev.EventEnd;
ev.Street = eventDetailCtl.txtStreet.Text;
ev.City = eventDetailCtl.txtCity.Text;
ev.State = eventDetailCtl.txtState.Text;
ev.Country = eventDetailCtl.txtCountry.Text;
ev.ContactEmail = eventDetailCtl.txtEmail.Text;
ev.ContactWeb = eventDetailCtl.txtWebsite.Text;
ev.ContactName = eventDetailCtl.txtContactName.Text;
ev.ContactPhone = eventDetailCtl.txtContactPhone.Text;
)
.SaveChanges();
if
(id != Guid.Empty)
SubmitEventToWorkflow(id);
private
void
SubmitEventToWorkflow(Guid eventID)
Event eventItem = App.WorkWith().Events().Where(ev => ev.Id == eventID).Get().FirstOrDefault();
var masterId = eventItem.OriginalContentId;
EventsManager.GetManager().RecompileItemUrls<Event>(eventItem);
if
(eventItem.Status == ContentLifecycleStatus.Master)
EventsManager.GetManager().CheckOut(eventItem);
masterId = eventItem.Id;
EventsManager.GetManager().SaveChanges();
var contextBag =
new
Dictionary<
string
,
string
>();
contextBag.Add(
"ContentType"
, eventItem.GetType().FullName);
WorkflowManager.MessageWorkflow(
masterId,
eventItem.GetType(),
EventsManager.GetDefaultProviderName(),
"SendForApproval"
,
false
,
contextBag);
Ivan,
What is the relevance of the data showing up in the sf_events table? Project completion is waiting on this issue and an issue open in another thread to get resolved, so a prompt resolution would be appreciated. What are the next steps to get this issue resolved?
Thanks.
Does anyone on the Telerik team have any input on this issue?
Thanks.
Hi Geoff,
We are very sorry for this delayed answer.
There are three lifecycle states for each content item: Master, Live and Temp and for every content item there may be three rows with data. You can read more about these states here. The problem in your first code is that you edit directly the Live item instead of modifying the Master item and then publishing it. That's why you can see the changes in the frontend but the backend is not affected. The Sitefinity workflow besides the changing of the workflow status also manages the lifecycle status and that's why your second code works.I suppose you are using the Sitefinity documentation to assemble your code. But you would better use the sample for single item instead of the one for multiple items:
public
void
EditEvent(Guid itemID,
string
newContent)
App.WorkWith()
.Event(itemID)
.CheckOut()
.Do(e =>
e.Content = newContent;
e.LastModified = DateTime.UtcNow;
)
.CheckIn()
.SaveChanges();
.CheckIn()
.Publish()
.SaveChanges();
Thank you for responding to my issue, Ivan. Explaining the lifecycle states helped a lot. I am now editing the Master and am able to update the content item and have the changes show up in the Sitefinity backend. However, I cannot get the event to be resubmitted to my workflow.
Here is my code for resubmitting the event to the workflow, which is used successfully on event creation:
private
void
SubmitEventToWorkflow(Event eventItem)
var masterId = eventItem.OriginalContentId;
EventsManager eventsManager = EventsManager.GetManager();
eventsManager.RecompileItemUrls<Event>(eventItem);
if
(eventItem.Status == ContentLifecycleStatus.Master)
eventsManager.CheckOut(eventItem);
masterId = eventItem.Id;
eventsManager.SaveChanges();
var contextBag =
new
Dictionary<
string
,
string
>();
contextBag.Add(
"ContentType"
, eventItem.GetType().FullName);
WorkflowManager.MessageWorkflow(
masterId,
eventItem.GetType(),
EventsManager.GetDefaultProviderName(),
"SendForApproval"
,
false
,
contextBag);
Hello Geoff,
Thank you for coming back to us.
This error often appears if you get a data item within one transaction and try to edit and save it in another transaction. In these cases you should retrieve the data item again so that the changes to be part of one transaction.
private
void
SubmitEventToWorkflow(Event eventItem)
EventsManager eventsManager = EventsManager.GetManager();
var eventItem2 = eventsManager.GetEvent(eventItem.Id);
// continue work with eventItem2
// ...
Ivan, thanks for your help so far. I updated my SubmitToWorkflow method with your code and I am no longer getting the error, however I am now having another issue. The event is being saved correctly, but is not properly entering the workflow.
With the following piece of code:
if
(eventItem.Status == ContentLifecycleStatus.Master)
eventsManager.CheckOut(eventItem);
masterId = eventItem.Id;
Hi Geoff,
Thank you for coming back to us.
I am not sure what you are trying to do. You are calling the workflow with "SendForApproval" operation but you want it to be published. You would better call it with "Publish" workflow operation. When you call the workflow you should pass the id of the master version.
If you want to change an item then you check it out, perform the changes to the temp version and then call CheckIn for the temp version. Checking the temp version in will copy the data of the temp to the master version. You may make changes to the master version directly but the more proper way is to go from master to temp and then back to master version.
Greetings,
Ivan Pelovski
the Telerik team
Sorry for the confusion. My process is this:
A frontend user can view and edit an existing event. Upon editing the event, the user submits the event for publishing. This event enters the workflow and must be approved before being published. A user of an approved role can view the event through the Sitefinity backend and then publish the event through the backend.
So I'm only looking for workflow submission from the frontend. The publishing can take place through the workflow on the Sitefinity backend. My original problem was that events were not entering the workflow (as they are still not) and the changes to metadata were not showing up on the backend (because I was modifying the wrong version of the event). The changes appearing on the frontend were an unwanted side effect of me editing the wrong version of the event.
Currently the changes are appearing in the backend, and I would like these changes to be published until they have been approved in the workflow.
I hope this makes more sense.
So my question is, how is submitting a newly created event to a workflow different from submitting an existing, edited event to a workflow? I cannot get my workflow submission code, which works on newly created events, to work correctly on already existing events.
Thanks.
Hi Geoff,
Some of the item's states will not allow to you to edit them and you have to check this before you allow the user to modify them. If you enter in edit mode of the item , the item should be in draft state according our workflow logic. When a user save the item it should be in awaiting approval state. You can use WorkflowMenu control or the other way is to implement your custom code for this. Manually you could invoke the workflow with this code :
The workflowOperation
value should be equal to the value of the FlowSwitchLink (see the attached file)
if (content.SupportsContentLifecycle && !string.IsNullOrEmpty(workflowOperation))
var item = this.Manager.CheckOut(content);
this.Manager.SaveChanges();
var contextBag = new Dictionary<
string
, string>();
contextBag.Add("ContentType", item.GetType().FullName);
contextBag.Add("MasterId", content.Id.ToString());
WorkflowManager.MessageWorkflow(
item.Id,
content.GetType(),
providerName,
workflowOperation,
false,
contextBag
);
Teodor, I used the code that you provided in the last post and received the same results. The event is updated, but is locked by the user and is not submitted to the workflow.
You said the item should be in "draft state" for editing and workflow submission. Is this the same as Temp Lifecycle State? I was previously told that I should be editing the Master version of the event in this post.
I assume
var item =
this
.Manager.CheckOut(content);
WorkflowManager.MessageWorkflow(
item.Id,
content.GetType(),
providerName,
workflowOperation,
false
,
contextBag
);
Hello Geoff,
I am sorry for the late response.
1. I attached the current workflows, because I understood that they are not distributed with the download (we will fix this).
2. Take a look into one of the workflow and you will see the following:
You have an entry point in the workflow. After that you have a switch for the workflow type(Default , StandardOneStep,StandardTwoSteps). Lets see the OneLevelApprovalWorkflow:
Here we also have a switch but this switch is based on the ItemState (Draft,Unpublished,Rejected , AwaithingArrpoval ... )
Depending on the state, you go to Default Workflow, Pending, Approval Workflow Or Published Workflow.
Lets see the published workflow:
There is a switch but now it is based on ItemAction (SaveAsDraft,Unpublish, Delete ... etc ).
So basically to apply an action over an item it should be in a state that allows to apply this action. For example if the item is in Published State, it couldn't go in Awaiting Approval state, unless you implement the specific logic. You can also do it manually by adding a WorkflowRecord to the Item and manually put the item in specific state, but I'd not not recommend this.
I hope this helps.
Regards,
Teodor
the Telerik team
What program should I use to open the files? When I try to open them in Visual Studio 2010, I get the attached error in the designer window ("Activity could not be loaded because of errors in the XAML").
Thanks.
Hi Geoff,
I think the reason for this exception is that you don't have the proper DLLS ( possibly the Sitefinity dlls ) in the project that you add the workflows. I think you should try to include the xamlx files in the sitefinity web application project and this should fix this problem.
Regards,
Teodor
the Telerik team