2017-06-17 37 views
2

以下asp.net中的代码web API工作正常,但在Asp.net核心中不起作用。如何在asp.net核心web api中绑定Json查询字符串

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

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

[FromUri]属性不存在asp.net核心网络API,我试图用以下,但没有成功。

[HttpGet] 
public Device Get([FromQuery] string deviceName) 
{ 
    return repo.GetDeviceByName(deviceName); 
} 
+0

好像非功能性的代码。 **参数**被称为'query'而不是'deviceName'。 'deviceName'是一些类似json的查询参数的属性。为了得到你应该只使用查询参数和post请求身体内的数据传输。如果您真的想要这种非标准方式(与ASP.NET Core无关)仍然可以工作,那么您需要编写自己的模型绑定器 – Tseng

回答

2

不幸的是,没有办法在GET查询中绑定JSON,就像你在那里一样。你正在寻找的是使用自定义模型联编程序来告诉ASP.net核心你想如何绑定。

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

public class MyCustomModel 
{ 
    public string DeviceName { get; set; } 
} 

接下来,您需要构建模型联编程序。下面给出了一个简单的例子,但是您显然需要进行其他检查,如果它可以被转换,Try/Catch块等。实质上,模型联编程序告诉ASP.net核心模型应该如何绑定。你也可能遇到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; 
    } 
} 

所以我们正在做的是将查询字符串和反序列化到我们的模型。

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

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

     return null; 
    } 
} 

而最后一块拼图。在我们的startup.cs中,我们找到了添加MVC服务的位置,并将模型绑定器插入到列表的前面。这个很重要。如果我们只是将我们的模型绑定器添加到列表中,另一个模型绑定器可能会认为它应该被使用(首先在第一次服务),所以我们可能永远不会使它成为我们的。所以一定要在开始时插入它。

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

现在我们只是创建一个读取数据的操作,不需要属性。

[HttpGet] 
public void Get(MyCustomModel model) 
{ 

} 

进一步阅读:

+0

谢谢。它确实有帮助。如果我在api控制器中有两个Get方法,则获取所有设备,其他Get方法获取设备名称。我有相同的Get方法的错误。 – Rohit

+0

如果他们都接受相同的有效负载(整个JSON对象),那么你应该只需要一个权利? – MindingData

+0

现在,对于您创建的每个自定义模型绑定,您都必须确保您的json可以反序列化它。使用json值提供程序并使默认模型vinder启动可能会更好一些之后,这样你也可以获得单个属性的错误信息 –

相关问题