外部服務正在使用格式為 mysite.com/date/2021&4&12 的 URL 呼叫我的 .NET Core API。我無法控制它如何呼叫我的 API,所以我必須適應這種 URL 格式。
我可以在我的控制器操作方法中解決這個問題
[HttpGet("date/{dateString}")]
public Thing GetThingByDate(string dateString)
{
//...string manipulation on dateString
}
但是是否有可能讓 .NET Core 完成這項作業,甚至自己撰寫一些東西,這樣我就可以得到
[HttpGet("date/((some kind of formatting here))")]
public Thing GetThingByDate(int year, int month, int day)
{
}
uj5u.com熱心網友回復:
是的,這是可能的。使其可重用的一種方法是為此創建自定義模型和模型系結器。
首先這是我的天真控制器實作:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
[HttpGet("{**slug}")]
public IActionResult Get(MyDateModel slug)
{
return Ok(slug);
}
}
[ModelBinder(BinderType = typeof(MyDateModelBinder))]
public class MyDateModel
{
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
}
這{**slug}是一個包羅萬象的屬性,所以所有尚未系結的東西都被扔到一個名為“slug”的變數中。在我們的例子中“2021&4&12”
我們還使用我們的年、月和日屬性創建了一個新的視圖模型,并將其系結到我們尚未創建的模型系結器。
現在所有的魔法都發生了。Microsoft 在https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-5.0提供了一個很好的示例作為起點。我們將以此為基礎開展作業:
public class MyDateModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var modelName = bindingContext.ModelName;
// Try to fetch the value of the argument by name
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
var rawValue = valueProviderResult.FirstValue;
// Check if the argument value is null or empty
if (string.IsNullOrEmpty(rawValue))
{
return Task.CompletedTask;
}
// parse the string to the target value
try
{
var values = rawValue.Split("&");
var model = new MyDateModel
{
Year = Int32.Parse(values[0]),
Month = Int32.Parse(values[1]),
Day = Int32.Parse(values[2]),
};
bindingContext.Result = ModelBindingResult.Success(model);
}
catch (Exception ex)
{
bindingContext.ModelState.TryAddModelError(
modelName, ex.Message);
}
return Task.CompletedTask;
}
}
I'm not going to go into too much detail, at to what happens at which line, as you can set a breakpoint and get a good Eureka! - moment your self. Please be aware, that this rather naive implementation is missing quiet a lot of robustness and error handling - so if your string is in a wrong format or has a wrong delimiter, it wont work and your error messages might not be suitable for clients.
In our example now, I've issed the request https://localhost:5001/api/values/2021&4&12 and it returned the following values as JSON:
{
"year": 2021,
"month": 4,
"day": 12
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/344523.html
