You can custom the model binding like below:
public class CreatedByModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
var claim = int.Parse(bindingContext.HttpContext.User.FindFirst("KeyName").Value);
bindingContext.Result = ModelBindingResult.Success(claim);
return Task.CompletedTask;
}
}
Model:
public class CreatePlugin
{
[Required]
[JsonProperty("name"), JsonPropertyName("name")]
public string Name { get; set; }
//...
[NSwag.Annotations.SwaggerIgnore]
[ModelBinder(BinderType = typeof(CreatedByModelBinder))]
[JsonProperty("created_by"), JsonPropertyName("created_by")]
public int CreatedBy { get; set; }
}
Controller:
Not sure how do you add the claims, I just add the claim in cookie authentication.
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public async Task<IActionResult> GetAsync()
{
var claims = new List<Claim>
{
new Claim("KeyName","4")
};
var authProperties = new AuthenticationProperties
{
IssuedUtc = DateTimeOffset.UtcNow,
ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1),
IsPersistent = false
};
const string authenticationType = "Cookies";
var claimsIdentity = new ClaimsIdentity(claims, authenticationType);
await HttpContext.SignInAsync(authenticationType, new ClaimsPrincipal(claimsIdentity), authProperties);
return Ok();
}
[HttpPost]
[Produces("application/json")]
public async Task<IActionResult> Add([FromForm]CreatePlugin plugin) //add FromForm....
{
//some logic
return Ok();
}
}
Result:

UPDATE:
If you must using FromBody
, you can custom JsonConverter for the model:
public class CreatedByConverter : Newtonsoft.Json.JsonConverter
{
private readonly IHttpContextAccessor httpContextAccessor;
public CreatedByConverter(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(CreatePlugin));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
{
var claim = int.Parse(httpContextAccessor.HttpContext.User.FindFirst("KeyName").Value);
JObject obj = JObject.Load(reader);
CreatePlugin root = new CreatePlugin();
root.Name = (string)obj["name"];
root.Description = (string)obj["description"];
root.Version = (string)obj["version"];
root.Public = (bool)obj["public"];
root.CreatedBy = claim;
return root;
}
public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
{
JToken t = JToken.FromObject(value);
if (t.Type != JTokenType.Object)
{
t.WriteTo(writer);
}
else
{
JObject o = (JObject)t;
o.WriteTo(writer);
}
}
}
Model:
Note: If you get the claim from HttpContext, you need inject the service and cannot use JsonConverter attribute any more. You need register it in Startup.cs
public class CreatePlugin
{
[Required]
[JsonProperty("name"), JsonPropertyName("name")]
public string Name { get; set; }
//more property...
[NSwag.Annotations.SwaggerIgnore]
//[Newtonsoft.Json.JsonConverter(typeof(CreatedByConverter))]
[JsonProperty("created_by"), JsonPropertyName("created_by")]
public int CreatedBy { get; set; }
}
Controller:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public async Task<IActionResult> GetAsync()
{
//add claims like the first answer..
return Ok();
}
[HttpPost]
[Produces("application/json")]
public async Task<IActionResult> Add(CreatePlugin plugin)
{
//some logic
return Ok(plugin);
}
}
Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
var httpContextAccessor = new HttpContextAccessor();
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.Converters.Add(new CreatedByConverter(httpContextAccessor));
});
services.AddSingleton<IHttpContextAccessor>(httpContextAccessor);
services.AddSwaggerDocument();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(o => o.LoginPath = new PathString("/account/login"));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseOpenApi();
app.UseSwaggerUi3();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}