.Net рдХреЛрд░ рдореЗрдВ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдореЙрдбрд▓ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рддрдВрддреНрд░ рд╣реИ, рдЬреЛ рди рдХреЗрд╡рд▓ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдореЗрдВ рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рддреБрд░рдВрдд рднрд░реЗ рд╣реБрдП рдХреНрд╖реЗрддреНрд░реЛрдВ рд╕реЗ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдореЙрдбрд▓ рд╡реИрдзрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдВрдЪреЛрдВ рдХреЛ рдРрд╕реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдПрдореНрдмреЗрдб рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИредрдпрд╣рд╛рдВ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рд╣реИрдВ, рди рдХреЗрд╡рд▓ рдХреНрд╡реЗрд░реА рдпрд╛ рдмреЙрдбреА рд╕реЗ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрдПрдВред рдХреБрдЫ рдбреЗрдЯрд╛ рдХреЛ рд╣реЗрдбрд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдмреЗрд╕ 64 рдореЗрдВ json рдерд╛), рдХреБрдЫ рдбреЗрдЯрд╛ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдпрд╛ рдПрдХреНрд╢рдирд░реАрдЯ рд╕реЗ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдпрджрд┐ рдЖрдк REST рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд╡рд╣рд╛рдВ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рдЕрдкрдиреА рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рдЪ рд╣реИ, рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ: рдпрджрд┐ рдЖрдк рдирд┐рд░реНрдорд╛рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рдХреЛ рддреЛрдбрд╝рдиреЗ рдФрд░ рдореЙрдбрд▓ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдирд╣реАрдВ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рд╢рд░реНрдорд╕рд╛рд░ рд╣реЛрдирд╛ рдкрдбрд╝реЗрдЧрд╛редрдЕрдкрдиреЗ рд▓рд┐рдП рдФрд░ рдЖрдиреЗ рд╡рд╛рд▓реА рдкреАрдврд╝рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдФрд░ рд╢рд░реНрдорд┐рдВрджрдЧреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХреБрдЫ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛редрдореБрд╕реАрдмрдд
рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рдпрдВрддреНрд░рдХ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:[HttpGet]
public async Task<IActionResult> GetSomeData([FromQuery[IncomeData someData)
{
var moreData = GetFromHeaderAndDecode("X-Property");
if (moreData.Id == 0)
{
return StatusCode(400, "Nginx doesnt know your id");
}
var externalData = GetFromExternalService("http://myservice.com/MoreData");
if (externalData == null)
{
return StatusCode(500, "Cant connect to external service");
}
var finalData = new FinalData(someData, moreData, externalData);
return _myService.Handle(finalData);
}
рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╕реНрдпрд╛рдПрдВ рдЖрддреА рд╣реИрдВ:- рд╕рддреНрдпрд╛рдкрди рддрд░реНрдХ рдХреЛ рдЕрдиреБрд░реЛрдз рдСрдмреНрдЬреЗрдХреНрдЯ, рд╣реЗрдбрд░ рд╕реЗ рдЕрдиреБрд░реЛрдз рд╡рд┐рдзрд┐, рд╕реЗрд╡рд╛ рд╕реЗ рдЕрдиреБрд░реЛрдз рд╡рд┐рдзрд┐ рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рд╕реНрдореАрдпрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдВрдЪ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╣реИ, рдЖрдкрдХреЛ рдкреВрд░реА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ!
- рдЖрд╕рдиреНрди рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐ рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рд╕рдорд╛рди рдХреЛрдб рд╣реЛрдЧрд╛ред рд╣рдорд▓реЗ рдореЗрдВ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧред
- рдЖрдорддреМрд░ рдкрд░ рдЙрджрд╛рд╣рд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЪреЗрдХ рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдХреЗрд╡рд▓ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓рд╛рдЗрди - рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ - рдХреЛрдб рдХреЗ рдвреЗрд░ рдореЗрдВ рдЫрд┐рдкрд╛ рд╣реБрдЖ рд╣реИред рдЙрд╕реЗ рджреЗрдЦрдиреЗ рдФрд░ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ, рдХреБрдЫ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдХрд╕реНрдЯрдо рдмрдВрдзрди (рдЖрд╕рд╛рди рдореЛрдб)
рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рдЕрдкрдиреЗ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рдЕрдВрддрд┐рдо рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рддреБрд░рдВрдд рд╡рд┐рдзрд┐ рд╕реЗ рдкрд╛рд╕ рдХрд░рдХреЗ рд╣рдорд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдареАрдХ рдХрд░реЗрдВред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ, рд╣реИ рдирд╛?[HttpGet]
public async Task<IActionResult> GetSomeData([FromQuery]FinalData finalData)
{
return _myService.Handle(finalData);
}
рдЗрд╕рдХреЗ рдмрд╛рдж, MoreData рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдмрд╛рдЗрдВрдбрд░ рдмрдирд╛рдПрдВредpublic class MoreDataBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var moreData = GetFromHeaderAndDecode(bindingContext.HttpContext.Request.Headers);
if (moreData != null)
{
bindingContext.Result = ModelBindingResult.Success(moreData);
}
return Task.CompletedTask;
}
private MoreData GetFromHeaderAndDecode(IHeaderDictionary headers) { ... }
}
рдЕрдВрдд рдореЗрдВ, рд╣рдо рд╡рд╣рд╛рдВ рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдмрд╛рдЗрдВрдбрд░ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдЬреЛрдбрд╝рдХрд░ рдлрд╝рд╛рдЗрдирд▓рдбрд╛рдЯрд╛ рдореЙрдбрд▓ рдХреЛ рдареАрдХ рдХрд░ рджреЗрдВрдЧреЗ:public class FinalData
{
public int SomeDataNumber { get; set; }
public string SomeDataText { get; set; }
[ModelBinder(BinderType = typeof(MoreDataBinder))]
public MoreData MoreData { get; set; }
}
рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╡рд╛рд╕реАрд░ рдореЗрдВ рд╡реГрджреНрдзрд┐ рд╣реБрдИ рд╣реИ: рдЕрдм рдЖрдкрдХреЛ рдпрд╣ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╣реИрдВрдбрд▓рд░ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕рднреА рдореЙрдбрд▓реЛрдВ рдореЗрдВ рджрд░реНрд╢рд╛рдПрдВред рд▓реЗрдХрд┐рди рдпрд╣ рд╕реЙрд▓реНрд╡ рд╣реИредрдЕрдкрдирд╛ BinderProvider рдмрдирд╛рдПрдВ:public class MoreDataBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
var modelType = context.Metadata.UnderlyingOrModelType;
if (modelType == typeof(MoreData))
{
return new BinderTypeModelBinder(typeof(MoreDataBinder));
}
return null;
}
}
рдФрд░ рдЗрд╕реЗ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ:public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new MoreDataBinderProvider());
});
}
рдкреНрд░рджрд╛рддрд╛ рдХреЛ рдХрддрд╛рд░ рдХреЗ рдХреНрд░рдо рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдореЙрдбрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╣рдорд╛рд░рд╛ рдкреНрд░рджрд╛рддрд╛ рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рдХрд╛рд░ рд╕реЗ рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╡рд╛рдВрдЫрд┐рдд рдмрд╛рдЗрдВрдбрд░ рд▓реМрдЯрд╛ рджреЗрдЧрд╛ред рдФрд░ рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдмрд╛рдЗрдВрдбрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рддреЛ рдЕрдм рдЬрдм рднреА рд╣рдо MoreData рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рд╣реЗрдбрд░ рд╕реЗ рд▓рд┐рдпрд╛ рдФрд░ рдбрд┐рдХреЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдореЙрдбрд▓ рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИредрдХрд╕реНрдЯрдо рдмрд╛рдЗрдВрдбрд┐рдВрдЧ (рд╣рд╛рд░реНрдб рдореЛрдб)
рдпрд╣ рд╕рдм рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдмрд╛рдд рд╣реИ рд▓реЗрдХрд┐рди: рдЬрд╛рджреВ рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдореЗрдВ рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЧреБрдг рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдЗрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рдХрд╛ рдХреНрдпрд╛? рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдореИрдВ рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдЕрдиреБрд░реЛрдз рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рдЬрд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рд╡рд╣рд╛рдВ рдирд╣реАрдВ рдмрджрд▓рд╛ рдЬрд╛рдПрдЧрд╛?рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдмрд╛рдЗрдВрдбрд░ рдЙрди рдореЙрдбрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдирдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣рдореЗрдВ рдЦреБрдж рдХреЛ рд▓рд┐рдЦрдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ?рдЬрд┐рд╕ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рдпрд╣ рдХреЛрдб рд▓рд┐рдЦрд╛ рдерд╛ рд╡рд╣ REST рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗрд╡рд▓ рдХреНрд╡реЗрд░реА рдФрд░ рдмреЙрдбреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░реЗрд╖рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдХреЗрд╡рд▓ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
рдФрд░ рдкреЛрд╕реНрдЯ рдХрд░реЗрдВред рддрджрдиреБрд╕рд╛рд░, рдЖрд░рдИрдПрд╕рдЯреА рдПрдкреАрдЖрдИ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рддрд░реНрдХ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рд╣реЛрдЧрд╛ред
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХреЛрдб рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд░рд╣реЗрдЧрд╛, рдХреЗрд╡рд▓ рд╣рдорд╛рд░реЗ рдмрд╛рдЗрдВрдбрд░ рдХреЛ рд╢реЛрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╡рд╣ рдПрдХ рд╡рд╕реНрддреБ рдмрдирд╛ рд╕рдХреЗ рдФрд░ рдЕрдкрдиреЗ рдирд┐рдЬреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рднрд░ рд╕рдХреЗред рдЖрдЧреЗ рдореИрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЗ рджреВрдВрдЧрд╛, рдЬрд┐рдиреНрд╣реЗрдВ рдХреЛрдИ рджрд┐рд▓рдЪрд╕реНрдкреА рдирд╣реАрдВ рд╣реИ - рдмрд┐рд▓реНрд▓реА рдХреЗ рдиреАрдЪреЗ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рдХрдХреНрд╖рд╛ рдХреА рдкреВрд░реА рд╕реВрдЪреА рд╣реИредрдкрд╣рд▓реЗ, рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ рдХрд┐ рдХреНрдпрд╛ MoreData рдХреЗрд╡рд▓ рд╡рд░реНрдЧ рдХреА рд╕рдВрдкрддреНрддрд┐ рд╣реИред рдпрджрд┐ рд╣рд╛рдБ, рддреЛ рдЖрдкрдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реНрд╡рдпрдВ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рд╣реИрд▓реЛ, рдПрдХреНрдЯрд┐рд╡реЗрдЯрд░), рдФрд░ рдпрджрд┐ рдирд╣реАрдВ, рддреЛ JsonConvert рдХрд╛рдо рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд░реЗрдЧрд╛, рдФрд░ рд╣рдо рд╕рд┐рд░реНрдл рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдкрд░реНрдЪреА рдХрд░рддреЗ рд╣реИрдВредprivate static bool NeedActivator(IReflect modelType)
{
var propFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
var properties = modelType.GetProperties(propFlags);
return properties.Select(p => p.Name).Distinct().Count() == 1;
}
JsonConvert рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рд╡рд╕реНрддреБ рдмрдирд╛рдирд╛ рд╕рд░рд▓ рд╣реИ, рд╢рд░реАрд░ рдХреЗ рд╕рд╛рде рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП:private static object? GetModelFromBody(ModelBindingContext bindingContext, Type modelType)
{
using var reader = new StreamReader(bindingContext.HttpContext.Request.Body);
var jsonString = reader.ReadToEnd();
var data = JsonConvert.DeserializeObject(jsonString, modelType);
return data;
}
рд▓реЗрдХрд┐рди рдХреНрд╡реЗрд░реА рдХреЗ рд╕рд╛рде рдореБрдЭреЗ рд▓реЗрдЯрдирд╛ рдкрдбрд╝рд╛ред рдореБрдЭреЗ рдЦреБрд╢реА рд╣реЛрдЧреА рдЕрдЧрд░ рдХреЛрдИ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рд╕рдорд╛рдзрд╛рди рд╕реБрдЭрд╛ рд╕рдХрддрд╛ рд╣реИредрдПрдХ рд╕рд░рдгреА рдкрд╛рд╕ рдХрд░рддреЗ рд╕рдордп, рд╕рдорд╛рди рдирд╛рдо рд╡рд╛рд▓реЗ рдХрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдПрдХ рдлреНрд▓реИрдЯ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдХрд░рдиреЗ рд╕реЗ рдорджрдж рдорд┐рд▓рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрд░рдорд╛рдВрдХрди рд╕рд░рдгреА рдкрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдЙрджреНрдзрд░рдг рдбрд╛рд▓рддрд╛ рд╣реИ [], рдЬрд┐рд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╣рдЯрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПредprivate static object? GetModelFromQuery(ModelBindingContext bindingContext, Type modelType)
{
var valuesDictionary = QueryHelpers.ParseQuery(bindingContext.HttpContext.Request.QueryString.Value);
var jsonDictionary = valuesDictionary.ToDictionary(pair => pair.Key, pair => pair.Value.Count < 2 ? pair.Value.ToString() : $"[{pair.Value}]");
var jsonStr = JsonConvert.SerializeObject(jsonDictionary).Replace("\"[", "[").Replace("]\"", "]");
var data = JsonConvert.DeserializeObject(jsonStr, modelType);
return data;
}
рдЕрдВрдд рдореЗрдВ, рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реБрдП, рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛ рдХреЛ рдЙрд╕рдХреА рдирд┐рдЬреА рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдпрд╣ рдЗрд╕ shamanism рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдерд╛ рдЬреЛ рдореИрдВрдиреЗ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдмреЛрд▓рд╛ рдерд╛ред рдореБрдЭреЗ рдпрд╣ рд╕рдорд╛рдзрд╛рди рдпрд╣рд╛рдВ рдорд┐рд▓рд╛ , рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд▓реЗрдЦрдХ рдХреЛ рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджредprivate void ForceSetValue(PropertyInfo propertyInfo, object obj, object value)
{
var propName = $"<{propertyInfo.Name}>k__BackingField";
var propFlags = BindingFlags.Instance | BindingFlags.NonPublic;
obj.GetType().GetField(propName, propFlags)?.SetValue(obj, value);
}
рдЦреИрд░, рд╣рдо рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдПрдХ рдХреЙрд▓ рдореЗрдВ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:public Task BindModelAsync(ModelBindingContext bindingContext)
{
var moreData = GetFromHeaderAndDecode(bindingContext.HttpContext.Request.Headers);
if (moreData == null)
{
return Task.CompletedTask;
}
var modelType = bindingContext.ModelMetadata.UnderlyingOrModelType;
if (NeedActivator(modelType))
{
var data = Activator.CreateInstance(modelType, moreData);
bindingContext.Result = ModelBindingResult.Success(data);
return Task.CompletedTask;
}
var model = bindingContext.HttpContext.Request.Method == "GET"
? GetModelFromQuery(bindingContext, modelType)
: GetModelFromBody(bindingContext, modelType);
if (model is null)
{
throw new Exception(" ");
}
var ignoreCase = StringComparison.InvariantCultureIgnoreCase;
var dataProperty = modelType.GetProperties()
.FirstOrDefault(p => p.Name.Equals(typeof(T).Name, ignoreCase));
if (dataProperty != null)
{
ForceSetValue(dataProperty, model, moreData);
}
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
рдпрд╣ рдмрд╛рдЗрдВрдбрд░рдкреНрд░реЛрдЗрдбрд░ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рд╡рд╛рдВрдЫрд┐рдд рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рднреА рд╡рд░реНрдЧ рдХреЛ рдЬрд╡рд╛рдм рджреЗ:public class MoreDataBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
var modelType = context.Metadata.UnderlyingOrModelType;
if (HasDataProperty(modelType))
{
return new BinderTypeModelBinder(typeof(PrivateDataBinder<MoreData>));
}
return null;
}
private bool HasDataProperty(IReflect modelType)
{
var propFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
var properties = modelType.GetProperties(propFlags);
return properties.Select(p => p.Name) .Contains(nameof(MoreData));
}
}
рдмрд╕ рдЗрддрдирд╛ рд╣реАред рдмрд╛рдЗрдВрдбрд░ рдИрдЬрд╝реА рдореЛрдб рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдирд┐рдХрд▓рд╛, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдо рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЗ рдмрд┐рдирд╛ рд╕рднреА рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЗ рд╕рднреА рддрд░реАрдХреЛрдВ рдореЗрдВ "рдмрд╛рд╣рд░реА" рдЧреБрдгреЛрдВ рдХреЛ рдмрд╛рдВрдз рд╕рдХрддреЗ рд╣реИрдВред Minuses рдХреА:- рдирд┐рдЬреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ [JsonConstrustor] рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдореЙрдбрд▓ рдХреЗ рддрд░реНрдХ рдореЗрдВ рдлрд┐рдЯ рдмреИрдарддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдзрд╛рд░рдгрд╛ рдореЗрдВ рд╣рд╕реНрддрдХреНрд╖реЗрдк рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
- рдХрд╣реАрдВ, рдЖрдкрдХреЛ рд╣реЗрдбрд░ рд╕реЗ рдореЛрд░реЗрдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдмрдирд╛рдХрд░ рдЗрд╕рдХрд╛ рдЗрд▓рд╛рдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рдмрд╛рдХреА рдЯреАрдо рдХреЛ рдЬрд╛рджреВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдкреНрд░рд▓реЗрдЦрди рдорд╛рдирд╡рддрд╛ рдХреЛ рдмрдЪрд╛рдПрдЧрд╛ред
рдкрд░рд┐рдгрд╛рдореА рдмрд╛рдЗрдВрдбрд░ рдХреА рдкреВрд░реА рд╕реВрдЪреА рдпрд╣рд╛рдБ рд╣реИ:PrivateMoreDataBinder.cspublic class PrivateDataBinder<T> : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var moreData = GetFromHeaderAndDecode(bindingContext.HttpContext.Request.Headers);
if (moreData == null)
{
return Task.CompletedTask;
}
var modelType = bindingContext.ModelMetadata.UnderlyingOrModelType;
if (NeedActivator(modelType))
{
var data = Activator.CreateInstance(modelType, moreData);
bindingContext.Result = ModelBindingResult.Success(data);
return Task.CompletedTask;
}
var model = bindingContext.HttpContext.Request.Method == "GET"
? GetModelFromQuery(bindingContext, modelType)
: GetModelFromBody(bindingContext, modelType);
if (model is null)
{
throw new Exception(" ");
}
var ignoreCase = StringComparison.InvariantCultureIgnoreCase;
var dataProperty = modelType.GetProperties()
.FirstOrDefault(p => p.Name.Equals(typeof(T).Name, ignoreCase));
if (dataProperty != null)
{
ForceSetValue(dataProperty, model, moreData);
}
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
private static object? GetModelFromQuery(ModelBindingContext bindingContext,
Type modelType)
{
var valuesDictionary = QueryHelpers.ParseQuery(bindingContext.HttpContext.Request.QueryString.Value);
var jsonDictionary = valuesDictionary.ToDictionary(pair => pair.Key, pair => pair.Value.Count < 2 ? pair.Value.ToString() : $"[{pair.Value}]");
var jsonStr = JsonConvert.SerializeObject(jsonDictionary)
.Replace("\"[", "[")
.Replace("]\"", "]");
var data = JsonConvert.DeserializeObject(jsonStr, modelType);
return data;
}
private static object? GetModelFromBody(ModelBindingContext bindingContext,
Type modelType)
{
using var reader = new StreamReader(bindingContext.HttpContext.Request.Body);
var jsonString = reader.ReadToEnd();
var data = JsonConvert.DeserializeObject(jsonString, modelType);
return data;
}
private static bool NeedActivator(IReflect modelType)
{
var propFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
var properties = modelType.GetProperties(propFlags);
return properties.Select(p => p.Name).Distinct().Count() == 1;
}
private void ForceSetValue(PropertyInfo propertyInfo, object obj, object value)
{
var propName = $"<{propertyInfo.Name}>k__BackingField";
var propFlags = BindingFlags.Instance | BindingFlags.NonPublic;
obj.GetType().GetField(propName, propFlags)?.SetValue(obj, value);
}
private T GetFromHeaderAndDecode(IHeaderDictionary headers) { return (T)Activator.CreateInstance(typeof(T), new object[] { "ok" }); }
}