Reputation: 3991
I have a function returning dynamic list and I want to return it back. Is this possible?
My function is as
public List<dynamic> GiveMeProjects(int id)
{
Entities.VSTMEntities vstm = new Entities.VSTMEntities();
var currentUserProject = (from users in vstm.Users
from project in users.Projects
where users.UserID == id
select new
{
Id = project.ProjectID,
Name = project.ProjectName
}).ToList<dynamic>();
return currentUserProject;
}
and calling it as
[WebMethod()]
public List<dynamic> GiveMeProjects(string id)
{
int pId = Convert.ToInt32(id);
return projectItems.GiveMeProjects(pId);
}
When I am testing the service, this function is generating exception
There was an error generating the XML document. ---> System.InvalidOperationException: f__AnonymousType102[System.Int32,System.String] cannot be serialized because it does not have a parameterless constructor.
at System.Xml.Serialization.TypeDesc.CheckSupported()
at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError)
at System.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException(Type type)
at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write9_ArrayOfAnyType(Object o)
at Microsoft.Xml.Serialization.GeneratedAssembly.ListOfObjectSerializer.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream outputStream, Object returnValue)
at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
at System.Web.Services.Protocols.WebServiceHandler.Invoke()
How to resolve this issue
Upvotes: 1
Views: 1748
Reputation: 1
This is no longer true. One can have polymorphic objects or regular objects and the JSON serializer will serialize them. I'm referring to .net6.0. Also, real streaming has been enabled in .NET6.0 so this additionally will provide this capability.
[HttpGet("execute")]
public async IAsyncEnumerable<dynamic> Get()
{
var extractor = new Extractor();
// different types of objects being returned in extract
await foreach (var extract in extractor)
{
yield return extract;
}
}
Upvotes: 0
Reputation: 2684
The C# dynamic keyword is not intended to be used like that. Since you now what you will return, the correct way is to create a class or struct and return it.
public class ProjectOverview
{
public int Id { get; set; }
public int Name { get; set; }
}
public List<ProjectOverview> GiveMeProjects(int id)
{
Entities.VSTMEntities vstm = new Entities.VSTMEntities();
var currentUserProject = (from users in vstm.Users
from project in users.Projects
where users.UserID == id
select new ProjectOverview()
{
Id = project.ProjectID,
Name = project.ProjectName
}).ToList();
return currentUserProject;
}
The dynamic keyword should only be used on special occasions. You can find details in the officals MSDN article. If you do not want to do that, you can check existing classes like KeyValuePair or Tuple. This is not recommended though. A service needs a clear interface so clients can easily access it. This is best done by exposing a custom class as return value (also with regards of extending your interface at one point).
Upvotes: 1