Обработка исключений, вызванных анализом обнуляемых параметров в действии контроллера - PullRequest
1 голос
/ 29 мая 2019

У меня есть конечная точка

[HttpGet]
public async Task<ActionResult> GetNodes([FromQuery] Guid? parentId)

И назови это так GET .../api/nodes?parentId=null
Asp.net генерирует исключение при разборе параметра "The value 'null' is not valid."
Как переопределить это поведение, чтобы оно могло анализировать обнуляемые типы в 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

Ответы [ 3 ]

1 голос
/ 29 мая 2019

Преобразуйте параметр 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.
        }
}
1 голос
/ 29 мая 2019

Решение от @Karan - путь, по которому вы должны идти.Но если вы не желаете изменять свой скрипт на стороне клиента, у вас все равно есть опция:

[HttpGet]
public async Task<ActionResult> GetNodes() {
     var parentId = Request.QueryString["parentId"].ToString();
     Guid guid;
     if (Guid.TryParse(parentId , out guid))
     {
       // use guid here
     }

}
0 голосов
/ 01 июня 2019

Я только что сделал простой 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;
}

Требуетсябыть немного настроенным, но это работает, как я хотел, чтобы это было

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...