gpt4 book ai didi

c# - 为什么我的属性会在所有操作上触发,包括那些没有该属性的操作?

转载 作者:可可西里 更新时间:2023-11-01 08:49:36 24 4
gpt4 key购买 nike

我的网络 API 中有一个 Controller 。我们称它为 TimeController

我有一个GET 操作和一个PUT 操作。它们看起来像这样:

public class TimeController : ApiController
{
[HttpGet]
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK, DateTime.UtcNow);
}

[HttpPut]
public HttpResponseMessage Put(int id)
{
_service.Update(id);
return Request.CreateResponse(HttpStatusCode.OK);
}
}

我还有一个路由配置如下:

routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional });

这样我就可以安心地访问它了。

现在我还想使用自定义 Route 属性对 GET 操作进行版本控制。我使用的代码与 Richard Tasker 在 blog post 中所说的非常相似.

(不同之处在于我使用正则表达式从 accept header 获取版本。其他一切都几乎相同)

所以我的 Controller 现在看起来像这样:

public class TimeController : ApiController
{
private IService _service;

public TimeController(IService service)
{
_service = service;
}

[HttpGet, RouteVersion("Time", 1)]
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.Ok, DateTime.UtcNow);
}

[HttpGet, RouteVersion("Time", 2)]
public HttpResponseMessage GetV2()
{
return Request.CreateResponse(HttpStatusCode.Ok, DateTime.UtcNow.AddDays(1));
}

[HttpPut]
public HttpResponseMessage Put(int id)
{
_service.Update(id);
return Request.CreateResponse(HttpStatusCode.OK);
}
}

但是,现在当我尝试访问 PUT 端点时,我从服务器收到了 404 响应。如果我在 Debug模式下单步执行代码,我可以看到 RouteVersion 属性被触发,即使我没有用它修饰操作。

如果我将属性添加到版本为 1 的 PUT 操作,或者我像这样添加内置 Route 属性:Route("Time") 那么它就可以工作了。

所以我的问题是:为什么属性会触发,即使我没有用它装饰 Action ?

编辑:这是属性的代码:

public class RouteVersion : RouteFactoryAttribute
{
private readonly int _allowedVersion;

public RouteVersion(string template, int allowedVersion) : base(template)
{
_allowedVersion = allowedVersion;
}

public override IDictionary<string, object> Constraints
{
get
{
return new HttpRouteValueDictionary
{
{"version", new VersionConstraint(_allowedVersion)}
};
}
}
}

public class VersionConstraint : IHttpRouteConstraint
{
private const int DefaultVersion = 1;
private readonly int _allowedVersion;
public VersionConstraint(int allowedVersion)
{
_allowedVersion = allowedVersion;
}

public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
if (routeDirection != HttpRouteDirection.UriResolution)
{
return true;
}
int version = GetVersionFromHeader(request) ?? DefaultVersion;
return (version == _allowedVersion);
}

private int? GetVersionFromHeader(HttpRequestMessage request)
{
System.Net.Http.Headers.HttpHeaderValueCollection<System.Net.Http.Headers.MediaTypeWithQualityHeaderValue> acceptHeader = request.Headers.Accept;
var regularExpression = new Regex(@"application\/vnd\.\.v([0-9]+)",
RegexOptions.IgnoreCase);

foreach (var mime in acceptHeader)
{
Match match = regularExpression.Match(mime.MediaType);
if (match.Success)
{
return Convert.ToInt32(match.Groups[1].Value);
}
}
return null;
}
}

Edit2:我认为有些困惑,所以我更新了 Put 操作以匹配路由配置

最佳答案

So my question is: why is the attribute firing even though I haven't decorated the action with it?

从您的问题的措辞方式“当我尝试访问 PUT 端点”以及它与您拥有的 GET 操作(然后随后运行其约束)相匹配的事实可以清楚地看出没有向服务器发出 PUT 请求。大多数浏览器无法发出 PUT 请求,您需要一段代码或脚本来执行此操作。

例子

using (var client = new System.Net.WebClient())
{
// The byte array is the data you are posting to the server
client.UploadData(@"http://example.com/time/123", "PUT", new byte[0]);
}

引用:How to make a HTTP PUT request?

关于c# - 为什么我的属性会在所有操作上触发,包括那些没有该属性的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36351745/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com