POST到ServiceStack Service并检索Location Header

Son*_*Nun 7 servicestack

我正在尝试POST到我的ServiceStack服务并从我的CREATED实体的响应中检索Location头.我不确定使用IReturn是否有效,但我不确定如何从我的客户端访问响应头.有人可以帮我理解如何正确地与HttpResult交互吗?代码底部有一个测试用例来演示我想要做的事情.这是codz:

    public class ServiceStackSpike
{
    public class AppHost : AppHostHttpListenerBase
    {
        public AppHost() : base("TODOs Tests", typeof(Todo).Assembly) { }

        public override void Configure(Container container)
        {
            //noop
        }
    }


    [Route("/todos", "POST")]
    public class Todo:IReturn<HttpResult>
    {
        public long Id { get; set; }
        public string Content { get; set; }
        public int Order { get; set; }
        public bool Done { get; set; }
    }


    public class TodosService : Service
    {
        public object Post(Todo todo)
        {
            //do stuff here
            var result = new HttpResult(todo,HttpStatusCode.Created);
            result.Headers[HttpHeaders.Location] = "/tada";
            return result;
        }


    }


    public class NewApiTodosTests : IDisposable
    {
        const string BaseUri = "http://localhost:82/";

        AppHost appHost;

        public NewApiTodosTests()
        {
            appHost = new AppHost();
            appHost.Init();
            appHost.Start(BaseUri);                
        }


        [Fact]
        public void Run()
        {
            var restClient = new JsonServiceClient(BaseUri);


            var todo = restClient.Post(new Todo { Content = "New TODO", Order = 1 });
            Assert.Equal(todo.Headers[HttpHeaders.Location], "/tada"); //=>fail
        }

        public void Dispose()
        {
            appHost.Dispose();
            appHost = null;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

myt*_*thz 7

有关自定义HTTP响应的所有不同方法,请参阅自定义HTTP响应 ServiceStack维基页面.

A HttpResult只是一种自定义HTTP响应的方法.如果要重定向,通常需要包含Absolute Url,例如:

public object Post(Todo todo)
{
    var todo = ...;
    return new HttpResult(todo, HttpStatusCode.Created) { 
        Location = base.Request.AbsoluteUri.CombineWith("/tada")
    };
}
Run Code Online (Sandbox Code Playgroud)

注意HTTP客户端永远不会看到HttpResultDTO.HttpResult 不是DTO本身,它的唯一目的是捕获和修改您想要的自定义HTTP响应.

所有ServiceStack客户端都将返回HTTP Body,在这种情况下是TodoResponse DTO.确实将位置添加到HTTP响应标头中,并且要查看返回的整个HTTP响应,您应该使用HTTP嗅探器,如Fiddler,WireShark或Chrome的WebInspector.

如果要使用ServiceStack的HTTP客户端访问它,则需要添加一个响应过滤器,使您可以访问HttpWebResponse,例如:

restClient.ResponseFilter = httpRes => {
      Assert.Equal(httpRes.Headers[HttpHeaders.Location], "/tada"); 
 };

Todo todo = restClient.Post(new Todo { Content = "New TODO", Order = 1 });
Run Code Online (Sandbox Code Playgroud)

使用Web请求扩展检查响应标头

如果您只想检查HTTP响应,另一个轻量级替代方法是使用ServiceStack的Convenient WebRequest扩展方法,例如:

var url = "http://path/to/service";
var json = url.GetJsonFromUrl(httpRes => {
      Assert.Equal(httpRes.Headers[HttpHeaders.Location], "/tada"); 
});
Run Code Online (Sandbox Code Playgroud)