我正在构建一个带有NServiceBus的Request/Acknowledge/Poll style REST service来管理队列处理。我想给客户端一个URI来轮询更新。
因此,我想在我的Web服务中返回一个位置标题元素作为确认的一部分。我可以看到有可能这样做:
return new HttpResult(response, HttpStatusCode.Accepted)
{
Location = base.Request.AbsoluteUri.CombineWith(response.Reference)
}
但是对于像http://localhost:54567/approvals/?message=test
这样创建新消息的网址(我知道我应该只使用POST),该位置将返回为:http://localhost:54567/approvals/?message=test/8f0ab1c1a2ca46f8a98b75330fd3ac5c
。
ServiceStack请求不公开Uri片段,只公开AbsouteUri。这意味着我需要访问原始请求。无论这是在IIS中运行还是在自托管进程中运行,我希望它能够正常工作。我能想出的最接近的是以下内容,但看起来非常笨重:
var reference = Guid.NewGuid().ToString("N");
var response = new ApprovalResponse { Reference = reference };
var httpRequest = ((System.Web.HttpRequest)base.Request.OriginalRequest).Url;
var baseUri = new Uri(String.Concat(httpRequest.Scheme, Uri.SchemeDelimiter, httpRequest.Host, ":", httpRequest.Port));
var uri = new Uri(baseUri, string.Format("/approvals/{0}", reference));
return new HttpResult(response, HttpStatusCode.Accepted)
{
Location = uri.ToString()
};
现在返回:http://localhost:55847/approvals/8f0ab1c1a2ca46f8a98b75330fd3ac5c
有什么建议吗?无论ServiceStack如何托管,这都有效吗?我有点害怕self hosted process中的System.Web.HttpRequest
投射。这段代码安全吗?
答案 0 :(得分:5)
如果您正在尝试为ServiceStack服务构建网址,则可以使用RequestDto.ToGetUrl()
和RequestDto.ToAbsoluteUri()
来构建相对网址和绝对网址,如前面的question on Reverse Routing所示。 e.g:
[Route("/reqstars/search", "GET")]
[Route("/reqstars/aged/{Age}")]
public class SearchReqstars : IReturn<ReqstarsResponse>
{
public int? Age { get; set; }
}
var relativeUrl = new SearchReqstars { Age = 20 }.ToUrl("GET");
var absoluteUrl = HostContext.Config.WebHostUrl.CombineWith(relativeUrl);
relativeUrl.Print(); //= /reqstars/aged/20
absoluteUrl.Print(); //= http://www.myhost.com/reqstars/aged/20
要为其他第三方API创建Url,请查看可以提供帮助的Http Utils wiki扩展方法,例如:
var url ="http://api.twitter.com/user_timeline.json?screen_name={0}".Fmt(name);
if (sinceId != null)
url = url.AddQueryParam("since_id", sinceId);
if (maxId != null)
url = url.AddQueryParam("max_id", maxId);
var tweets = url.GetJsonFromUrl()
.FromJson<List<Tweet>>();
您还可以使用QueryStringSerializer
序列化多种不同的集合类型,例如:
//Typed POCO
var url = "http://example.org/login?" + QueryStringSerializer.SerializeToString(
new Login { Username="mythz", Password="password" });
//Anonymous type
var url = "http://example.org/login?" + QueryStringSerializer.SerializeToString(
new { Username="mythz", Password="password" });
//string Dictionary
var url = "http://example.org/login?" + QueryStringSerializer.SerializeToString(
new Dictionary<string,string> {{"Username","mythz"}, {"Password","password"}});
您还可以序列化内置NameValueCollection.ToFormUrlEncoded()
扩展名,例如:
var url = "http://example.org/login?" + new NameValueCollection {
{"Username","mythz"}, {"Password","password"} }.ToFormUrlEncoded();