我假設您的請求數據中有一個屬性orderBy
,您想使用OrderExpression.TryParse
綁定到OrderExpression
。
讓我們假設你的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如何通過創建JsonConverter格式化OrderExpression
類型的屬性:
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,只是想知道你是否有機會嘗試我提出的解決方案? –