为什么我的ServiceStack服务会抛出异常?

Sim*_*mon 3 c# web-services servicestack

我使用ServiceStack构建了一个简单的Rest服务(很棒),它返回一个键值对列表.

我的服务如下:

 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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的回答如下:

    public class ListAllResponse
{
    public string County { get; set; }
    public string Destination { get; set; }
    public string APIKey { get; set; }     
}
Run Code Online (Sandbox Code Playgroud)

我已经映射了其余的URL,如下所示:

.Add<ListAllResponse>("/destinations")
.Add<ListAllResponse>("/counties")
Run Code Online (Sandbox Code Playgroud)

在调用服务时

HTTP://本地主机:5000 /县/ apikey = XXX&格式= XML

我收到此异常(服务的第一行中的断点未被命中):

NullReferenceException未将对象引用设置为对象的实例.at ServiceStack.Text.XmlSerializer.SerializeToStream(Object obj,Stream stream)at ServiceStack.Common.Web.HttpResponseFilter.<GetStreamSerializer> b_ 3(IRequestContext r,Object o,Stream s)at ServiceStack.Common.Web.HttpResponseFilter.<>在ServiceStack.WebHost.Endpoints.Extensions.HttpResponseExtensions.WriteToResponse(IHttpResponse响应,对象结果,ResponseSerializerDelegate defaultAction,IRequestContext serializerCtx,Byte [] bodyPrefix,Byte []中的c _DisplayClass1.<GetResponseSerializer> b__0(IRequestContext httpReq,Object dto,IHttpResponse httpRes) bodySuffix)

无论我是否在调用中包含任何参数,都会抛出异常.我也在同一个项目的同一行创建了许多其他服务,工作正常.任何人都可以指出我的方向是正确的吗?

myt*_*thz 7

您的Web服务设计有点倒退,您的请求DTO应该继续而RestServiceBase<TRequest>不是您的响应.如果您正在创建REST-ful服务,我建议您将服务的名称(即Request DTO)作为名词,例如在这种情况下可能是代码.

此外,我建议使用与"{RequestDto} Response"约定相同的名称对服务使用相同的强类型响应,例如CodesResponse.

最后返回一个空响应而不是null,因此客户端只需处理空结果集而不是空响应.

以下是我将如何重写您的服务:

 [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; 
     }
 }
Run Code Online (Sandbox Code Playgroud)

您可以使用[RestService]属性或以下路由(执行相同的操作):

Routes.Add<Codes>("/codes/{Type}");
Run Code Online (Sandbox Code Playgroud)

这将允许您像这样调用服务:

http://localhost:5000/codes/counties?apikey=xxx&format=xml
Run Code Online (Sandbox Code Playgroud)