如何使用ServiceStack实现删除服务调用

use*_*592 5 c# rest servicestack

我有几个与使用ServiceStack的REST服务实现相关的问题.

  1. 对于GET操作,我将请求DTO定义如下:

    [Route("/Customer/{ID}", Verbs = "GET")]
    public class GetCustomer : IReturn<GetCustomerResponse>
    {
        ....
        ....
    }
    
    Run Code Online (Sandbox Code Playgroud)

这里"GetCustomer"是请求DTO,"GetCustomerResponse"是响应DTO.但是对于PUT/POST/DELETE操作,我只需要知道操作是否成功提交,如果'不'那么什么是异常.那么对于POST/PUT/DELETE我的请求dto定义应该是什么?它应该使用IReturnVoid,如下所示?

[Route("/Customer/{ID}", Verbs = "DELETE")]
public class DeleteCustomer : IReturnVoid
{
    ....
    ....
}
Run Code Online (Sandbox Code Playgroud)

如果我必须使用IReturnVoid,那么如何检索提交我的操作时可能发生的任何异常信息?

在服务堆栈的错误处理文档中,它是写的,我在下面引用

错误响应类型

抛出异常时返回的错误响应取决于是否存在常规命名的{RequestDto}响应DTO.

如果存在:

无论服务方法的响应类型如何,都会返回{RequestDto}响应.如果{RequestDto}响应DTO具有ResponseStatus属性,则会填充它,否则将不返回ResponseStatus.(如果您使用[DataContract]/[DataMember]属性修饰了{ResponseDto} Response类和属性,则还需要对ResponseStatus进行修饰以填充().

否则,如果不是:

返回一个通用的ErrorResponse,其中包含一个填充的ResponseStatus属性.

服务客户端透明地处理不同的错误响应类型,对于无模式格式(如JSON/JSV/etc),在自定义或通用ErrorResponse中返回ResponseStatus之间没有实际的明显区别 - 因为它们都在线路上输出相同的响应.

我从上面得到的是我的服务实现中的Delete方法的返回类型是什么?如何在不定义删除响应DTO的情况下实现我的删除方法但是我能够检索"ErrorResponse"n异常信息?

  1. 是否可以使用"DELETE"动词定义路线?我有以下实施.

路线:

[Route("/DeleteCustomer/{ID}", Verbs = "DELETE")]
public class DeleteCustomer : IReturn<DeleteCustomerResponse>
{
    public int ID { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

方法实施:

public DeleteContactResponse Delete(DeleteContact request)
{
    .....
}
Run Code Online (Sandbox Code Playgroud)

但每当我使用我的客户端调用此删除时,我总是得到"NotFound"异常.我尝试了不同的客户端但是我得到了404错误.

与Servicestack文档一起提供的参考链接之一可以重复使用"GET"和"DELETE"动词.

另一个链接表明并非所有浏览器都支持删除操

所以我想知道如何实现删除操作?

myt*_*thz 15

有关如何使用ServiceStack设计REST-ful API的详细信息,请参阅此前面的答案.

CustomerRestExample包含客户REST ServiceStack服务的一个完整独立的例子:

客户服务定义

以下是典型客户REST服务的自定义路由和请求DTO的示例:

[Route("/customers", "GET")]
public class GetCustomers : IReturn<GetCustomersResponse> {}

public class GetCustomersResponse
{
    public List<Customer> Results { get; set; } 
}

[Route("/customers/{Id}", "GET")]
public class GetCustomer : IReturn<Customer>
{
    public int Id { get; set; }
}

[Route("/customers", "POST")]
public class CreateCustomer : IReturn<Customer>
{
    public string Name { get; set; }
}

[Route("/customers/{Id}", "PUT")]
public class UpdateCustomer : IReturn<Customer>
{
    public int Id { get; set; }

    public string Name { get; set; }
}

[Route("/customers/{Id}", "DELETE")]
public class DeleteCustomer : IReturnVoid
{
    public int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

OrmLite POCO型号:

public class Customer
{
    [AutoIncrement]
    public int Id { get; set; }

    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

本质上,自定义路由标识资源,而HTTP VERB指示对该资源的操作.查看HTTP请求使这一点更清晰:

GET    /customers   -> return all Customers
POST   /customers   -> Create a new Customer
GET    /customers/1 -> return Customer 1
PUT    /customers/1 -> Update Customer 1
DELETE /customers/1 -> Delete Customer 1
Run Code Online (Sandbox Code Playgroud)

客户服务实施

通过上述DTO的定义,我们现在可以通过为每个Request DTO添加一个实现来实现此Customer REST服务 - 在本例中使用OrmLite:

public class CustomerService : Service
{
    public object Get(GetCustomers request)
    {
        return new GetCustomersResponse { Results = Db.Select<Customer>() };
    }

    public object Get(GetCustomer request)
    {
        return Db.SingleById<Customer>(request.Id);
    }

    public object Post(CreateCustomer request)
    {
        var customer = new Customer { Name = request.Name };
        Db.Save(customer);
        return customer;
    }

    public object Put(UpdateCustomer request)
    {
        var customer = Db.SingleById<Customer>(request.Id);
        if (customer == null)
            throw HttpError.NotFound("Customer '{0}' does not exist".Fmt(request.Id));

        customer.Name = request.Name;
        Db.Update(customer);

        return customer;
    }

    public void Delete(DeleteCustomer request)
    {
        Db.DeleteById<Customer>(request.Id);
    }
}
Run Code Online (Sandbox Code Playgroud)

客户使用示例

通过上述Customer REST Service实现,我们可以重新使用Request DTO和ServiceStack的.NET服务客户端来提供没有代码生成的端到端Typed API,即:

var client = new JsonServiceClient(BaseUri);

//GET /customers
var all = client.Get(new GetCustomers());                         // Count = 0

//POST /customers
var customer = client.Post(new CreateCustomer { Name = "Foo" });

//GET /customer/1
customer = client.Get(new GetCustomer { Id = customer.Id });      // Name = Foo

//GET /customers
all = client.Get(new GetCustomers());                             // Count = 1

//PUT /customers/1
customer = client.Put(
    new UpdateCustomer { Id = customer.Id, Name = "Bar" });       // Name = Bar

//DELETE /customers/1
client.Delete(new DeleteCustomer { Id = customer.Id });

//GET /customers
all = client.Get(new GetCustomers());                             // Count = 0
Run Code Online (Sandbox Code Playgroud)

上面的注释包括在每个Service Client示例中执行的HTTP操作.


use*_*592 0

我通过以下两个链接解决了第二个问题:1. Link1 2. Link2

我不完全理解此修复,但执行上述更改对我有用,现在我可以从任何客户端调用删除功能。

对于第一个问题,请详细参考下面@mythz的回复。