Я предполагаю, что в ваших запросах есть свойство orderBy
, которое вы хотите связать в OrderExpression
, используя OrderExpression.TryParse
.
Давайте предположим, что ваш OrderExpression
класс выглядит следующим образом, где я обеспечил очень простую реализацию Вашего TryParse
метода:
public class OrderExpression
{
public string RawValue { get; set; }
public static bool TryParse(string value, out OrderExpression expr)
{
expr = new OrderExpression { RawValue = value };
return true;
}
}
Тогда вы могли бы создать модель связующее вещество, которое в основном получает необработанное значение строки и вызывает OrderExpression.TryParse
:
public class OrderExpressionBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var values = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (values.Length == 0) return Task.CompletedTask;
// Attempt to parse
var stringValue = values.FirstValue;
OrderExpression expression;
if (OrderExpression.TryParse(stringValue, out expression))
{
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, expression, stringValue);
bindingContext.Result = ModelBindingResult.Success(expression);
}
return Task.CompletedTask;
}
}
Вам также потребуется новый поставщик модель связующего, которая возвращает свой новый связующий только для OrderExpression
типа:
public class OrderExpressionBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
return context.Metadata.ModelType == typeof(OrderExpression) ? new OrderExpressionBinder() : null;
}
}
// It should be registered in your Startup class, adding it to the ModelBinderProviders collection:
services.AddMvc(opts => {
opts.ModelBinderProviders.Insert(0, new OrderExpressionBinderProvider());
});
С помощью этого на месте вы сможете связать параметры контроллера с контроллером OrderExpression
. Нечто подобное в следующем примере:
[HttpPost]
public IActionResult Products([FromBody]OrderExpression orderBy)
{
return Ok();
}
$.ajax({
method: 'POST',
dataType: 'json',
url: '/home/products',
data: {orderby: 'my orderby expression'}
});
Однако есть что-то другое, что должно быть сделано для вас, чтобы иметь возможность отправить JSON и привязать его к сложной модели, как GetProductsModel
который внутри содержит OrderExpression
. Я говорю о сценарии, как это:
[HttpPost]
public IActionResult Products([FromBody]GetProductsModel model)
{
return Ok();
}
public class GetProductsModel
{
public OrderExpression OrderBy { get; set; }
}
$.ajax({
method: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
url: '/home/products',
data: JSON.stringify({orderby: 'my orderby expression'})
});
В этом сценарии ASP.Net Ядро будет использовать только Newtonsoft.Json как InputFormatter и преобразовать полученный в JSON экземпляр GetProductsModel
модели, не пытаясь использовать новый OrderExpressionBinderProvider
для внутреннего имущества.
К счастью, вы можете также сказать Newtonsoft.Json, как форматировать свойства OrderExpression
типа путем создания JsonConverter:
public class OrderExpressionJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(OrderExpression);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var stringValue = reader.Value?.ToString();
OrderExpression expression;
if (OrderExpression.TryParse(stringValue, out expression))
{
return expression;
}
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Какими должны быть зарегистрированы в классе запуска:
services.AddMvc(opts => {
opts.ModelBinderProviders.Insert(0, new OrderExpressionBinderProvider());
}).AddJsonOptions(opts => {
opts.SerializerSettings.Converters.Add(new OrderExpressionJsonConverter());
});
Теперь вам наконец, смогут обрабатывать оба сценария :)
Вы пытаетесь связать свойства OrderExpression или пытаетесь привязать OrderExpression к вводу контроллера/action, который будет строковым вводом, а затем отобразит объект OrderExpression? –
@AshleyLee Я пытаюсь привязать OrderExpression к вводу действия контроллера ... Помогает ли это? –
@MiguelMoura, просто интересно, есть ли у вас шанс попробовать мое предложенное решение? –