如何在asp.net核心web api中绑定Json Query字符串

Roh*_*hit 7 c# asp.net-mvc asp.net-web-api asp.net-core

以下代码在asp.net web API工作正常但在Asp.net核心中不起作用.

端点 api/devices?query={"deviceName":"example"}

[HttpGet]
public Device ([FromUri] string deviceName)
{        
        var device = context.Computers.Where(x => x.deviceName == deviceName);
        return device;
}
Run Code Online (Sandbox Code Playgroud)

[FromUri]属性不是asp.net核心网API,我尝试使用以下,但没有成功.

[HttpGet]
public Device  Get([FromQuery] string  deviceName)
{
    return repo.GetDeviceByName(deviceName);
}
Run Code Online (Sandbox Code Playgroud)

Min*_*ata 6

不幸的是,您无法像在那儿一样在GET查询中绑定JSON。您正在寻找的是使用自定义模型绑定器来告诉ASP.net Core您希望如何绑定。

首先,您要为JSON对象构建模型。

public class MyCustomModel
{
    public string DeviceName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

接下来,您需要构建模型绑定程序。下面给出了一个简单的示例,但是您显然希望进行其他检查,以确定是否可以转换,尝试/捕获块等。实质上,模型绑定器告诉ASP.net Core如何绑定模型。您可能还会遇到给定类型的TypeConverters,如何在模型绑定期间将其更改为另一种类型。现在,让我们只使用modelbinders。

public class MyViewModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var jsonString = bindingContext.ActionContext.HttpContext.Request.Query["query"];
        MyCustomModel result = JsonConvert.DeserializeObject<MyCustomModel>(jsonString);

        bindingContext.Result = ModelBindingResult.Success(result);
        return Task.CompletedTask;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,我们要做的就是获取查询字符串并将其反序列化为模型。

接下来,我们建立一个提供程序。提供程序告诉ASP.net核心使用哪个modelbinder。在我们的例子中,很简单,如果模型类型是我们的自定义类型,则使用我们的自定义绑定器。

public class MyViewModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context.Metadata.ModelType == typeof(MyCustomModel))
            return new MyViewModelBinder();

        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后的难题。在startup.cs中,我们找到要在其中添加MVC服务的位置,并将模型绑定程序插入列表的前面。这个很重要。如果我们仅将modelbinder添加到列表中,则另一个模型绑定器可能会认为应该改用它(第一个先服务),因此我们可能永远也不会这样做。因此,请务必在开始时将其插入。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(config => config.ModelBinderProviders.Insert(0, new MyViewModelBinderProvider()));
}
Run Code Online (Sandbox Code Playgroud)

现在,我们只需要创建一个操作即可读取数据,无需任何属性。

[HttpGet]
public void Get(MyCustomModel model)
{

}
Run Code Online (Sandbox Code Playgroud)

进一步阅读: