WCF数据服务返回复杂类型

时间:2012-07-12 07:55:50

标签: wcf wcf-data-services odata

我创建了一个ComplexType,并在服务操作中返回它,如下所示:

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

当我尝试通过调用http://localhost/MyService.svc/GetCityByZip?zip='20000'来调用服务操作时,服务操作调用工作,浏览器显示城市列表。

当我尝试通过调用http://localhost/MyService.svc/GetCityByZip?zip='20000'&$top=1来调用服务操作时,浏览器会显示错误页面。

你能帮助我吗?

2 个答案:

答案 0 :(得分:2)

假设ComplexAddressType实际上是一个复杂类型,则不能将$top系统查询选项与该服务操作一起使用。如果您根据上述评论启用详细错误,则可能会收到此错误:

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

为了能够在服务操作中使用$top,您需要返回一组实体类型而不是复杂类型。

您还可以在函数调用中引入另一个参数,以便您可以使用以下URL:

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

示例代码:

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

答案 1 :(得分:0)

GetCityByZip方法有2个参数时,最后一个代码将起作用。第一个用于zip,第二个用于top。在你的情况下,你有参数不一致和wcf找不到方法。