Должны ли мои объекты модели иметь то же имя, что и мои объекты WCF Web Api DTO при использовании restsharp? - PullRequest
0 голосов
/ 17 октября 2011

Я настроил службу веб-API WCF, и все работало нормально, пока я не начал использовать DTO для предоставления данных.

Ранее в Службе WCF был мой объект модели, который назывался 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; }
}

Метод get в сервисе выглядел так:

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

В клиентском приложении MVC 3 у меня было действие контроллера, которое запрашивало все мои игры: (я использую 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);
    }

и модель клиента:

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; }
}

После того, как я начал использовать DTO, клиент не получал никакой информации о какой-либо игре, даже если сервис возвращал информацию. Метод get в службе немного изменился, теперь вместо возврата моей модели я возвращаю объект DTO, в котором есть информация, которую я действительно хочу предоставить через 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();
    }

Объект DTO имеет следующую структуру:

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; }
}

XML, возвращаемый службой, выглядит следующим образом:

<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>

Я заметил, что корневой тег xml теперь изменился с ArrayOfGame на ArrayOfGameDTO, и это кажется проблемой для restsharp, поскольку в моем клиентском приложении моя модель для игр называется Game.cs, поэтому для получения клиента Для работы приложения моя модель клиента должна иметь то же имя, что и объект de DTO в сервисе (GameDTO). Я нашел это решение немного странным, поэтому мой вопрос: есть ли способ заставить все работать без названий DTO и моделей клиентов?

Любая помощь будет благодарна ... Заранее спасибо.

1 Ответ

1 голос
/ 18 октября 2011

Вы можете попробовать сделать следующее

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

и к вашим услугам:

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();
    }
  }
}

Мне любопытно, что это сериализует, но я думаю, что это может сработать.

РЕДАКТИРОВАТЬ: Я думал, что вы переименовываете их на клиенте в DTO.

Другой вариант, который я могу придумать, это сделать вашу сериализацию DTO осведомленной.Я предполагаю, что вы используете DataContractSerializer (по умолчанию WCF), поэтому вы можете использовать свойство Name атрибута DataContract, см. здесь .

...