servicestack - 为什么servicestack服务路由到GET而不是PUT

标签 servicestack ormlite-servicestack

本周我获准学习 ServiceStack。我喜欢它。这是一个了不起的框架。但是我遇到了一种情况,我无法获得一个相当直接的例子来工作。 (虽然它诚然不如示例那么简单,但可能是一个更现实的示例。)

提前为这个冗长的问题道歉。

我有一个简单的 DTO,可以映射到这样的数据库...

[Description("Customer")]
[Alias("Customers")]
    public class Customer : IHasId<int>
    {
        [Alias("Id")]
        [AutoIncrement]
        public int Id { get; set;}

        [Required]
        public int CompanyId { get; set;}

        [Required]
        public string FirstName { get; set;}

        [Required]
        public string LastName { get; set;}

        public string MiddleInitial { get; set;}
        public string EmployerName { get; set;}
        public string ServiceLocationDescription { get; set;}
        public string Street1 { get; set;}
        public string Street2 { get; set;}
        public string City { get; set;}
        public string State { get; set;}
        public string Zip { get; set;}

        [Required]
        public string Phone { get; set;}
        public string Fax { get; set;}

        [Required]
        public string EmailAddress { get; set;}
    }
}

我还创建了如下所示的请求 DTO...

//request dto
[Route("/customers/{companyId/customer/{customerId}", "GET")]
public class GetCustomer  : Customer
{
}

[Route("/customers/{companyId}/customer/{customerId}", "PUT")]
public class UpdateCustomer  : Customer
{
}

我意识到路由是一样的……这可能是问题所在……但我指定了不同的 http 方法……

我终于有了一个看起来像这样的服务......

public CustomerResponse Get(GetCustomer request)
{
    return new CustomerResponse { Customer = customerRepository.GetCustomer(request.CustomerId), };
}

public object Put(UpdateCustomer request)
{
    customerRepository.UpdateCustomer(request);
    return new HttpResult
    {
        StatusCode = HttpStatusCode.NoContent,
        Headers = {
            { HttpHeaders.Location, this.RequestContext.AbsoluteUri.CombineWith(request.Id.ToString()) }
        }
    };
}

所以为了测试它,我创建了以下简单的 html...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="en-us" http-equiv="Content-Language" />
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Untitled 1</title>
</head>

<body>

<form action="http://localhost:8080/co/1/customers/1000" method="get">
    <br />
    <label id="Label1">CompanyId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input name="CompanyId" type="text" /></label><br />
    FirstName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input name="FirstName" type="text" /><br />
    LastName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input name="LastName" type="text" /><br />
    Middle Initial&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    **OTHER FIELDS**  
    <input type="submit" />
</form>

</body>

</html>

所有这一切都很好,只有 PUT 路由到 GET 服务。

我的目标当然是用新值更新客户行。

我没有显示客户存储库类,但它工作正常。我猜。我有一个具体的一般性问题。

如何路由到 PUT 而不是 GET。是否有使用该服务进行更新的“最佳实践”。例如...是否应该 PUT 服务不接收客户对象,而是接收所有值...然后 repo 代码获取记录并进行更新?

顺便说一句,POST 方法(未显示)效果很好。它与 PUT 方法完全一样(接收客户对象等)

编辑

我也刚刚确定我尝试使用 DELETE http 方法也路由到 GET。这是一个简单的类型,甚至不从 Customer 继承。它只得到两个删除参数。现在我真的很困惑。

编辑 2

似乎只是路由到返回具体类型的服务方法。异常(exception)是返回对象的 POST...Get 返回一个客户响应对象。获取客户返回一个客户(复数)响应对象并且可以工作。其余的服务方法是返回对象。是这样吗?

最佳答案

正如 Eli 指出的,浏览器不支持 PUT/DELETE。应该能够使用 X-HTTP-Method-Override 让它与 ServiceStack 一起工作作为输入字段。 @mythz 抢了我的风头并增加了对它的支持 here (对他把我打到这个地步并不痛苦)

还有你的<form>方法是 'get',它应该始终路由到您的 ServiceStack 的 Service 'Get' 方法。

未经测试,但我认为这应该可行。

<form action="http://localhost:8080/co/1/customers/1000" method="POST">
    <br />
    <input name="X-HTTP-Method-Override" type="hidden" value="PUT" />
    <label id="Label1">CompanyId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input name="CompanyId" type="text" /></label><br />
    FirstName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input name="FirstName" type="text" /><br />
    LastName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <input name="LastName" type="text" /><br />
    Middle Initial&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    **OTHER FIELDS**  
    <input type="submit" />
</form>

关于servicestack - 为什么servicestack服务路由到GET而不是PUT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15435042/

相关文章:

ServiceStack - [引用]还是[忽略]?

api - 使用附加用户 API key 在服务堆栈中实现仅应用程序 API key 和 secret

c# - ServiceStack FluentValidation 中的自定义响应 DTO

NUnit 测试被随机中止(涉及 ServiceStack 和 RavenDB)

c# - ORMLite 中的 ServiceStack 如何对父表进行简单引用?

mysql - OrmLite(服务堆栈): Only use temporary db-connections (use 'using' ?)

c# - 如何将 SqlAzure 重试逻辑添加到 OrmLite 操作?

c# - 在 Windows/C# 上加速 Redis

c# - ORMLITE 是否支持表变量作为存储过程参数?

c# - 使用 servicestack ormlite 动态创建(并从中选择)表