Search code examples
asp.net-web-apiodata

OData webapi2 can't change Account to AccountViewModel


I have the following

        [EnableQuery]
        public IQueryable<AccountViewModel> GetAccounts()
        {
            return _accountRepository.Table
                .Select(x => new Bepoz.Api.Models.AccountViewModel() {Title = x.Title, AccountID = x.AccountID}).AsQueryable();
        }

And

    [EnableQuery]
    public SingleResult<AccountViewModel> GetAccount([FromODataUri] int key)
    {
        return SingleResult.Create(this._accountRepository.Table.Where(account => account.AccountID == key)
            .Select(x => new Bepoz.Api.Models.AccountViewModel() { Title = x.Title, AccountID = x.AccountID }).AsQueryable());
    }

In my WebApiConfig

        public static void Register(HttpConfiguration config)
        {
            // New code:
            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<AccountViewModel>("Accounts");
            config.MapODataServiceRoute(
                routeName: "ODataRoute",
                routePrefix: "odata",
                model: builder.GetEdmModel());
        }

When I execute

http://localhost:55045/odata/Accounts

The response is all the accounts as expected, however when I execute

http://localhost:55045/odata/Accounts(1)

I get

{
  "error":{
    "code":"","message":"No HTTP resource was found that matches the request URI 'http://localhost:55045/odata/Accounts(1)'.","innererror":{
      "message":"No routing convention was found to select an action for the OData path with template '~/entityset/key'.","type":"","stacktrace":""
    }
  }
}

My AccountViewModel looks like this

public class AccountViewModel
{
    [Key]
    public int AccountID { get; set; }
    public string Title { get; set; }
}

FYI - If I change the class from AccountViewModel to Account, it will work! Thanks


Solution

  • The only thing you need to do is add 2 more lines:

    ODataModelBuilder builder = new ODataConventionModelBuilder();
    EntitySetConfiguration<AccountViewModel> accounts= builder.EntitySet<AccountViewModel>("Accounts");
    EntityTypeConfiguration<AccountViewModel> account = accounts.EntityType;
    account.Name = "Account";