Send custom data as object using WCF - wcf

In my latest project, I wish to send custom data as an object using WCF. Reason for this is that I won't have to update each client when a new data class is introduced.
However, when I try to send this data, it never arrives at the client side.
To give a short example:
A custom class:
[DataContract]
public class MyData
{
[DataMember]
public string Name { get ;set; }
[DataMember]
public id Value { get; set; }
public MyData(string name, id value)
{
this.Name = name;
this.Value = value;
}
}
When I want to send this to the client, I use:
object obj = new MyData("test",1);
service.SendDataToClient(obj);
The client never receives this event from the service when I send it as object. However, when I send it as MyData instead of object, it works as it should. How can I send this as object?

If you want to send custom data the easy way is using XElement instead of object. Another approach is defining all possible transfered types by ServicKnownTypeAttribute or creating generic resolver (in such case you must share contract assembly between client and service). Check this great article.

Related

Validate existing entity in CQRS + EventSourcing. Microservice ASP.NET Core 5.0

I am currently building an app, and I would like to use micro services.
I use Mediatr for implementing a CQRS pattern and EventStore for event sourcing.
I have a problem with checking that an entity exists before creating an event of aggregate and appending it to the EventStore.
For example: I have LanguageAggregateRoot
public class LanguageAggregateRoot
{
public Guid Id {get;set}
public string Code { get; private set; }
public string Name { get; private set; }
public bool Enable { get; private set; }
public string Icon { get; private set; }
}
Field Code is unique and user can change code for language.
When I use Code field for stream id of eventstore, if the user sends a CreateLanguageCommand and ChangeCodeCommand, I need to check that the new code exists.
So I use Id field for stream id. But I don't understand how I can validate whether code field is unique?
As far as I've found out should not use query handling in command handling.
If i use client to check existed then send command to server. I think it doesn't look good. Because something/someone can request only command with out my client.
How can I do that?
Thanks for your support.
It should be fine to validate your request in your command itself.
you can use the below link for more details.
CQRS - is it allowed to call the read side from the write side?

Object return type is not supported in WCF test client

In WCF i have a class which is acting as the return type for all my methods.
public class ResponseResult
{
public object data {get;set;}
public string Name {get;set;}
}
and in IService interface i have method declaration like:
ResponseResult GetValues(int id);
if run the test client GetValues is not available.beside the method name i am getting cross sign on hover it says "this method is not supported in WCF Test client because it uses mmService.Common.ResponseResult".
if i remove the property data then it get visible and i want that object property. please help me out.
Object data type will not work with service client.service client need the serialize data type like list , string , int etc.... it will not actually decide the actual return type of object data type.

What are my options in ServiceStack to assign a unique ID to each request?

I'm building an API with ServiceStack. I'd like each request to have a unique ID so that I can trace it through the system (which is distributed).
I have my contracts assembly containing my API's DTOs, and so I thought the natural place would be to make each Request derive from a base class that had a sealed protected parameterless constructor that assigned a new ID (probably a GUID is fine).
However, it'll be possible to use my API via the clients without necessarily using the contract DTOs assembly - naked, if you will. At that point, the clients can assign whatever IDs they like (since the property will be a string to be accomodating, and I want ID assignment to be quick).
So, this leads me to think that the service should assign request IDs when the requests arrive at the system. So - I'm currently thinking that the best thing to do is have an ID property on each request DTO that is validated to be empty by the API - clients cannot set it. Then, a before-everything filter to assign a value to the DTO property.
Is that sensible?
Is there a more elegant way to do it (that still works against naked clients?)?
Using a global request filter would work, you can do something like:
public class IRequiresUniqueId
{
public Guid UniqueId { get; set; }
}
And then mark all request DTOs you would like to have a Unique Id by implementing the above interface:
public MyRequest : IRequiresUniqueId
{
public Guid UniqueId { get; set; }
}
Then you can use a Global Request Filter to set all request DTOs that have them:
this.RequestFilters.Add((httpReq, httpResp, requestDto) =>
{
var requiresUniqueId = requestDto as IRequiresUniqueId;
requiresUniqueId.UniqueId = Guid.NewGuid();
});

silverlight domain service don't allow return a generic object

I have a domain service running smooth, some expose functions that return generic lists of defined entity, but for some reason, I had add some common information so I created a generic object to wrap the collection with the extra information that I need return.
but when after made the change and try use the service in the client, the function don't show up in the context, I already search about it and what I found was attributes for generic IQueryable
my wrap class
public class Wrap<T>
{
public String commonProperty { get; set; }
public String anotherCommonProperty { get; set; }
public List<T> items { get; set; }
}
in my service domain
public Wrap<SomeClass> GetAll()
{
Wrap<SomeClass> myObject = new Wrap<SomeClass>();
myObject.items = new List<SomeClass>();
myObject.commonProperty = "some info";
myObject.anotherCommonProperty = "some info";
return myObject;
}
Maybe adding the [KnownType(typeof(SomeClass))] attribute in the Wrap<T> class, the problem is that you need to include one KnowType attribute for every class in your domain (this is because you are making a polymorphic service).
And adding the [ServiceKnownType(typeof(SomeClass))] in the GetAll method in the service (this is for wcf services I don't know if is valid for domain services).
WCF RIA domain services does not support generic entity types. IEnumerable<T> and IQueryable<T> are special cases.
Your method was ignored because it did not match supported method type.
Before changes GetAll was recognized as Query method. You can force that by adding attribute.
[Query]
public Wrap<SomeClass> GetAll()
Now it does not dissapear silently. But generates compile time error instead:
Type 'Wrap`1' is not a valid entity type. Entity types cannot be
generic.

WCF - Exposing parameterized constructor

I have a WCF DataContract called RecipientDto defined as:
[DataContract]
public class RecipientDto
{
[DataMember]
public string Name
{
get;
private set;
}
[DataMember]
public string EmailAddress
{
get;
private set;
}
public RecipientDto(string name, string emailAddress)
{
Name = name;
EmailAddress = emailAddress;
//Initialize other property here
}
}
I want to have constructor of RecipientDto being exposed to the client as it involve some basic initialization of other properties (not shown here).
Please guide how can I achieve this.
Thank you!
You cannot achieve that unless you share assembly with your DTOs between client and server. Metadata (WSDL + XSD) can describe only data transferred by DTO. They cannot describe any logic defined in DTO on service side.
What you could do is the create a second source file for the RecipientDto class, that contains a second declaration of the class with the "partial" keyword. Add your constructor to it and include that file in your client project using Visual Studio's "Add Link" functionality available on the "Add existing item" dialog. If you only need that constructor on the client then just define that second source file directly in the client project.