Почему моя служба ServiceStack создает исключение? - PullRequest
3 голосов
/ 08 марта 2012

Я сконструировал простой сервис Rest, используя ServiceStack (что великолепно), который возвращает список пар ключ-значение.

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

 public class ServiceListAll : RestServiceBase<ListAllResponse>
{
    public override object OnGet(ListAllResponse request)
    {          
        APIClient c = VenueServiceHelper.CheckAndGetClient(request.APIKey, VenueServiceHelper.Methods.ListDestinations);

        if (c == null)
        {
            return null;
        }
        else
        {
            if ((RequestContext.AbsoluteUri.Contains("counties")))
            {
                return General.GetListOfCounties();
            }

            else if ((RequestContext.AbsoluteUri.Contains("destinations")))
            {
                return General.GetListOfDestinations();
            }

            else
            {
                return null;
            }
        }
    }
}

мой ответ выглядит так:

    public class ListAllResponse
{
    public string County { get; set; }
    public string Destination { get; set; }
    public string APIKey { get; set; }     
}

и я сопоставил остальные URL следующим образом:

.Add<ListAllResponse>("/destinations")
.Add<ListAllResponse>("/counties")

при вызове услуги

http://localhost:5000/counties/?apikey=xxx&format=xml

Я получаю это исключение (точка останова в первой строке службы не достигнута):

NullReferenceException В экземпляре объекта не задана ссылка на объект. в ServiceStack.Text.XmlSerializer.SerializeToStream (Object obj, Stream stream) в ServiceStack.Common.Web.HttpResponseFilter. b_ 3 (IRequestContext r, Object o, Stream s) в ServiceStack.Common.ResseFT . <> c _DisplayClass1. b__0 (IRequestContext httpReq, Object dto, IHttpResponse httpRes) в ServiceStack.WebHost.Endpoints.Extensions.HttpResponseExtensions.WriteToResponse, Responsetext_Extext_Repontext, Resource Response ] bodyPrefix, Byte [] bodySuffix)

Исключение выдается независимо от того, включаю ли я какие-либо параметры в вызов или нет. Я также создал ряд других сервисов по тому же принципу в том же проекте, которые отлично работают. Кто-нибудь может указать мне правильное направление относительно того, что это значит?

1 Ответ

7 голосов
/ 09 марта 2012

Ваш веб-сервис немного отстал, Ваш Запрос DTO должен продолжаться RestServiceBase<TRequest>, а не ваш ответ. И если вы создаете службу REST-ful, я рекомендую название (т.е. запросить DTO) вашей службы как существительное, например, в этом случае возможно коды.

Также я рекомендую иметь и использовать тот же тип ответа со строгим типом для вашей службы с именем, соответствующим соглашению «RequestDto}, например CodesResponse.

Наконец, верните пустой ответ вместо нуля, так что клиенты должны обрабатывать только пустой набор результатов, а не нулевой ответ.

Вот как бы я переписал ваш сервис:

 [RestService("/codes/{Type}")]
 public class Codes {
      public string APIKey { get; set; }     
      public string Type { get; set; }
 }

 public class CodesResponse {
      public CodesResponse() {
           Results = new List<string>();
      }

      public List<string> Results { get; set; }
 }

 public class CodesService : RestServiceBase<Codes>
 {
      public override object OnGet(Codes request)
      {          
           APIClient c = VenueServiceHelper.CheckAndGetClient(request.APIKey, 
              VenueServiceHelper.Methods.ListDestinations);

           var response = new CodesResponse();
           if (c == null) return response;

           if (request.Type == "counties") 
                response.Results = General.GetListOfCounties();
           else if (request.Type == "destinations") 
                response.Results = General.GetListOfDestinations();

           return response; 
     }
 }

Вы можете использовать атрибут [RestService] или следующий маршрут (который делает то же самое):

Routes.Add<Codes>("/codes/{Type}");

Что позволит вам позвонить в службу так:

http://localhost:5000/codes/counties?apikey=xxx&format=xml
...