Я хочу иметь настраиваемый атрибут для анализа данных в виде потока и проверки с помощью Swagger.
Итак, я создал контроллер, который читает из POST
тела:
[SwaggerOperation("Create")]
[SwaggerResponse(HttpStatusCode.Created)]
public async Task<string> Post([FromContent]Stream contentStream)
{
using (StreamReader reader = new StreamReader(contentStream, Encoding.UTF8))
{
var str = reader.ReadToEnd();
Console.WriteLine(str);
}
return "OK";
}
Как определить поток, чтобы он отображался в пользовательском интерфейсе Swagger?
Вот моя реализация атрибута FromContent
и привязки ContentParameterBinding
:
public class ContentParameterBinding : HttpParameterBinding
{
private struct AsyncVoid{}
public ContentParameterBinding(HttpParameterDescriptor descriptor) : base(descriptor)
{
}
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider,
HttpActionContext actionContext,
CancellationToken cancellationToken)
{
var binding = actionContext.ActionDescriptor.ActionBinding;
if (binding.ParameterBindings.Length > 1 ||
actionContext.Request.Method == HttpMethod.Get)
{
var taskSource = new TaskCompletionSource<AsyncVoid>();
taskSource.SetResult(default(AsyncVoid));
return taskSource.Task as Task;
}
var type = binding.ParameterBindings[0].Descriptor.ParameterType;
if (type == typeof(HttpContent))
{
SetValue(actionContext, actionContext.Request.Content);
var tcs = new TaskCompletionSource<object>();
tcs.SetResult(actionContext.Request.Content);
return tcs.Task;
}
if (type == typeof(Stream))
{
return actionContext.Request.Content
.ReadAsStreamAsync()
.ContinueWith((task) =>
{
SetValue(actionContext, task.Result);
});
}
throw new InvalidOperationException("Only HttpContent and Stream are supported for [FromContent] parameters");
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public sealed class FromContentAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
if (parameter == null)
throw new ArgumentException("Invalid parameter");
return new ContentParameterBinding(parameter);
}
}
Обновлять
Когда я создаю Stream
с помощью [FromBody]
, он правильно отображается в Swagger, однако Stream
не инициируется и ==null
[SwaggerOperation("Create")]
[SwaggerResponse(HttpStatusCode.Created)]
public async Task<string> Post([FromBody]Stream contentStream)
{
using (StreamReader reader = new StreamReader(contentStream, Encoding.UTF8))
{
var str = reader.ReadToEnd();
Console.WriteLine(str);
}
return "OK";
}
Итак, я хочу иметь тот же пользовательский интерфейс, но с моим пользовательским атрибутом, который позволяет мне получать Stream
из контента.
С моим пользовательским атрибутом он отображается без TextArea
для параметра, но его можно проверить с помощью Postman и работать правильно, а Stream
доступен
var stream = await this.Request.Content.ReadAsStreamAsync()
в методе контроллера. - person Darrel Miller   schedule 20.06.2017var stream = await this.Request.Content.ReadAsStreamAsync();
в пользовательском интерфейсе swagger? - person v-andrew   schedule 20.06.2017