我使用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;
}
}
}
}
我的回答如下:
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")
调用服务时
我收到此异常(未命中服务第一行中的断点):
的NullReferenceException 你调用的对象是空的。 ServiceStack.Text.Web上的ServiceStack.Text.XmlSerializer.SerializeToStream(Object obj,Stream stream)at ServiceStack.Common.Web.HttpResponseFilter。&lt; GetStreamSerializer&gt; b_ 3(IRequestContext r,Object o,Stream s)。 ServicePack.WebHost.Endpoints.Extensions.HttpResponseExtensions.WriteToResponse(IHttpResponse响应,对象结果,ResponseSerializerDelegate defaultAction,HttpResponseFilter。&lt;&gt; c _DisplayClass1。&lt; GetResponseSerializer&gt; b__0(IRequestContext httpReq,Object dto,IHttpResponse httpRes) IRequestContext serializerCtx,Byte [] bodyPrefix,Byte [] bodySuffix)
无论我是否在调用中包含任何参数,都会抛出异常。我也在同一个项目的同一行创建了许多其他服务,工作正常。任何人都可以指出我的方向是正确的吗?
答案 0 :(得分:7)
您的网络服务设计有点倒退,您的请求DTO 应继续RestServiceBase<TRequest>
而不是您的回复。如果您正在创建REST-ful服务,我建议您将服务的名称(即Request DTO)作为名词,例如在这种情况下可能是代码。
此外,我建议您使用相同的强类型响应服务,其名称遵循“{RequestDto}响应”惯例,例如: 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;
}
}
您可以使用[RestService]属性或以下路由(执行相同的操作):
Routes.Add<Codes>("/codes/{Type}");
这将允许您像这样调用服务:
http://localhost:5000/codes/counties?apikey=xxx&format=xml