如果没有传递查询字符串,则带有 FromUri 的 Webapi 对象参数为 null

问题描述 投票:0回答:3

我有以下 API 控制器操作

[HttpGet]
[Route("assets")]
public async Task<HttpResponseMessage> Get([FromUri]SearchCriteria searchCriteria)
{

}

当我通过访问 url 来使用 fiddler 进行测试时

http://localhost/assets

searchCriteria 参数为空,但是当我尝试使用时

http://localhost/assets?param1=1¶m2=2 然后searchCriteria就得到了对象的实例。

SearchCriteria 类定义为

public class SearchCriteria
{
    public SearchCriteria()
    {
        Param1 = "";
        Param2 = "";
        PageIndex = 0;
        PageSize = 10;
    }
    public string Param1 { get; set; }
    public string Param2 { get; set; }
    public int PageIndex{ get; set; }
    public int PageSize { get; set; }
}

我的方法有什么问题吗?为什么没有传递查询字符串时,action 参数为 null?

谢谢

c# asp.net-web-api2
3个回答
3
投票

嗯...因为没有数据来创建参数实例。

查看网址。 这里有用于创建参数的值:

http://localhost/assets?param1=1&param2=2

注意如何为

param1
param2
提供值,这些值直接映射到参数的类型:

public string Param1 { get; set; }
public string Param2 { get; set; }

但是在这个 URL 中,没有值:

http://localhost/assets

因此没有任何东西可以用来创建方法参数的实例。

null
字面意思是“这里什么都没有”。 由于没有提供参数值,所以那里什么也没有。


0
投票

如果您可以接受搜索条件为空,但想避免单元测试错误,请尝试

[HttpGet]
[Route("assets")]
public async Task<HttpResponseMessage> Get([FromUri]SearchCriteria searchCriteria)
{

if(searchCriteria == null)
    searchCriteria = new SearchCriteria();

}

0
投票

这是您可以尝试的自定义属性。它将工作委托给普通的 FromUriAttribute 类,然后简单地实例化该类型(如果它的值为 null)

[AttributeUsage( AttributeTargets.Parameter )]
public sealed class FromUriOrNewAttribute : ParameterBindingAttribute
{
    public override HttpParameterBinding GetBinding( HttpParameterDescriptor parameter )
    {
        return new FromUriOrNewModelBinder( parameter );
    }

    private class FromUriOrNewModelBinder : HttpParameterBinding
    {
        public FromUriOrNewModelBinder( HttpParameterDescriptor descriptor ) : base( descriptor ) { }

        public override async Task ExecuteBindingAsync( ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken )
        {
            var type = Descriptor.ParameterType;

            var binder = new FromUriAttribute( );
            var defaultBinding = binder.GetBinding( Descriptor );
            await defaultBinding.ExecuteBindingAsync( metadataProvider, actionContext, cancellationToken );

            SetValue( actionContext, actionContext.ActionArguments[ Descriptor.ParameterName ] ?? Activator.CreateInstance( type ) );
        }
    }
}

使用示例

[HttpGet]
public IHttpActionResult Endpoint( [FromUriOrNew] Model model)
{
    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.