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

Set*_*man 2 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;}
    }
}
Run Code Online (Sandbox Code Playgroud)

我还创建了看起来像这样的Request DTO ......

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

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

我意识到路线是一样的...这可能是问题......但我指的是不同的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()) }
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

所以为了测试它我创建了以下简单的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>
Run Code Online (Sandbox Code Playgroud)

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

我的目标是使用新值来更新客户行.

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

如何在不受GET限制的情况下路由到PUT.是否有使用该服务进行更新的"最佳实践".例如......如果PUT服务不接收客户对象而是所有值......那么repo代码会获取记录并执行udpate吗?

POST方法(未示出)工作得很好BTW.它与PUT方法完全相同(接收Customer对象等)

编辑

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

编辑2

它似乎只是路由到返回具体类型的服务方法.返回对象的POST是例外... Get返回客户响应对象.获取客户返回客户(复数)响应对象并起作用.其余的服务方法是返回对象.是吗?

paa*_*hpa 8

Eli指出,浏览器不支持PUT/DELETE.应该能够使用ServiceStack X-HTTP-Method-Override作为输入字段来使用它.@mythz偷走了我的雷声,并在这里增加了对它的支持(并不是因为他打败我而苦恼)

您的<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>
Run Code Online (Sandbox Code Playgroud)