Hi everybody,
I'm currently migrating from the old SOAP API to the new gRPC API and using the get_object_list method, which returns a List<Google.Protobuf.IMessage>. To work with the results, I'm currently doing the following:
var result = _applicationClient.get_object_list([new Dlubal.Api.Rfem.StructureCore.Member()]).GetAwaiter().GetResult();
var members = result.Select(res =>
{
byte[] bytes = res.ToByteArray();
return Dlubal.Api.Rfem.StructureCore.Member.Parser.ParseFrom(bytes);
}).ToArray();
This works, but I wanted to check:
Is this the expected way to deserialize the returned IMessage objects into concrete types like Member?
I was expecting a more type-safe approach like a generic method that returns the concrete type directly, without the need to handle serialization and parsing myself.
Is there something i have missed like a generic helper method of some sort?
In the documentation I can only find this example, which seems like it's copied 1 to 1 from python, and as a result isn't particularly helpful for C#:
await rfem_app.get_object_list();
// Get all objects from specific type without parent
var all_members = await rfem_app.get_object_list([rfem.structure_core.Member()]);
// Get all objects from specific type with parent
var all_member_load = await rfem_app.get_object_list([rfem.loads.MemberLoad(load_case = "")]);
// Get all objects
var all_objects = await rfem_app.get_object_list([rfem.All()]);
Considering that this is a commercial API, i feel like i should not have to implement this functionality myself.
Thanks in advance for any clarification or best practices!
Hi Nils,
Thanks for your question!
You're absolutely right that manually handling the deserialization of IMessage objects into concrete types like Member can be cumbersome. The approach you shared using ToByteArray() and ParseFrom() is a valid workaround, but it isn't the most type-safe or convenient method, especially if you're working with multiple types.
Here’s a type-safe solution that makes working with the deserialized objects more streamlined:
// Fetch the list of members from the gRPC call
var objList = await RfemApp.get_object_list(
new List<IMessage> { new Rfem.StructureCore.Member() }
);
// Iterate over each item in the list
foreach (var obj in objList)
{
// Check if the object is of type Rfem.StructureCore.Member
if (obj is Rfem.StructureCore.Member member)
{
// Access and print the properties of the Member class
Console.WriteLine($"Member ID: {member.No}, Length: {member.Length}");
}
}
Let me know if this helps or if you need any further clarification! Apologies for any inconvenience caused – the documentation will be updated to reflect this.
Best regards
1 Like
Hi Tomas,
thanks you for nudging me in the right direction and pointing out that handling multiple types will be a problem.
For now, I wrote a generic extension methods that allows me to get an array with all elements of one type and casts them.
public static class RfemClientExtensions
{
public static TOut[] get_object_list<TOut>(this ApplicationRfem application) where TOut : class, IMessage<TOut>, new()
{
IMessage<TOut> filter = new TOut();
var result = application.get_object_list([filter], false, null).GetAwaiter().GetResult();
// filter and cast objects
return result.OfType<TOut>().ToArray();
}
}
which can be used like this:
var combinations = _applicationClient.get_object_list<LoadCombination>();
So no further clarification required, thanks for the help.
Best regards
2 Likes