Skip to main content
I have an aspx page that starts the process and enters data into a set of Process Data Fields. The next activity is aspx based and it loads up some fields with the data that has been entered and then has some additional fields that will be filled out and then stored in Process Data Fields.



Everything appears to be working correctly and I even can write the Process Data Fields back to the screen but when I attempt to use them in a line rule the data does not get saved back to the process when I complete the Worklist item.



I thought that Process Instance data remained within the process not the activity.



This appears to be working but the data does not get saved

if (_control.GetType() == typeof(RadioButtonList))

{


_controlName = _control.ID.ToString();

Response.Write(_controlName );



_pi.DataFields[_controlName].Value = ((RadioButtonList)Section2.FindControl(_controlName)).SelectedItem.Value.ToString();



Response.Write(_controlName + " = " + _pi.DataFields[_controlName].Value.ToString());


}

}

Did u use the K2.ProcessInstance.Update() method after setting the data for the data fields??

You do not need to call the ProcessInstance.Update() method, calling the WorklistItem.Actions[YourAction].Execute() will automatically save any updated fields.


I would try checking if something else isn't updating the fields after the update happen, maybe some code in a server event, etc. Enable Auditing for this field, it should tell you what and who makes the changes.


Something else that is also a common pitfall: if you use multiple slots for the same client event, users will overwrite each other's comments/updates. Only the last user's updates will be reflected. If you have a case where multiple users work on the same item, use Activity DataFields instead.


Maxpirate's solution worked. Not sure why the values were not getting updated on the Execute() command.

ProcessInstance.Update() requires the user to have admin server rights. I'd suggest dc's solution as WorklistItem.Actions[].Execute() does not require this.

It be good to understand why the Execute() isn't updating the fields. Are you able to post some sample code?


protected void Page_Load(object sender, EventArgs e)

{


string _controlName = "";

Connection _conn = new Connection();



_conn.Open(ConfigurationManager.AppSettings["K2Host"]);




ProcessInstance _pi = _conn.OpenProcessInstance(Utilities.getPID(Request.QueryString["SN"].ToString()));

try

{




foreach (Control _control in Section1.Controls)

{

if (_control.GetType() == typeof(TextBox))

{

_controlName = _control.ID.ToString();

((TextBox)Section1.FindControl(_controlName)).Text = _pi.DataFields[_controlName].Value.ToString();


}

if (_control.GetType() == typeof(DatePicker))

{

_controlName = _control.ID.ToString();

((DatePicker)Section1.FindControl(_controlName)).DateValue = Convert.ToDateTime(_pi.DataFields[_controlName].Value.ToString());


}


}




foreach (Control _control in Section2.Controls)

{

if (_control.GetType() == typeof(RadioButtonList))

{

_controlName = _control.ID.ToString();


((RadioButtonList)Section2.FindControl(_controlName)).SelectedValue = _pi.DataFields[_controlName].Value.ToString();


if (((RadioButtonList)Section2.FindControl(_controlName)).SelectedItem.Value == "3")

{

((RadioButtonList)Section2.FindControl(_controlName)).Enabled = false;

((RadioButtonList)Section2.FindControl(_controlName)).CssClass = "inputRO";

}


}

}


}


catch (Exception ex)

{

Response.Write("**** Error **** " + ex.Message.ToString() + "
" + ex.StackTrace.ToString());

}

finally

{

_conn.Close();

}


}


protected void Submit_Click(object sender, EventArgs e)

{

string _controlName = "";


Connection _conn = new Connection();


_conn.Open(ConfigurationManager.AppSettings["K2Host"]);



try

{

ProcessInstance _pi = _conn.OpenProcessInstance(Utilities.getPID(Request.QueryString["SN"].ToString()));



foreach (Control _control in Section2.Controls)

{

if (_control.GetType() == typeof(RadioButtonList))

{


_controlName = _control.ID.ToString();

_pi.DataFields[_controlName].Value = ((RadioButtonList)Section2.FindControl(_controlName)).SelectedItem.Value.ToString();



}

}

_pi.Update();


}


catch (Exception ex)

{

Response.Write("error " + ex.Message.ToString());

}



WorklistItem _wli = _conn.OpenWorklistItem(Request.QueryString["SN"], "asp");

_wli.Actions["Complete"].Execute();

}

Did you you know you have access to the ProcessInstance via the worklist item?  Instead of opening both, try opening just the worklistitem and then access the ProcessInstance datafields that way. 


Maybe it's just not included in this code sample, but always make sure you Dispose of any object (like the connection) that implements IDisposable.


Thanks moffutt.

I see the problem. Here's what is happening.

  1. An object called _pi is created and the datafields are changed/updated.
  2. A new object called _wli is created and you execute the action.

The problem is that _wli needs the updated datafields. It has no idea about _pi.

 

I've updated your code so you can see how to do it. See http://codepaste.net/pc1g2r

 

As you'll see in the code sample, and as David said, you can access the process instance from the worklist item itself. Best of all, it doesn't require admin rights.

I recommend you change the _conn.OpenProcessInstance() in Page_Load to _conn.OpenWorklistItem(Request.QueryStringn"SN"], "asp").ProcessInstance;

 

Let me know how you get on.


Well that makes perfect sense. I made the assumption if I created the objects from the same SN then they would interact with the same data. I appreciate all the help.

Reply