C# struct in E10 BPM editor produces compiler error

It’s not really a bug of any kind. It absolutely makes sense. You are adding code inside of a method that their framework calls. You are trying to jam code in that is not intended to be there. That is no fault of Epicor’s. That being said there is supposedly in the latest version of Epicor a Global Variables section where you can define stuff outside of the methods a custom code action.  Invoke External Method is not to be used that way, but to your point you could create an external DLL and include that into the Using and References tabs.

 

Joshua Giese
Technology Solutions : CTO

Direct Phone:    920.593.8299
Office Phone:    920.437.6400 x342

http://wcibags.com/email/emailFooter4.jpg

From: vantage@yahoogroups.com [mailto:vantage@yahoogroups.com]
Sent: Wednesday, September 14, 2016 8:04
To: vantage@yahoogroups.com
Subject: [Vantage] Re: C# struct in E10 BPM editor produces compiler error

 

 

That's crazy.  How the heck does Epicor expect people to use their environment if the parser doesn't handle simple syntax.  Is Epicor aware of this and acknowledge there is a problem?  I agree, I don't want to write "bogus" code just to get the system to compile.  Would a better solution would be to write it in Visual Studio and use the Invoke External Method?

To keep the code clean and reduce issues as Epicor releases updates, I created a separate assembly in Visual Studio called BPMUtilities that deals with actual writing of the message queue and associated structure.  I then added the assembly as a reference in the data directive and called the methods to do the writes. 


Thanks everyone for your input!

Has anyone run across difficulty in using structs in E10 BPMs?  The following code, all by itself, will not compile complaining there is a missing end bracket }


struct CustomerQueueData
{
    public string action; // action: Insert, Update, Delete
    public string custid; // CRM Account: accountnumber
    public int custnum; // CRM Account: fcii_custnum
    public string shortchar01; // CRM Account: accountid
}; 



I don’t think you should have the semi-colon at the end

From: vantage@yahoogroups.com [mailto:vantage@yahoogroups.com]
Sent: Tuesday, September 13, 2016 1:23 PM
To: vantage@yahoogroups.com
Subject: [Vantage] C# struct in E10 BPM editor produces compiler error



Has anyone run across difficulty in using structs in E10 BPMs? The following code, all by itself, will not compile complaining there is a missing end bracket }



struct CustomerQueueData
{
public string action; // action: Insert, Update, Delete
public string custid; // CRM Account: accountnumber
public int custnum; // CRM Account: fcii_custnum
public string shortchar01; // CRM Account: accountid
};






NOTICE: THIS MESSAGE CONTAINS THE PROPRIETARY AND CONFIDENTIAL INFORMATION OF ACE PRECISION MACHINING CORP. If you are an unintended recipient, immediately (1) delete all copies of this message and any attachments, and (2) contact the sender. If you are an intended recipient, you are prohibited from deleting or obstructing this or any other Ace Precision Machining Corp. proprietary or confidentiality designation that appears on this message or any attachments. All recipients are prohibited from reproducing, publishing or disclosing the contents of this message and any attachments to others, unless you first request and receive written permission from Ace Precision Machining Corp.


[Non-text portions of this message have been removed]
Thanks for reply Scott.  It fails the same with or without the semicolon.  I have even removed the comments with the same result.
Could you provide the error message, if any? Or does it just say it's not compiling ?
The very last semicolon? or the last in the list inside the brackets?

Calvin

============

"I don’t think you should have the semi-colon at the end "
 

The very last semicolon.  Like this:

struct CustomerQueueData
{
    public string action; // action: Insert, Update, Delete
    public string custid; // CRM Account: accountnumber
    public int custnum; // CRM Account: fcii_custnum
    public string shortchar01; // CRM Account: accountid
}


In the wild, I've seen it both ways.  Visual Studio doesn't care either way.


Server Side Exception

There is at least one compilation error.

Exception caught in: Epicor.ServiceModel

