| Author |
Share Topic Topic Search Topic Options
|
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Topic: How to call the following Remote Server methds Posted: 16-Jan-2011 at 6:13pm |
I am having trouble figuring out how to call the following Remote Server Methods.
1. public static double GetMemberDuesRate(Member member, DateTime startDate, DateTime endDate) It is located in a folder called RemoteCalls in the LaborWare2011Web project.
2. public static void CalculateBalanceOwing(Member member) it is also located in a folder called RemoteCalls in the LaborWare2011Web project.
Bill
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 734
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 1:05pm |
Hi Bill
Like previously stated at
The method called must correspond to the ServerMethodDelegate signature:
public delegate object ServerMethodDelegate( IPrincipal principal, EntityManager serverEntityManager, params object[] args )
So your methods' signatures should look like:
public static double GetMemberDuesRate(
IPrincipal principal,
EntityManager server,
Member member, DateTime startDate, DateTime endDate
)
and
public static void CalculateBalanceOwing(
IPrincipal principal,
EntityManager server,
Member member
)
Make sure your parameters are serializable.
If for some reason you can't modify your methods to comply with the signature above, I suggest that you create compliant methods and call your methods within them.
You can find valuable information about invoking server methods in our DevForce Resource Center and in the DevForce API documentation as well.
Silvio.
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 7:14pm |
Ok I changed the signature to the following
[ AllowRpc]
public static void CalculateAmountOwing(IPrincipal principal, EntityManager manager, Member m)
{
so how do I call this method now. Is this correct?
public void CalculateBalance()
{
string typeName = "LaborWare2011Web.RemoteCalls.MemberBalanceCalculator, LaborWare2011Web";
string methodName = "CalculateAmountOwing";
var op = Mgr.InvokeServerMethodAsync(typeName, methodName, Mgr, CurrentMember);
op.Completed += (o, args) => {
};
}
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 7:43pm |
Ok so I made the following change according to the documentation
public void CalculateBalance()
{
string typeName = "LaborWare2011Web.RemoteCalls.MemberBalanceCalculator, LaborWare2011Web";
string methodName = "CalculateAmountOwing";
var op = Mgr.InvokeServerMethodAsync(typeName, methodName, null, null, CurrentMember);
op.Completed += (o, args) => {
};
}
[ AllowRpc]
public static void CalculateAmountOwing(IPrincipal principal, EntityManager mgr, params Object[] args)
{
when I step through the code the call to InvokeServerMethodAsync does not call the server method, it just advances past the code.
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 734
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 8:14pm |
Bill,
You are invoking the method asynchronously and once it's completed it will invoke the callback (if any).
Are you saying that it is not getting to the callback at all?
Are you getting any exceptions?
Did you try stepping into the server method?
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 8:25pm |
I get an unhandled exceptions code 4004 Category: ManagedRuntimeError
Message:EntityServerException: Could not load type
'LaborWare2011Web.RemoteCalls.MemberBalanceCalculator' from assembly 'LaborWare2011Web.
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 8:34pm |
I place a breakpoint inside of the server method and it never gets called.
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 734
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 8:44pm |
The error means that your assembly-qualified type name is incorrect.
So yours will most likely be
LaborWare2011.RemoteCalls.MemberBalanceCalculator, LaborWare2011Web
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 8:59pm |
Ok now I got further. I get the follwing error message
unable to locate public method: MemberBalanceCalculator.CalculateAmountOwing
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 9:10pm |
I think that I know what the problem is now.
What do I want for the second parameter for the CalculateAmountOwing method
EntityManager mgr
or
LaborWareEntities mgr
I tried using the EntityManager mgr and I get an error 'the type initializer for LaborWare2011.RemoteCalls.MemberBalanceCalculator threw an exception. System.TypeInitializationException: The type 'initializer for MemberBalanceCalculator threw an exeption. IdeaBlade.Core.IdeaBladeException: Type conflict: the defaultmanager is currently of type EntityManager.
when I use my domain specfic manager it can't find the method because the signature is wrong.
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 734
|
Post Options
Quote Reply
Posted: 18-Jan-2011 at 9:42pm |
Bill,
You'd declare your server method as:
[AllowRpc]
public static string CalculateAmountOwing(IPrincipal principal, EntityManager entityManager, params Object[] args){
Member member = args[0] as Member;
...
and in your application you'd call it as follows:
string typeName = "LaborWare2011.RemoteCalls.MemberBalanceCalculator, LaborWare2011Web";
string methodName = "CalculateAmountOwing";
var op = Mgr.InvokeServerMethodAsync(typeName, methodName, null, null, CurrentMember);
Are you defining your server method and invoking the method as stated above?
If yes, where exactly is the exception being thrown?
We'd appreciate some feedback on how we could make this information clearer.
Silvio.
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 19-Jan-2011 at 8:35am |
Two issues I am still having.
I thought that the server methods that ran on the server could run synchronous methods. Do the executes and calls in my server methods have to be asychronous? This is what I am trying to do inside of CalculateAmountOwing()
1. var query1 = from DuesPaid in _manager.DuesPaids
orderby DuesPaid.BatchDate descending
where DuesPaid.SocSecNo == m.SocSecNo
select DuesPaid;
var results1 = query1.Execute<DuesPaid>();
results1.ForEach(Paid.Add);
2. It will not compile my CalculateAmountOwing if I use the manager object being passed in. example I tried to do the following
var query1 = from DuesPaid in manager.DuesPaids and it gave a compile error. Right now in my class I have the following
private static LaborWareEntities _manager = LaborWareEntities.DefaultManager;
and I am using _manager to access all properties and it works fine.
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 734
|
Post Options
Quote Reply
Posted: 19-Jan-2011 at 9:34am |
Bill,
1. The Server Method will run synchronously in the server, but the call to the server method is asynchronous because you are using InvokeServerMethodAsync.
i.e.
If you invoke the server method asynchronously (InvokeServerMethodAsync), the code in the client keeps going. Once the Server Method completes, the results are accessible in the callback.
If you invoke the server method synchronously (InvokeServerMethod), the code in the client halts until the Server Method completes. (pretty much like calling a method in the client itself) Then the code in the client continues.
Assuming you are not running a Silverlight app, you could invoke the method synchronously by using InvokeServerMethod.
2. I'm not sure I understand why it's not compiling. What line of code is causing the error? What is the error message?
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 19-Jan-2011 at 10:15am |
public static string CalculateAmountOwing(IPrincipal principal, EntityManager manager, params Object[] args)
{
Member m = args[0] as Member;
Paid = new ObservableCollection<DuesPaid>();
Owed = new ObservableCollection<DuesOwed>();
var query1 = from DuesPaid in manager.DuesPaids doesn't like manager
orderby DuesPaid.BatchDate descending
where DuesPaid.SocSecNo == m.SocSecNo
select DuesPaid;
var results1 = query1.Execute<DuesPaid>();
results1. ForEach(Paid.Add);
|
 |
BillG
DevForce MVP
Joined: 05-Dec-2007
Location: Monroe, MI
Posts: 177
|
Post Options
Quote Reply
Posted: 19-Jan-2011 at 10:36am |
Is the documentation correct? Here is your remote server method, it looks like even though you are calling it asychronously your GetQuery is a synchronous call. what is entityManager initialized to?
[AllowRpc] public static int GetNumberOfOrders(IPrincipal principal, EntityManager entityManager, params Object[] args) {
// Gather args DateTime startDate = (DateTime) args[0]; DateTime endDate = (DateTime) args[1];
return entityManager.GetQuery<OrderSummary>() .Where(os => os.OrderDate > startDate && os.OrderDate < endDate) .Count(); }
Here is the calling method
public void GetOrderCount(DateTime startDate, DateTime endDate) { string typeName = "DomainModel.OrderSummary, DomainModel"; string methodName = "GetNumberOfOrders";
var op = _em1.InvokeServerMethodAsync(typeName, methodName, null, null, startDate, endDate); is null, null the principal and the entitymanager op.Completed += (o, args) => { int myResult = (int)args.Result; }; }
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 734
|
Post Options
Quote Reply
Posted: 19-Jan-2011 at 12:14pm |
Bill,
The example in the documentation is correct.
You asked "what is entityManager initialized to"
- For server-side code accepting an EntityManager we create a server-specific EM just for that particular use. In the case of RPC methods it's a bit different in that the type will usually be the type of the calling EM on the client.
By the way, in an earlier post, you showed the following line of code:
private static LaborWareEntities _manager = LaborWareEntities.DefaultManager;
Avoid using static EntityManagers in server-side code. The server code must be able to support multi-threading, and using a static EM means you're opening yourself up to unforeseen multi-threading errors later on. These threading problems usually don't show up in development and early testing, but they show up when you go into production.
You mentioned "Here is your remote server method, it looks like even though you are calling it asychronously your GetQuery is a synchronous call"
- Regardless of being called SYNCHRONOUSLY or ASYNCHRONOUSLY in the Client, the Server Method will be executed SYNCHRONOUSLY in the Server.
You asked "is null, null the principal and the entitymanager"
- InvokeServerMethodAsync has 3 overloads. The one shown in your post is: InvokeServerMethodAsync(String,String,Action<InvokeServerMethodOperation>,Object,Object[])
Here's a quote from our API documentation:
======================================================================
Asynchronously invokes the specified static (Shared in Visual Basic) method for execution on the server. Syntax C# public InvokeServerMethodOperation InvokeServerMethodAsync( string fullTypeName, string methodName, Action<InvokeServerMethodOperation> userCallback, object userState, params object[] userArguments ) Parameters fullTypeName Assembly-qualified type name such as 'MyNamespace.Services, MyAssembly' methodName Name of method to be invoked userCallback Callback called when the operation completes userState Token identifying the asynchronous request userArguments Arguments to be passed to method
======================================================================
and also in your machine (installed with DevForce) at Start>Programs>DevForce2010>Documentation>API Documentation.
I am also attaching a simple Silverlight App invoking a Server Method based on the example in the DevForce Resource Center.
You can download the sample here.
Silvio.
|
 |