Do my model objects have to have the same name as my WCF Web Api DTO objects when using restsharp?

StackOverflow https://stackoverflow.com/questions/7798577

Question

I have set up a WCF Web Api service, and everything was working fine, until I started using DTOs to expose data.

Previously I had on the WCF Service my model object which was called Game.cs:

public class Game
{
    public int Id { get; set; }
    public string Description { get; set; }
    public string Developer { get; set; }
    public Genre Genre { get; set; }
    public string Name { get; set; }
    public decimal? Price { get; set; }
    public string Publisher { get; set; }
    public Rating Rating { get; set; }
    public DateTime? ReleaseDate { get; set; }
}

The get method in the service looked like this:

public IQueryable<Game> GetGames()
    {
        var db = new XBoxGames();
        var games = db
            .Games
            .Include("Genre")
            .Include("Rating")
            .OrderBy(g => g.Id)
            .ToList()
            .AsQueryable();
        return games;
    }

In the MVC 3 client application I had a controller action that requested all my games: (I'm using restsharp)

public ActionResult Index()
    {
        var request = new RestRequest(Method.GET);
        var restClient = new RestClient();
        restClient.BaseUrl = "http://localhost:4778";
        request.Resource = "games";
        var response = restClient.Execute<List<Game>>(request);
        var games = response.Data;
        return View(games);
    }

and the client model:

public class Game
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Developer { get; set; }
    public int GenreId { get; set; }
}

After I started using DTOs, the client was not getting any information about any game, eventhough the service was returning the info. The get method in the service changed a little bit, now instead of returning my model, I am returning a DTO object which has the information I actually want to expose over the API:

[WebGet(UriTemplate = "")]
    public IQueryable<GameDTO> GetGames()
    {
        var db = new XBoxGames();
        var games = db
            .Games
            .Include("Genre")
            .Include("Rating")
            .OrderBy(g => g.Id)
            .ToList();
        var gamesDTO = Mapper.Map<List<Game>, List<GameDTO>>(games);
        return gamesDTO.AsQueryable();
    }

The DTO object has the following structure:

public class GameDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Developer { get; set; }
    public string GenreName { get; set; }
}

The xml returned by the service looks like this:

<ArrayOfGameDTO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <GameDTO>
    <Id>3</Id>
    <Name>Jade Empire™</Name>
    <Description>
     ...
    </Description>
    <Developer>BioWare Corp.eeeddd</Developer>
 </GameDTO>
 <GameDTO
  .
  .
  . 
 </GameDTO>
</ArrayOfGameDTO>

I noticed that the xml root tag has now changed from ArrayOfGame to ArrayOfGameDTO, and that seems to be a problem for restsharp, since in my client application my model for games is called Game.cs, so in order to get the client application to work my client model needs to have tha same name as de DTO object in the service (GameDTO). I found this solution a little odd, so my question: is there a way to get things working without having DTOs and client models named the same?

Any help would be appreciate it... Thanks in advance.

Était-ce utile?

La solution

You can try to do the following

namespace MyDTONamespace {
  public class Game { ... }
}

and in your service:

using DTO = MyDTONamespace;

namespace MyServiceNamespace {
  public class MyService {
    [WebGet(UriTemplate = "")]
    public IQueryable<DTO.Game> GetGames() {
      var db = new XBoxGames();
      var games = db
          .Games
          .Include("Genre")
          .Include("Rating")
          .OrderBy(g => g.Id)
          .ToList();
      var gamesDTO = Mapper.Map<List<Game>, List<DTO.Game>>(games);
      return gamesDTO.AsQueryable();
    }
  }
}

I'm curious to what this serializes, but I think this could work.

EDIT: I thought you were renaming them on the client to DTO.

The other option that I can think of is to make your DTOs serialization-aware. I assume you're using the DataContractSerializer (WCF default) so you can use the Name property of the DataContract attribute, see here.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top