Andrea
Andrea

Reputation: 803

WCF Data Service return Complex Type

I created a ComplexType and am returning it in a service operation as shown here:

   [WebGet]
   public IQueryable<ComplexAddressType> GetCityByZip(string zip) 
   {
      List<AddressType> normalizeAddress = NormalizeAddressProcess(new AddressType
                                                                             {
                                                                                 ZIP = zip,
                                                                             }).AddressList;
      return normalizeAddress.Select(x =>new ComplexAddressType
                        {
                            ZIP = x.zip,
                            City = x.City,
                            State = x.State
                        }).AsQueryable();
        }

When I try to invoke the service operation by calling http://localhost/MyService.svc/GetCityByZip?zip='20000', the service operation invocation works and the browser displays a list of cities.

When I try to invoke the service operation by calling http://localhost/MyService.svc/GetCityByZip?zip='20000'&$top=1, the browser displays an error page.

Could you can help me?

Upvotes: 0

Views: 2192

Answers (2)

Mark Stafford - MSFT
Mark Stafford - MSFT

Reputation: 4336

Assuming ComplexAddressType is actually a complex type, you cannot use the $top system query option with that service operation. If you enable verbose errors per the comment above, you are likely getting back this error:

Query options $orderby, $inlinecount, $skip and $top cannot be applied to the requested resource.

To be able to use $top with the service operation, you will need to return a collection of entity types rather than complex types.

You could also just introduce another parameter to your function call, so that you can use a URL such as the following:

http://localhost:59803/ScratchService.svc/GetProfiles?startsWith='ABC'&top=2

Sample code:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace Scratch.Web
{
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class ScratchService : DataService<ScratchContext>
    {
        static ScratchService()
        {
            Database.SetInitializer(new ScratchContextInitializer());
        }

        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
            config.UseVerboseErrors = true;
        }

        [WebGet]
        public IQueryable<User> GetUsers(int numUsers)
        {
            var users = new List<User>();

            for (int i = 0; i < numUsers; i++)
            {
                users.Add(new User
                              {
                                  Id = i,
                                  Password = i.ToString(),
                                  Username = i.ToString()
                              });
            }
            return users.AsQueryable();
        }

        [WebGet]
        public IQueryable<Profile> GetProfiles(string startsWith, int top)
        {
            var profiles = new List<Profile>
                            {
                                new Profile{ DisplayName = "A", Preferences = "1" },
                                new Profile{ DisplayName = "AB", Preferences = "2" },
                                new Profile{ DisplayName = "ABC", Preferences = "3" },
                                new Profile{ DisplayName = "ABCD", Preferences = "4" },
                                new Profile{ DisplayName = "ABCDE", Preferences = "5" },
                                new Profile{ DisplayName = "ABCDEF", Preferences = "6" },
                                new Profile{ DisplayName = "ABCDEFG", Preferences = "7" }
                            };

            return profiles.Where(p => p.DisplayName.StartsWith(startsWith)).Take(top).AsQueryable();
        }
    }

    public class ScratchContextInitializer : DropCreateDatabaseAlways<ScratchContext>
    {
    }

    public class ScratchContext : DbContext
    {
        public DbSet<User> Users { get; set; }
    }

    public class Profile
    {
        public string DisplayName { get; set; }
        public string Preferences { get; set; }
    }

    public class User
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public Profile Profile { get; set; }
    }
}

Upvotes: 2

RredCat
RredCat

Reputation: 5421

Last code will work when GetCityByZip method has 2 parameters. First one for zip and second one for top. In your case you have parameters inconsistency and wcf can't find method.

Upvotes: 0

Related Questions