C# 通过输入格式化程序将正文发布到参数
我正在尝试编写自己的输入格式化程序,它将读取请求正文,将其逐行拆分,并在控制器操作中将其传递到字符串数组参数中C# 通过输入格式化程序将正文发布到参数,c#,.net-core,inputformatter,C#,.net Core,Inputformatter,我正在尝试编写自己的输入格式化程序,它将读取请求正文,将其逐行拆分,并在控制器操作中将其传递到字符串数组参数中 这起作用(将整个身体作为字符串传递): Startup.cs public void配置服务(IServiceCollection服务) { services.AddMvcCore(选项=> { options.InputFormatters.Add(新的MyInputFormatter()); } } MyInputFormatter.cs public override异步任务
这起作用(将整个身体作为字符串传递): Startup.cs
public void配置服务(IServiceCollection服务)
{
services.AddMvcCore(选项=>
{
options.InputFormatters.Add(新的MyInputFormatter());
}
}
MyInputFormatter.cs
public override异步任务ReadRequestBodyAsync(InputFormatterContext上下文)
{
使用(StreamReader=newstreamreader(context.HttpContext.Request.Body))
{
返回InputFormatterResult.Success(wait reader.ReadToEndAsync());
}
}
MyController.cs
[HttpPost(“/foo”,Name=“foo”)]
公共IActionResult栏([FromBody]字符串foo)
{
返回Ok(foo);
}
这不起作用(参数foo为null): MyInputFormatter.cs
public override异步任务ReadRequestBodyAsync(InputFormatterContext上下文)
{
列表输入=新列表();
使用(StreamReader=newstreamreader(context.HttpContext.Request.Body))
{
而(!reader.EndOfStream)
{
字符串行=(wait reader.readlinesync()).Trim();
输入。添加(行);
}
}
返回InputFormatterResult.Success(input.ToArray());
}
MyController.cs
[HttpPost(“/foo”,Name=“foo”)]
公共IActionResult栏([FromBody]字符串[]foo)
{
返回Ok(string.Join(“,foo));
}
不同之处在于,在控制器中,我现在接受字符串数组而不是字符串,在格式化程序中,我逐行读取输入,最后将其作为数组返回
我错过了什么/
编辑:我的格式化程序的实际外观,或多或少(如果有区别):
公共类MyInputFormatter:InputFormatter
{
公共MyInputFormatter()
{
this.SupportedMediaTypes.Add(新的MediaTypeHeaderValue(MimeType.URI_列表));/“text/URI列表”
}
公共覆盖bool CanRead(InputFormatterContext上下文)
{
if(context==null)抛出新的ArgumentNullException(nameof(context));//未到达此处的断点
if(context.HttpContext.Request.ContentType==MimeType.URI\u列表)
返回true;
返回false;
}
受保护的覆盖布尔CanReadType(类型数据类型)
{
返回typeof(字符串[])。IsAssignableFrom(数据类型);//未到达此处的断点
}
公共重写异步任务ReadRequestBodyAsync(InputFormatterContext上下文)
{
列表输入=新列表();//未到达此处的断点
使用(StreamReader=newstreamreader(context.HttpContext.Request.Body))
{
而(!reader.EndOfStream)
{
字符串行=(wait reader.readlinesync()).Trim();
if(string.IsNullOrEmpty(行))
{
继续;
}
如果(!line.StartsWith(“foo-”))
{
返回InputFormatterResult.Failure();
}
input.Add(line.Substring(“foo-”.Length));
}
}
返回InputFormatterResult.Success(input.ToArray());
}
我用您的代码在请求处理程序方法中创建了一个测试输入格式化程序,它工作正常,如下所示:
public class TestInputFormatter : IInputFormatter
{
public bool CanRead(InputFormatterContext context) => true;
public async Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
{
List<string> input = new List<string>();
using (StreamReader reader = new StreamReader(context.HttpContext.Request.Body))
{
while (!reader.EndOfStream)
{
string line = (await reader.ReadLineAsync()).Trim();
input.Add(line);
}
}
return InputFormatterResult.Success(input.ToArray());
}
}
它在我的测试项目中使用的就是这样的注册。因为当你调用
选项.InputFormatters.Add
时,它将被添加到输入格式化程序集合的末尾,并且可能你的请求将由位于该集合第一位的其他输入格式化程序处理。我发现了t中的问题所在我有一个自定义的ModelBinder,它会干扰,捕获任何不是字符串的东西,还有一个自定义接口的实现(用于其他post数据)。这就是为什么它适用于字符串和其他输入有效负载(接口的实现),但不是字符串数组。该活页夹应用于查询参数(以便能够处理自定义类型),但最终也触发了此POST有效负载。这不是格式化程序顺序。:/我一直在调试它,好像根本没有使用格式化程序。没有使用格式化程序。它甚至没有运行任何CanRead或CanReadType方法,它只是直接以空值进入控制器操作。我用调试器和断点。还有什么可能导致这种行为?什么决定是否试用格式化程序?我在格式化程序的SupportedMediaTypes中添加了一个内容类型,在请求的content type标头中使用了完全相同的值,但它仍然不会触发。我在底部添加了格式化程序的实际外观。我认为这没有多大区别,只是以防万一。问题不在于您的InputFilter
实现或它在filters集合中的注册(因为它有自己的内容类型)。我已经测试了你的MyInputFormatter
,它工作得很好。你错过了其他一些东西,如果没有完整的项目来源,很难说什么。是的,我明白你的意思。我创建了一个新的mvc项目,只添加了控制器操作和格式化程序,它工作得很好。:/我会试着四处看看有什么问题。。。
options.InputFormatters.Insert(0, new TestInputFormatter());