将模型的属性别名别名为asp.net

编程入门 行业动态 更新时间:2024-10-24 06:31:05
本文介绍了将模型的属性别名别名为asp-core中的其他名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我希望为我的请求对象属性的名称加上别名,以便这些请求都可以工作并且都转到同一个控制器:

I wish to alias the name of my request object properties, so that these requests both work and both go to the same controller:

myapi/cars?colors=red&colors=blue&colors=green和myapi/cars?c=red&c=blue&c=green

对于请求对象:

public class CarRequest { Colors string[] { get; set; } }

任何人都可以使用新的ModelBinder解决此问题而不必从头开始编写ModelBindings吗?

Has anyone been able to use the new ModelBinders to solve this without having to write ModelBindings from scratch?

和也在这里

推荐答案

我编写了一个模型活页夹来做到这一点:

I wrote a model binder to do this:

这是github上的存储库.您可以将两个nuget软件包添加到代码中,以解决此问题.自述文件中的详细信息

Here's the repo on github. There are two nuget packages you can add to your code that solve this problem. Details in the readme

它基本上代替了ComplexTypeModelBinder(我很胆小,无法替换它,但是我用相同的条件将其放在前面),除了它试图使用我的新属性来扩展它正在寻找的字段

It basically takes the place of the ComplexTypeModelBinder (I'm too cowardly to replace it, but I slot it in front with identical criteria), except that it tries to use my new attribute to expand the fields it's looking for.

活页夹:

using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MYDOMAIN.Client; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; using Microsoft.Extensions.Logging; namespace MYDOMAIN.Web.AliasModelBinder { public class AliasModelBinder : ComplexTypeModelBinder { public AliasModelBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders, ILoggerFactory loggerFactory, bool allowValidatingTopLevelNodes) : base(propertyBinders, loggerFactory, allowValidatingTopLevelNodes) { } protected override Task BindProperty(ModelBindingContext bindingContext) { var containerType = bindingContext.ModelMetadata.ContainerType; if (containerType != null) { var propertyType = containerType.GetProperty(bindingContext.ModelMetadata.PropertyName); var attributes = propertyType.GetCustomAttributes(true); var aliasAttributes = attributes.OfType<BindingAliasAttribute>().ToArray(); if (aliasAttributes.Any()) { bindingContext.ValueProvider = new AliasValueProvider(bindingContext.ValueProvider, bindingContext.ModelName, aliasAttributes.Select(attr => attr.Alias)); } } return base.BindProperty(bindingContext); } } }

提供者:

using System; using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; using Microsoft.Extensions.Logging; namespace MYDOMAIN.Web.AliasModelBinder { public class AliasModelBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Metadata.IsComplexType && !context.Metadata.IsCollectionType) { var propertyBinders = new Dictionary<ModelMetadata, IModelBinder>(); foreach (var property in context.Metadata.Properties) { propertyBinders.Add(property, context.CreateBinder(property)); } return new AliasModelBinder(propertyBinders, (ILoggerFactory) context.Services.GetService(typeof(ILoggerFactory)), true); } return null; } /// <summary> /// Setup the AliasModelBinderProvider Mvc project to use BindingAlias attribute, to allow for aliasing property names in query strings /// </summary> public static void Configure(MvcOptions options) { // Place in front of ComplexTypeModelBinderProvider to replace this binder type in practice for (int i = 0; i < options.ModelBinderProviders.Count; i++) { if (options.ModelBinderProviders[i] is ComplexTypeModelBinderProvider) { options.ModelBinderProviders.Insert(i, new AliasModelBinderProvider()); return; } } options.ModelBinderProviders.Add(new AliasModelBinderProvider()); } } }

价值提供者:

using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.Primitives; namespace MYDOMAIN.Web.AliasModelBinder { public class AliasValueProvider : IValueProvider { private readonly IValueProvider _provider; private readonly string _originalName; private readonly string[] _allNamesToBind; public AliasValueProvider(IValueProvider provider, string originalName, IEnumerable<string> aliases) { _provider = provider; _originalName = originalName; _allNamesToBind = new[] {_originalName}.Concat(aliases).ToArray(); } public bool ContainsPrefix(string prefix) { if (prefix == _originalName) { return _allNamesToBind.Any(_provider.ContainsPrefix); } return _provider.ContainsPrefix(prefix); } public ValueProviderResult GetValue(string key) { if (key == _originalName) { var results = _allNamesToBind.Select(alias => _provider.GetValue(alias)).ToArray(); StringValues values = results.Aggregate(values, (current, r) => StringValues.Concat(current, r.Values)); return new ValueProviderResult(values, results.First().Culture); } return _provider.GetValue(key); } } }

以及要在客户端项目中引用的属性

And an attribute to go in / be referenced by the client project

using System; namespace MYDOMAIN.Client { [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class BindingAliasAttribute : Attribute { public string Alias { get; } public BindingAliasAttribute(string alias) { Alias = alias; } } }

在Startup.cs中配置

Configured in the Startup.cs

public void ConfigureServices(IServiceCollection services) { services ... .AddMvcOptions(options => { AliasModelBinderProvider.Configure(options); ... }) ...

用法:

public class SomeRequest { [BindingAlias("f")] public long[] SomeVeryLongNameForSomeKindOfFoo{ get; set; } }

导致请求看起来像这样:

leading to a request that looks either like this:

api/controller/action?SomeVeryLongNameForSomeKindOfFoo=1&SomeVeryLongNameForSomeKindOfFoo=2

api/controller/action?f=1&f=2

我将大部分内容放在Web项目中,并将属性放在我的客户端项目中.

I put most things in my web project, and the attribute in my client project.

更多推荐

将模型的属性别名别名为asp.net

本文发布于:2023-11-16 18:38:33,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1606810.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:别名   属性   模型   net   asp

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!