Есть ли способ получить конечную точку с использованием обобщений в WebAPI с C#? - PullRequest
1 голос
/ 28 января 2020

с. net ядро ​​и ньютон JSON. Могу ли я иметь конечную точку, используя дженерики? Как мне попросить передать тип c generi?

public async Task<JsonResult> SaveSetting<T>([FromBody] Filter<T> model)
{}

public class Filter<T>
{
    public string GUID { get; set; }

    public string Name { get; set; }

    public FilterType FilterType { get; set; }

    public T FilterRequestModel { get; set; }
}

1 Ответ

4 голосов
/ 28 января 2020

Маловероятно, что есть простой способ сделать эту работу, если есть способ вообще. Что еще более важно, это было бы крайне нежелательно. Предположительно, вам нужно выяснить, какой тип T должен быть основан на входных данных из пользовательского интерфейса, а затем вы будете привязывать значения к этому типу с помощью привязок JSON. Это означает, что вы позволите вызывающей стороне (которой вы не можете доверять) заставить ваш код создавать экземпляры и задавать свойства для типа C# по своему выбору, который представляет уязвимость безопасности .

Есть хороший шанс, что вы можете заставить эту конечную точку делать то, что вы хотите, без обобщений: просто используйте JObject в качестве объекта FilterRequestModel. Если вы действительно полагаетесь на фактические C# типы для достижения sh того, что вы хотите, вам все же лучше сделать так, чтобы действие вашего контроллера использовало JObject, и использовать некоторые пользовательские логики c для его перевода на основе некоторых пользовательский ввод, после проверки того, что указанный тип - это то, что вы хотите, чтобы вызывающие абоненты могли создавать. После того как вы создали объект пользовательского типа, вы можете привести его к dynamic перед передачей его в вспомогательный метод c generi, и тип generi c будет автоматически преобразован во время выполнения в тип объект, который вы создали.

public async Task<JsonResult> SaveSetting([FromBody] Filter<JObject> model)
{
    Type filterRequestModelType = this.DetermineSafeModelType(model);
    object typedFilterRequestModel = model.FilterRequestModel.ToObject(filterRequestModelType);
    return SaveSettingHelper(model, (dynamic) typedFilterRequestModel);
}

public async Task<JsonResult> SaveSetting<T>([FromBody] Filter<JObject> model, T filterRequestModel) {...}

...