vinmore - Thursday, May 2, 2013 8:33 AM:
Hi all,
I have read Programmers Guide and some Wikis to understand Classes and Methods usage for Server methods. But still I have some doubts on using the Innovator object inside a Method. Here I' m mentioning a small example.
public class Test { ////Kindly ignore the syntax errors if any
public string GetItemName(Innovator inn); {
Item part = inn.newItem("Part","get");
part.setAttribute("where","[PART].item_number like 'PRT-001' " );
Item res_part = part.apply(); string part_name = res_part.getProperty("name"); return part_name; }
public static void main(){
Test t = new Test(); ///Instance ///// Call the GetItemName method
//// I want to store the Method return value in a temporary variable to use inside Main()
String new_name = t.GetItemName( inn); ///Here I" m confused with what the parameter to be passed
} /// Error states that 'inn' does' t exists in current context
How can I use the GetItemName method' s return value inside Main()?
What should be the Parameter to be passed here? And what happens if I declare static Main() as an entry point to the Method?
Thanks in advance, Vin
vinmore - Friday, May 3, 2013 1:52 AM:
Kindly some one help me, How can I use method's return value inside Main() ?
vinmore - Friday, May 3, 2013 3:56 AM:
How can I call Innovator object from Main() in C#? Innovator inn = new Innovator();
Programmers Guide: 7.1 Create an Aras Innovator Object says: There are basically two ways to create a new Innovator object; by getting the Innovator from the Item object or (only in JavaScript) calling the Class constructor.
C#: Innovator myInnovator = this.getInnovator();
Where 'this' is not valid inside a method. So, How can I call Innovator object? I tried in the above way but no luck!
Please help me.
Brian - Friday, May 3, 2013 12:20 PM:
Hi Vinmore,
I think you have read the article on the Wiki http://www.aras.comhttp://www.aras.com/Community/wikis/kb/using-classes-inside-server-methods.aspx but maybe missed an important point.
When you want to use Innovator class inside your own class you need to pass Innovator as a ref.
So when you are inside an Innovator Server method:
Innovator inn = this.getInnovator();
Foo f = new Foo();
Item myItem = f.create(ref inn,string type);
return myItem;
}
public class Foo{
public Item create(ref Innovator inn, string type){
Item itm = inn.newItem(type,"add");
itm.setProperty("name","My New Item");
itm = itm.apply();
return itm;
}
//} closing class bracket is not required.
So the important thing is to pass the Innovator object by Reference.
Hope this helps,
Brian.
Brian - Friday, May 3, 2013 12:21 PM:
Hi Vinmore,
In my code above I missed declaring the "string type" in the code.
Sorry.
Brian.
vinmore - Monday, May 6, 2013 2:55 AM:
Hi Brian, thanks for your example and explanation. After using 'ref' I' m getting the desired output. That is fine.
But, I need to use the output value inside my Main() / another method. Like:
Innovator inn = this.getInnovator();
Foo f = new Foo();
Item myItem = f.create(ref inn,"Part");
return myItem; // I want to use This value inside Main() //
}
public class Foo{
public Item create(ref Innovator inn, string type){
Item itm = inn.newItem(type,"get");
itm.setAttribute("where","[PART].name like 'part1' ");
itm = itm.apply();
return itm;
}
public static void Main() {
Item prt_item = myItem // This is what I have been asking //
}
This is not happening.
Even I tried creating instance for class inside Main() to call the method(As I mentioned in the starting question of this post) . With this it throws : 'inn' does' t exists in current context, Argument '1': cannot convert from 'ref inn' to 'ref Aras.IOM.Innovator' . How to solve this?
Thank you.
Eric Domke - Monday, May 6, 2013 8:58 PM:
To understand what is going on, look at the method_config.xml file on the server, if you look into the file you will see that your code is wrapped in a class similar to:
namespace $(pkgname)
{
public class ItemMethod : Item
{
public ItemMethod(IServerConnection arg) : base(arg) {}
public Item methodCode()
{
Aras.Server.Core.CallContext CCO = ((Aras.Server.Core.IOMConnection) serverConnection).CCO;
$(MethodCode)
}
}
}
Therefore, there is no static main subroutine which gets called like a traditional compiled program. Rather, the methodCode() function showed above gets called which contains your method code. You can add classes by fooling this template into thinking that the function is closed and then creating a class definition. If you imagine pasting Brian's code into this template, you should see that it works and produces the result that you want.
vinmore - Wednesday, May 8, 2013 8:51 AM:
Thanks Eric and Brian, Now I understood the flow of the program. Instead Main() I used a normal Met(), no issues now.
vinmore - Friday, May 10, 2013 6:14 AM:
A small issue again, Here is the sample code:
public void Test(ref Innovator inn){
Item doc = inn.newItem("Document","get");
doc.setID(doc.getID());
doc=doc.apply();
string num = doc.getProperty("item_number");
return inn.newError(num); }
I added an Action (Item , target as none) with a method(with the above code). When I select this Action for a Document Item it says 'Not a single Item'. But the following code(without classes and methods usage) works well.
Innovator inn = this.getInnovator();
Item doc = this.newItem("Document","get");
doc.setID(this.getID());
doc=doc.apply();
string num = doc.getProperty("item_number");
return inn.newError(num);
What is causing this issue?
Thank you.
Brian - Friday, May 10, 2013 6:31 AM:
rnnlib.wikinet.org/.../Main_PageHi Vinmore,
The line
doc.setID (doc.getID)
Is giving you the problem.
Doc is a new item that does not have an ID.
You either need to pass in an ID or something else to search against.
The error not a single item indicates that you are getting either an error or a collection. it is good practice to test the returns from the apply () method for errors or collectioins.
Hope this helps.
Brian
vinmore - Monday, May 13, 2013 2:52 AM:
Thanks Brian, 'where' condition works well to search a particular item. If I want to get a selected Item' s properties then I need something similar to this.getProperty(). But this is not possible here inside a method. How can I solve this?
Brian - Monday, May 13, 2013 7:23 AM:
Hi Vinmore,
Can you tell me more about what you are trying to achieve?
I'm not sure you are going about whatever it is the best way.
If you can give me some more details then I might be able to help you come up with a better solution or be able to give you a bit more help.
If you are only trying to do some simple data retrieval based on properties or relationships then you may not need classes at all.
You can pass Items to a method the same way you pass Innovator, as a ref. If you pass an Item in then you can use all of the normal Item methods like itm.getProperty(...)
Brian.
vinmore - Monday, May 13, 2013 9:25 AM:
Hi Brian,
We need our Documents in Innovator need to be send to a third party application for review. Outside Aras we use some API calls to Send our Docs to Third party application.
Now we have been trying to send the Docs from Aras Innovator directly. So, I' m trying to create a method in Aras which takes a selected document to the other app using the same APIs. API codes are about 300 lines and with many classes and methods. For doing this:
I created an action for Documents and added a method to the Action. Click on the Action for a Doc will do 1)Get the related file of the Document and download that to the local folder. 2)Take the downloaded file out side the Aras.
As I mentioned in the above I' m not able to perform the step1. I' m inside a method:
public void Test(ref Innovator inn) {
Item doc = inn.newItem("Document","get");
doc.setID(doc.getID());
doc=doc.apply();
string item_id = doc.getProperty("id");
Item related_file = inn.newItem("File","get");
related_file.setAttribute("where","[FILE].id in(select related_id from [DOCUMENT_FILE] where source_id = '"+item_id+"')");
Item result1 = related_file.apply();
string file_id = result1.getProperty("id");
result1.checkout("C:\Docs");
string file_name = result1.getProperty("filename");
/////code for step 2: takes the downloaded document out side Aras.
}
As I mentioned in the previous post I' m getting 'Not a Single Item' , If I perform the Action. Without using the Classes and Methods I can' t make all the code work efficient . Even If you check my other post http://www.aras.comhttp://www.aras.com/Community/forums/t/4124.aspx , here also I' m facing the same issue. As you said I can' t call this.getProperty(); for getting the JS variable into the C#.
Eric Domke - Monday, May 13, 2013 12:59 PM:
An Item can contain either a single AML <Item> tag and its data, or it can contain multiple items. When it contains multiple items, trying to access properties using code such as item.getProperty causes errors because Aras does not know which item to get the data from. I am assuming that the document you are running the action on has multiple files associated with it, and therefore, this is the situation you are in. To resolve this problem, you need to loop through each of the files returned. This will result in code similar to
Item results = related_file.apply();
for (int i = 0; i < results.getItemCount(); i++) {
Item result = results.getItemByIndex(i);
string file_id = result.getID(); // Slightly more robust than result.getProperty("id"), but generally equivalent.
result.checkout("C:\Docs");
string file_name = result.getProperty("filename");
}
(I am doing this from memory, so I apologize for any syntax errors.)
Brian - Monday, May 13, 2013 8:05 PM:
Hi Vinmore,
Paste this code inside your method. Don't worry about classes etc.
You are already inside a class thanks to the Aras template files that wrap around your method code.
// download the files related to a document item
// called from an action
Innovator inn = this.getInnovator();
// get the related files
Item docFiles = this.newItem("Document File","get");
docFiles.setProperty("source_id",this.getID());
docFiles = docFiles.apply();
if ( docFiles.isError() )
{
return inn.newError("No files related to document");
}
Item files = docFiles.getItemsByXPath("//Item[@type='File']");
for ( int i = 0; i < files.getItemCount(); i++)
{
Item fle = files.getItemByIndex(i);
fle.checkout("c:\aras\dataoutput");
}
return this;
The above code will download all of the files from the document when the action is selected.
If you really want to use a class and you don't need to, then your code should look like:
Innovator inn = this.getInnovator();
bool result = testMethod(ref inn, this.getID());
return this;
}
public bool testMethod(ref Innovator inn, string docId){
Item docFiles = this.newItem("Document File","get");
docFiles.setProperty("source_id",docId);
docFiles = docFiles.apply();
if ( docFiles.isError() )
{
return false;
}
Item files = docFiles.getItemsByXPath("//Item[@type='File']");
for ( int i = 0; i < files.getItemCount(); i++)
{
Item fle = files.getItemByIndex(i);
fle.checkout("c:\aras\dataoutput");
}
return true;
//}
I have tested both versions of this code and they both do the same thing.
Hope this helps,
Brian.
vinmore - Wednesday, May 15, 2013 4:13 AM:
Thank you Brian, your second version code solved many issues for me. Now the methods usage in a server method works fine.
Thanks Eric, looping through the results is a good idea that I missed to do.
Xavier Bertschy - Thursday, October 2, 2014 4:06 AM:
Hi,
I have just read this thread, the method works fine but do you know the difference between the checkout method and the DownloadFile method? Since we download the file and might then reupload it, it can work like the DonwloadFile method right?
Thanks,
Xavier
Brian - Wednesday, November 19, 2014 8:19 PM:
Hi Xavier,
Checkout downloads the file and locks the file record so you know the file is undergoing some change and you don't want anyone else to checkout the file.
Download just downloads the file but does nothing to the file lock so someone else could checkout the file after you have downloaded it.
Hope this helps,
Brian.
Xavier Bertschy - Thursday, November 20, 2014 5:48 AM:
Thanks Bryan,
I am actually now trying to access the CheckinManager class in order to use the proper "Checkin Method". I'm trying to access the class by IomFactory.CreateCheckinManager(item as ARAS.IOM) but there is no "CreateCheckinManager" Method for IomFactory and I am not able to use this class.
Does anyone have an idea on how to use the CheckinManager Class?
Xavier
PS: I am using IOM.dll version 10.0 and the following code in VB.NET:
Dim checkin As CheckinManager
checkin = IomFactory.CreateCheckinManager
Xavier Bertschy - Wednesday, November 26, 2014 10:11 AM:
Or at least, is there any possibility to edit a File item to replace its file by a new one?
Thanks,
Xavier
Martin Fraser - Tuesday, December 9, 2014 4:06 AM:
Have a look at attachphysical file:
Xavier Bertschy - Tuesday, December 9, 2014 10:03 AM:
Yes thanks, you have to use AttachPhysicalFile to upload a file to a File Item but this method doesn't work when there is already a file attached to the File item.
Xavier
Martin Fraser - Tuesday, December 9, 2014 10:26 AM:
Hi,
I had a bit of trouble getting this to work the first time. I think the trick is using lock and update.
To upload a file I had to follow the pattern:
1) Get the file item
2) Lock the file item
3) Set the action to update
4) Attach the Physical File
5) (optional) Set the filename
6) Apply the update action on the file
7) Unlock the Item
Many thanks,
Martin.
Below is the code in VBA that I am using to perform the function:
If d.getProperty("related_id", "") <> "" Then '4
Set f = innov.newItem("File", "get")
f.setProperty "id", d.getProperty("related_id", "")
Set f = f.Apply
If f.getItemCount = 1 Then '5
f.lockItem
f.setAction ("update")
f.attachPhysicalFile (fPath)
f.setProperty "filename", Dir(fPath)
Set f = f.Apply
f.unlockItem
End If '5
Xavier Bertschy - Thursday, December 11, 2014 3:45 AM:
Yes that works well.
Plus, to update over a file (without generated a new revision), you can use setAttribute("version","0").
Another thing I've noticed, if you make a new version of a CAD using the action "version", it makes a copy of the File items related.
Thanks!
Xavier
Martin Fraser - Thursday, December 11, 2014 4:12 AM:
I'm glad this has helped.
To make the code more robust, you should get the Item.fetchLockStatus Method on the file item, to check that if it is locked / lockable before you attempt to lock it.
Many thanks,
Martin
santoshr0114 - Tuesday, December 30, 2014 12:21 AM:
Hi,
I tried this method to perform checkout and modify the attached file and checkin back. It works, but the document is still in Locked state.
I tried calling the item.Unlock(). It gives me an error that the document is not locked, But when i login to ARAS and see the document shows a Lock icon.
What am i doing wrong ?
For check-out below are the steps i followed
- Lock Document
- Fetch Native File and Lock the File
- Then Perform CheckOut on the Native File
Below is the sample code which i am using for check_in.
--------------------------------------------------------------------------------------------------------------------------------------
string item_number = System.IO.Path.GetFileNameWithoutExtension(fullfilename);
Aras.IOM.Item active_item = get_Item_By_Name(item_number);
active_item.setAction("update");
Aras.IOM.Item get_native_file = MyInnovator.getItemById("File", active_item.getItemByIndex(0).getProperty("native_file"));
get_native_file.setAction("update");
get_native_file.attachPhysicalFile(fullfilename);
get_native_file.setProperty("filename", System.IO.Path.GetFileName(fullfilename));
Aras.IOM.Item attach_status = get_native_file.apply("update");
if (attach_status.isError())
{
rc = false;
throw new Exception(..............);
}
if (active_item.fetchLockStatus() != 0) /// Also tried getLockStatus()
{
Aras.IOM.Item unlockCAD_status = active_item.unlockItem();
if (unlockCAD_status.isError())
{
throw new Exception(......);
}
}
--------------------------------------------------------------------------------------------------------------------------------------