BodyOrDefaultModelBinder.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System;
  2. using System.Text;
  3. using System.Threading.Tasks;
  4. using Microsoft.AspNetCore.Http;
  5. using Microsoft.AspNetCore.Mvc.ModelBinding;
  6. using Newtonsoft.Json;
  7. using Newtonsoft.Json.Linq;
  8. namespace Masuit.Tools.AspNetCore.ModelBinder
  9. {
  10. public class BodyOrDefaultModelBinder : IModelBinder
  11. {
  12. private readonly IModelBinder _bodyBinder;
  13. private readonly IModelBinder _complexBinder;
  14. public BodyOrDefaultModelBinder(IModelBinder bodyBinder, IModelBinder complexBinder)
  15. {
  16. _bodyBinder = bodyBinder;
  17. _complexBinder = complexBinder;
  18. }
  19. public async Task BindModelAsync(ModelBindingContext bindingContext)
  20. {
  21. var request = bindingContext.HttpContext.Request;
  22. request.EnableBuffering();
  23. var buffer = new byte[Convert.ToInt32(request.ContentLength)];
  24. _ = await request.Body.ReadAsync(buffer, 0, buffer.Length);
  25. var text = Encoding.UTF8.GetString(buffer);
  26. request.Body.Position = 0;
  27. if (bindingContext.ModelType.IsPrimitive || bindingContext.ModelType == typeof(string) || bindingContext.ModelType.IsEnum || bindingContext.ModelType == typeof(DateTime) || bindingContext.ModelType == typeof(Guid))
  28. {
  29. var parameter = bindingContext.ModelMetadata.ParameterName;
  30. var value = "";
  31. if (request.Query.ContainsKey(parameter))
  32. {
  33. value = request.Query[parameter] + "";
  34. }
  35. else if (request.ContentType.StartsWith("application/json"))
  36. {
  37. value = JObject.Parse(text)[parameter] + "";
  38. }
  39. else if (request.HasFormContentType)
  40. {
  41. value = request.Form[bindingContext.ModelMetadata.ParameterName] + "";
  42. }
  43. if (value.TryConvertTo(bindingContext.ModelType, out var result))
  44. {
  45. bindingContext.Result = ModelBindingResult.Success(result);
  46. }
  47. return;
  48. }
  49. if (request.HasFormContentType)
  50. {
  51. if (bindingContext.ModelType.IsClass)
  52. {
  53. await DefaultBindModel(bindingContext);
  54. }
  55. else
  56. {
  57. bindingContext.Result = ModelBindingResult.Success(request.Form[bindingContext.ModelMetadata.ParameterName].ToString().ConvertTo(bindingContext.ModelType));
  58. }
  59. return;
  60. }
  61. try
  62. {
  63. bindingContext.Result = ModelBindingResult.Success(JsonConvert.DeserializeObject(text, bindingContext.ModelType) ?? request.Query[bindingContext.ModelMetadata.ParameterName!].ToString().ConvertTo(bindingContext.ModelType));
  64. }
  65. catch
  66. {
  67. await DefaultBindModel(bindingContext);
  68. }
  69. }
  70. private async Task DefaultBindModel(ModelBindingContext bindingContext)
  71. {
  72. await _bodyBinder.BindModelAsync(bindingContext);
  73. if (bindingContext.Result.IsModelSet)
  74. {
  75. return;
  76. }
  77. bindingContext.ModelState.Clear();
  78. await _complexBinder.BindModelAsync(bindingContext);
  79. }
  80. }
  81. }