Alternative 1
If you don't worry about using dynamics mixed with regular typed C# code you could make a utility method like...
public static dynamic PrepareForMusiciansView(IQuerable<Musician> musicians)
{
return musicians.Select(m => new
{
musicianId = m.MusicianId,
name = m.Name,
instrument = new
{
instrumentId = m.instrument.InstrumentId,
model = m.instrument.Model
}
}
}
...and then...
return Json(new
{
error = false,
message = "",
musiciansCount = musicians.Count(),
page = page,
pageSize = pageSize
musicians = Util.PrepareForMusiciansView(pageOfMusicians)
}, JsonRequestBehavior.AllowGet);
The method name should clearly reflect its purpose in terms of your application. Maybe you want to focus more on the serialization function and use a name like PrepareForJson
. Also, it should be consistent with your coding standards. I would avoid it if nowhere else dynamics is used.
Alternative 2
Use AutoMapper (available via NuGet).
With AutoMapper you'd typically have DTO classes for Musician
and Instrument
, having the properties you want to expose in the view. If these properties have the same names as those in the source classes, AutoMapper will match them by name convention.
Using AutoMapper always involves defining the mappings and executing mappings. Defining the mappings should be done once at application startup. It looks like...
Mapper.CreateMap<Musician, MusicianDto>();
Mapper.CreateMap<Instrument, InstrumentDto>();
There are different ways to execute the mappings, but when working with IQueryable
the preferred way is
musicians = pageOfMusicians.Project().To<MusicianDto>()
This projects IQueryable<Musician>
to IQueryable<MusicianDto>
, including the nested Instrument
(if the DTO has a property of that name).
These are two viable alternatives I can think of to reduce the awkward new {}
statements to reusable one-liners. It really depends on your application and coding style which alternative you prefer.