2017-06-17 60 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啓動可能會更好一些之後,這樣你也可以獲得單個屬性的錯誤信息 –

相關問題