我有一个终点
[HttpGet]
public async Task<ActionResult> GetNodes([FromQuery] Guid? parentId)
然后这样称呼它
GET .../api/nodes?parentId=null
解析参数"The value 'null' is not valid."
时Asp.net引发异常
如果发生异常,如何重写该行为以使其将可为空的类型解析为null?
我希望:
GET .../api/nodes?parentId=null
应该用parentId == null
GET .../api/nodes?parentId=50d21ddd-6a95-46db-bff9-c943cf5b0df1
应该用parentId = "50d21ddd-6a95-46db-bff9-c943cf5b0df1"
来调用操作
GET .../api/nodes?parentId=something_not_parsable_to_guid
应该用parentId = null
来调用操作
答案 0 :(得分:1)
@Karan的解决方案是您应该使用的方法。但是,如果您不愿意更改客户端脚本,则仍然可以选择如下:
[HttpGet]
public async Task<ActionResult> GetNodes() {
var parentId = Request.QueryString["parentId"].ToString();
Guid guid;
if (Guid.TryParse(parentId , out guid))
{
// use guid here
}
}
答案 1 :(得分:1)
将您的Guid
参数转换为string
,然后尝试使用Guid.TryParse
[HttpGet]
public async Task<ActionResult> GetNodes([FromQuery] string parentId)
{
Guid guid;
if (Guid.TryParse(parentId, out guid))
{
// code when guid is not null.
// use guid object.
}
else
{
// code when guid is null.
}
}
答案 2 :(得分:0)
我刚刚做了一个简单的IModelBinder
,如果它支持默认转换,它将把字符串转换成所需类型的实例
代码看起来像这样:
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var targetType = bindingContext.ModelType;
var targetName = bindingContext.ModelName;
var stringValue = bindingContext.ValueProvider.GetValue(targetName).FirstValue;
var isNullableOrReference = Nullable.GetUnderlyingType(targetType) != null ||
!targetType.IsValueType;
var valueProvider = bindingContext.ValueProvider.GetValue(targetName);
try
{
var converter = TypeDescriptor.GetConverter(targetType);
var resultValue = converter.ConvertFromString(stringValue);
bindingContext.Result = ModelBindingResult.Success(resultValue);
bindingContext.ModelState.SetModelValue(targetName, valueProvider);
}
catch (NotSupportedException e)
{
bindingContext.Result = ModelBindingResult.Failed();
return Task.CompletedTask;
}
catch (Exception e)
{
bindingContext.Result = ModelBindingResult.Success(isNullableOrReference ? null : Activator.CreateInstance(targetType));
bindingContext.ModelState.SetModelValue(targetName, valueProvider);
}
return Task.CompletedTask;
}
它需要进行一些调整,但是它可以按我希望的那样工作