我想在asp.net webapi的消息处理程序中添加属性值。 方案是我实现webapi,其中authenticationToken是不同请求的一部分,但客户端要求我接受请求标头中的令牌。但是一些应用程序已经在使用这个api在请求体中发送令牌。 所以我不想改变实施。我想读取请求标头,如果它包含标头,则将该值分配给请求的属性。 有可能吗?
答案 0 :(得分:5)
是的,可以修改您的请求uri
&消息处理程序中的formdata
。这是一个例子,你可以试试这个。我添加了class APIKeyHandler
来处理此问题,并在我的WebApiConfig
中添加了处理程序。我已在 Git 上传了一个解决方案,您可以从Example WebAPI with Modify Request Body in MessageHandler
WebApiConfig
代码:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
System.Web.Routing.RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//add the handler class in WebApiConfig
config.MessageHandlers.Add(new APIKeyHandler());
}
}
APIKeyHandler
代码:
public class APIKeyHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var formData = await request.Content.ReadAsFormDataAsync();
if (request.Method.Method.Equals("POST"))
{
request.Content = new FormUrlEncodedContent(ModifyYourFormData(formData, request));
}
request.RequestUri = new Uri(ModifyYourURI(request.RequestUri.ToString(), request), UriKind.Absolute);
return await base.SendAsync(request, cancellationToken);
}
public IEnumerable<KeyValuePair<string, string>> ModifyYourFormData(NameValueCollection source, HttpRequestMessage request)
{
//Add your logic here
string Authorized = "";
try
{
Authorized = request.Headers.GetValues("AuthorizedKey").FirstOrDefault();
}
catch (Exception ex)
{
}
List<KeyValuePair<string, string>> formData;
formData = source.AllKeys.SelectMany(
source.GetValues,
(k, v) => new KeyValuePair<string, string>(k, v)).ToList();
if (!string.IsNullOrEmpty(Authorized))
{
formData.Insert(0, new KeyValuePair<string, string>("AuthorizedKey", Authorized));
}
return formData;
}
public string ModifyYourURI(string uri, HttpRequestMessage request)
{
//Add your logic here
string Authorized = "";
try
{
Authorized = request.Headers.GetValues("AuthorizedKey").FirstOrDefault();
}
catch (Exception ex)
{
}
if (!string.IsNullOrEmpty(Authorized))
{
return uri + "?AuthorizedKey="+ Authorized;
}
else
{
return uri;
}
}
}
ExampleAPIController
代码:
public class ExampleAPIController : ApiController
{
public async Task<string> Post()
{
string returnValue = "OK";
var formKeyValueData = await Request.Content.ReadAsFormDataAsync();
string AuthorizedKey = formKeyValueData["AuthorizedKey"];
return returnValue;
}
public string Get(string AuthorizedKey)
{
string returnValue = "OK";
return returnValue;
}
}
POST请求呼叫示例:
GET请求呼叫示例:
答案 1 :(得分:0)
另一个解决方案我想在请求中添加动态属性
if (request.Headers.Contains(HeaderName) && request.Method.Method.Equals("POST"))
{
var formData = await request.Content.ReadAsStringAsync();
dynamic data = JsonConvert.DeserializeObject(formData);
data.authenticationToken = request.Headers.GetValues(HeaderName).FirstOrDefault();
request.Content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
}