I am have a method (GetUser()), method return type is an interface (IUser) and I have a class (User) include same fields with IUser. I want to bind GetUser methods result to User object.
I am using c#.
Method :
IEnumerable<IUser> GetUser();
Interface :
public interface IUser {
public string Id{ get; set;}
public string Name{ get; set;}
public string Username{ get; set;}
public IAddress Address{ get; set;}
//And more fields
}
Class :
public class User {
public string Id{ get; set;}
public string Name{ get; set;}
public string Username{ get; set;}
public Address Address{ get; set;}
//And more fields
}
I tried the following cases and not works.
IEnumerable<User> user = AnyLibrary.GetUser() as IEnumerable<User>;
IEnumerable<User> user = (IEnumerable<User>) AnyLibrary.GetUser();
Is it possible and how can i do this ?
The real solution to the problem is to inherit the IUser class as Adam Vincent and stuartd mentioned.
But If don't want to inherit from the Iuser class.Another solution that comes to my mind json serialize to GetUser() method's result and deserialize to User object.
string users = JsonConvert.SerializeObject(AnyLibrary.GetUser());
IEnumerable<User> c_user = JsonConvert.DeserializeObject<IEnumerable<User>>(users);
This solutions works for me well.
Related
I would like to do a deep copy of an object. This object has some normal string, int, properties but it would also have custom objects (e.g. a list of custom objects).
Is there a way to do a deep copy where I pick and choose which properties to copy?
e.g. I want to copy
public class BankAccount
{
[Required]
[DeepCopy]
public string Number { get; }
[Required]
[DeepCopy]
public string Owner { get; set; }
[Required]
[DeepCopy]
public decimal Balance { get; }
[Required]
[DeepCopy]
public List<CustomAddress> {get; set;}
[Required]
public List<CustomLinkedAccounts> {get; set;}
}
Where perhaps I would want to copy everything except the List of CustomLinkedAccounts.
This is a solution I have used in the past for deep cloning.
It requires Newtonsoft JSON library.
It can be adapted to use System.Text.Json if you can't use third party libraries.
using Newtonsoft.Json;
public class BankAccount
{
[Required]
public string Number { get; }
[Required]
public string Owner { get; set; }
[Required]
public decimal Balance { get; }
[Required]
public List<CustomAddress> {get; set;}
[Required]
[JsonIgnore]//this is not in the json
public List<CustomLinkedAccounts> {get; set;}
public BankAccount Clone()
{
var json = JsonConvert.SerializeObject(this);
var result = JsonConvert.DeserializeObject<BankAccount>(json);
//this is a deep copy... no reference issues
return result;
}
}
I have a base class like this-ish:
public class Baseclass
{
public string Id { get; set; }
public string Type { get; set; }
public string Name { get; set; }
}
...and many classes that inherit these properties, like this-ish:
public class Thing: Baseclass
{
public string Size{ get; set; }
public string Color{ get; set; }
public string Smell{ get; set; }
}
Now, I don't want to serialize all of these properties (mvc/jsonresult), so I use [JsonIgnore] on the properties of a class I want to exclude, and that works fine. The problem is that I don't want to serialize all the inherited properties for a class either. I've asked around and gotten the following answer:
Ex: I don't want to serialize the inherited Id from Baseclass in Thing.
I should make Id in Baseclass virutal:
public virtual string Id { get; set; }
and add the following to the Thing class:
[JsonIgnore]
public override string Id { get; set; }
...but this doesn't work, I'm afraid. I can get around it rebuilding the class hierarchy. but I would prefer a simpler solution. Any suggestions as to why this solution didn't work or alternatives to exclude certain inherited properties?
I want to change my CustomAttribute usage in this way, I'm using it to refer to the search parameters of an autocomplete dropdown
now:
[EntitySearchDropBox(Id="Id",SearchColumns="Name")]
public virtual class MyTarget
But i hate strings for defining entity properties and the best solution for me is passing AttributeTarget property without writing free strings.
[EntitySearchDropBox(Id=MyTarget.Id,SearchColumns=MyTarget.Name)]
public virtual class MyTarget
MyTarget example
public class MyTarget{
public int Id {get; set;}
public string Name {get; set;}
public string otherProperty { get; set; }
//etc..
}
I have a data structure something like this:
public class HighLevelConversionData
{
public int customerID {get;set;}
public string customerName {get;set;}
public decimal amountSpent {get;set;}
}
This data will be accessed by a third party and a GWT front end, meaning I'll be using web services to move the data around. The customer is also of a different localisation than the dev team, so I'm wanting to send status messages as a wrapper for the returned data items, like so:
public class HighLevelConversionDataWrapper
{
public int StatusCode {get;set;}
public string StatusMessage {get;set;}
public List<HighLevelConversionData> {get;set;}
}
However I'd rather have an interface for these methods to inherit from, to ensure we're always sending the statuscode & message in the same way. But my understanding of how generics work in an interface seems to be failing me. I believe it should be something like:
public Interface IServiceWrapper
{
public int StatusCode {get;set}
public string StatusMessage {get;set;}
public List<T> ReturnedData {get;set;}
}
But I've come unstuck here.
Something like this?
public class ConcreteWrapper : IServiceWrapper<HighLevelConversionData>
{
public int StatusCode {get;set;}
public string StatusMessage { get; set; }
public List<HighLevelConversionData> ReturnedData { get; set;}
}
public class HighLevelConversionData
{
public int customerID {get;set;}
public string customerName {get;set;}
public decimal amountSpent {get;set;}
}
public interface IServiceWrapper<T>
{
int StatusCode { get; set; }
string StatusMessage { get; set; }
List<T> ReturnedData { get; set;}
}
If the interface has generic type parameters, the interface itself must be generic, so you'll need to do:
public interface IServiceWrapper<T>
{
public int StatusCode {get;set}
public string StatusMessage {get;set;}
public List<T> ReturnedData {get;set;}
}
and then specify the type parameters in the code like this:
public class HighLevelConversionDataServiceWrapper
: IServiceWrapper<HighLevelConversionData>
{
public List<HighLevelConversionData> ReturnedData {get;set;}
}
I'm going boarder line crazy, I have been working with this for over a day and still have no idea why it doesn't work,
I have a MessageContract that I'm using to send out a stream, but I get the following error,
Type 'System.IO.FileStream' with data
contract name
'FileStream:http://schemas.datacontract.org/2004/07/System.IO'
is not expected. Add any types not
known statically to the list of known
types - for example, by using the
KnownTypeAttribute attribute or by
adding them to the list of known types
passed to DataContractSerializer.
[ServiceContract()]
public interface IContentService
{
[OperationContract(), FaultContract(typeof(ContentFault))]
PublishItemResponse PublishFile(PublishFileRequest request);
}
[MessageContract()]
public class PublishFileRequest
{
[MessageHeader()]
public FileInventoryItem Item {get;set;}
[MessageHeader()]
public Request Request {get;set;}
[MessageBodyMember()]
public Stream FileContent {get;set;}
}
[MessageContract()]
public class Request
{
[MessageHeader()]
public Guid AuthorizationToken { get; set; }
[MessageHeader()]
public string CoreVersion { get; set; }
[MessageHeader()]
public string Password { get; set; }
[MessageHeader()]
public DateTime RequestTime { get; set; }
[MessageHeader()]
public string ComponentVersion { get; set; }
[MessageHeader()]
public string UserName { get; set; }
}
[MessageContract()]
[Serializable()]
public class FileInventoryItem : InventoryItemBase
{
public Stream FileContent { get; set;}
}
[MessageContract()]
[KnownType(typeof(FileInventoryItem))]
[KnownType(typeof(FolderInventoryItem))]
[Serializable()]
public abstract class InventoryItemBase
{
public List<string> Errors {get;set;}
public List<string> Warnings {get;set;}
[MessageHeader()]
public StagingAction Action {get;set;}
[MessageHeader()]
public string ContentXml {get;set;}
[MessageHeader()]
public int ItemId {get;set;}
[MessageHeader()]
public ItemType ItemType { {get;set;}
[MessageHeader()]
public string Name {get;set;}
[MessageHeader()]
public int ParentId {get;set;}
[MessageHeader()]
public Guid ParentUniqueId {get;set;}
[MessageHeader()]
public Guid UniqueId {get;set;}
[MessageHeader()]
public Guid Version {get;set;}
}
Any help is greatly appropriated,
WCF requires the types that are serialized to exactly match the types that are declared in the contract. You can get around that by adding the KnownType attribute to indicate that you know a particular sub type is going to be used (in this case you would add it to the PublishFileRequest class).
However, while that will eliminate the first error, your code will still not work, since FileStreams are not serializable.
The FileStream object points to the filesystem, which cannot be accessed from another computer.
Use a MemoryStream instead to transfer the data. You can use Stream.CopyTo(memoryStream) to copy the data to the MemoryStream object.