Error Detail
============
Description:  There is at least one compilation error.
Details: 
Error CS1513: } expected [PostTran.CustomerTrigger.cs(97,60)]
Error CS1022: Type or namespace definition, or end-of-file expected [PostTran.CustomerTrigger.cs(147,1)]
Program:  Epicor.Customization.dll
Method:  PrepareException
Line Number:  99
Column Number:  13
Server Trace Stack:     at Epicor.Customization.Standard.CustomizationCompiler.PrepareException(CompilerErrorCollection errors) in c:\_Releases\ICE\3.1.400.0\source\Framework\Epicor.Customization\Standard\CustomizationCompiler.cs:line 99
   at Epicor.Customization.Standard.CustomizationCompiler.Compile(BuildEnvironment input, String outputAssembly) in c:\_Releases\ICE\3.1.400.0\source\Framework\Epicor.Customization\Standard\CustomizationCompiler.cs:line 62
   at Epicor.Customization.Standard.CustomizationBuilder.Process(CustomizationProject project) in c:\_Releases\ICE\3.1.400.0\source\Framework\Epicor.Customization\Standard\CustomizationBuilder.cs:line 78
   at Ice.Services.BO.BpMethodSvc.AfterUpdate() in c:\_Releases\ICE\3.1.400.10\source\Server\Services\BO\BpMethod\BpMethod.Events.cs:line 89
   at Ice.Services.Trace.TablesetProfilingCollector.DoTablesetEventTrace(String tablesetName, String methodName, Action action) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.Ice\Services\TablesetProfilingCollector.cs:line 198
   at Ice.TablesetBound`3.InnerUpdate(IceDataContext dataContext, TFullTableset tableset) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.Ice\Services\TablesetBound.cs:line 814
   at Ice.Services.BO.BpMethodSvc.Update(BpMethodTableset& ds) in c:\_Releases\ICE\3.1.400.10\source\Server\Services\BO\BpMethod\BpMethod.Designer.cs:line 837
   at Ice.Services.BO.BpMethodSvcFacade.Update(BpMethodTableset& ds) in c:\_Releases\ICE\3.1.400.10\source\Server\Services\BO\BpMethod\BpMethodSvcFacade.cs:line 224
   at SyncInvokeUpdate(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at Epicor.Hosting.OperationBoundInvoker.InnerInvoke(Object instance, Func`2 func) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 59
   at Epicor.Hosting.OperationBoundInvoker.Invoke(Object instance, Func`2 func) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 28
   at Epicor.Hosting.Wcf.EpiOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) in c:\_Releases\ICE\3.1.400.10\source\Framework\Epicor.System\Hosting\Wcf\EpiOperationInvoker.cs:line 23
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
   at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
   at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
   at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
   at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
   at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
   at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.InnerTryReceiveCompletedCallback(IAsyncResult result)
   at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
   at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
   at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceiveAsyncResult.OnReceive(IAsyncResult result)
   at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
   at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
   at System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.OnReceiveComplete(Object state)
   at System.ServiceModel.Channels.SessionConnectionReader.OnAsyncReadComplete(Object state)
   at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.Security.NegotiateStream.ProcessFrameBody(Int32 readBytes, Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.NegotiateStream.ReadCallback(AsyncProtocolRequest asyncRequest)
   at System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(Int32 bytes)
   at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
   at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
   at System.ServiceModel.Channels.ConnectionStream.IOAsyncResult.OnAsyncIOComplete(Object state)
   at System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(Object sender, SocketAsyncEventArgs eventArgs)
   at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
   at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)


Client Stack Trace
==================
   at Epicor.ServiceModel.Channels.ImplBase`1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets)
   at Ice.Proxy.BO.BpMethodImpl.Update(BpMethodDataSet ds)
   at Ice.Adapters.BpMethodAdapter.OnUpdate()
   at Ice.Lib.Framework.EpiBaseAdapter.Update()
   at Ice.UI.App.BpTriggerEntry.Transactions.MainTransaction.adapterUpdate()
   at Ice.Lib.Framework.EpiMultiViewTransaction.Update(IEnumerable`1 dataSets)

If you put that inside of a BPM the curly braces are going to conflict with how it’s compiled in the background you end up with something like.

 

Private static void Bpm_CustomAction01(){

 

    Struct myStuff{

         Public moreStuff;

    }

 

}

 

Joshua Giese
Technology Solutions : CTO

Direct Phone:    920.593.8299
Office Phone:    920.437.6400 x342

http://wcibags.com/email/emailFooter4.jpg

From: vantage@yahoogroups.com [mailto:vantage@yahoogroups.com]
Sent: Tuesday, September 13, 2016 14:34
To: vantage@yahoogroups.com
Subject: [Vantage] Re: C# struct in E10 BPM editor produces compiler error

 

 

Could you provide the error message, if any? Or does it just say it's not compiling ?

Putting the extra curly braces in there will "fix it" however this is strongly discouraged, you are banking on Epicor not changing the way they generate their code.


However for example sake

Epicor code generates like this

CustomConde()
{
 //YOUR CODE HERE

}


So if you want to "game" the system you could close / open your own curly braces to create your own structure... for example you could do


CustomCode()
{

 //Your Code starts here
  MyCustomMethod();
 }

 struct CustomerQueueData
 {
   public string action; // action: Insert, Update, Delete
   public string custid; // CRM Account: accountnumber
   public int custnum; // CRM Account: fcii_custnum
   public string shortchar01; // CRM Account: accountid
 }

 private void MyCustomMethod()
 {
  //Use your struct



 } //This curly brace is provided by Epicor


But this is highly hacky and I don't think you should use it.Â
Â


Jose C Gomez
Software Engineer


T: 904.469.1524 mobile

Quis custodiet ipsos custodes?

On Tue, Sep 13, 2016 at 3:46 PM, Joshua Giese jgiese@... [vantage] <vantage@yahoogroups.com> wrote:

Â
<div>
  
  
  <p>

If you put that inside of a BPM the curly braces are going to conflict with how it’s compiled in the background you end up with something like.

Â

Private static void Bpm_CustomAction01(){

Â

   Struct myStuff{

        Public moreStuff;

   }

Â

}

Â

Joshua Giese
Technology Solutions : CTO

Direct Phone:Â Â Â 920.593.8299
Office Phone:Â Â Â 920.437.6400 x342

http://wcibags.com/email/emailFooter4.jpg

From: vantage@yahoogroups.com [mailto:vantage@yahoogroups. com]
Sent: Tuesday, September 13, 2016 14:34
To: vantage@yahoogroups.com
Subject: [Vantage] Re: C# struct in E10 BPM editor produces compiler error

Â

Â

Could you provide the error message, if any? Or does it just say it's not compiling ?

</div>
 


<div style="color:#fff;min-height:0;"></div>

That error says you are missing a '}' which you very well could be. Can you paste the whole BPM or go over it yourself and make sure all the brackets are matching. Only other thing is struct using the name space system. So maybe in your usings add using System;
All I have in the BPM is the listed struct. I removed all the other code as I was debugging and found the error would occur with only the struct statement.

That is because of the curly braces. Please review Jose and I’s last posts for clarity on why that is occurring.

 

Joshua Giese
Technology Solutions : CTO

Direct Phone:    920.593.8299
Office Phone:    920.437.6400 x342

http://wcibags.com/email/emailFooter4.jpg

From: vantage@yahoogroups.com [mailto:vantage@yahoogroups.com]
Sent: Tuesday, September 13, 2016 17:42
To: vantage@yahoogroups.com
Subject: [Vantage] Re: C# struct in E10 BPM editor produces compiler error

 

 

All I have in the BPM is the listed struct. I removed all the other code as I was debugging and found the error would occur with only the struct statement.

That's crazy.  How the heck does Epicor expect people to use their environment if the parser doesn't handle simple syntax.  Is Epicor aware of this and acknowledge there is a problem?  I agree, I don't want to write "bogus" code just to get the system to compile.  Would a better solution would be to write it in Visual Studio and use the Invoke External Method?