为查询字符串属性声明不同的名称

时间:2019-04-24 07:12:39

标签: c# asp.net-mvc

是否有一种方法/内置解决方案将查询字符串属性映射到.NET属性?

对于动作和模型:

public ActionResult Index(AuthInitialRequest request)
{
    return View(request);
}

public class AuthInitialRequest
{
     [Required]
     public string FooBar { get; set; }
     ...
}

我要实现的功能类似于JsonProperty属性。它将模型属性映射到基于属性的查询属性。

public class AuthInitialRequest
{
     [Required]
     [QueryStringProperty("foo-bar")
     public string FooBar { get; set; }
     ...
}

1 个答案:

答案 0 :(得分:1)

感谢mmushtaq使我保持正轨。 BindAliasAttribute允许为我们的模型设置多个别名

public class AliasModelBinder : DefaultModelBinder
{
    protected override PropertyDescriptorCollection
      GetModelProperties(ControllerContext controllerContext,
                        ModelBindingContext bindingContext)
    {
        var toReturn = base.GetModelProperties(controllerContext, bindingContext);

        List<PropertyDescriptor> additional = new List<PropertyDescriptor>();

        //now look for any aliasable properties in here
        foreach (var p in
          this.GetTypeDescriptor(controllerContext, bindingContext)
          .GetProperties().Cast<PropertyDescriptor>())
        {
            foreach (var attr in p.Attributes.OfType<BindAliasAttribute>())
            {
                additional.Add(new AliasedPropertyDescriptor(attr.Alias, p));

                if (bindingContext.PropertyMetadata.ContainsKey(p.Name))
                    bindingContext.PropertyMetadata.Add(attr.Alias,
                          bindingContext.PropertyMetadata[p.Name]);
            }
        }

        return new PropertyDescriptorCollection
          (toReturn.Cast<PropertyDescriptor>().Concat(additional).ToArray());
    }
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class BindAliasAttribute : Attribute
{
    public BindAliasAttribute(string alias)
    {
        Alias = alias;
    }

    public string Alias { get; private set; }

    public override object TypeId
    {
        get { return Alias; }
    }
}
internal sealed class AliasedPropertyDescriptor : PropertyDescriptor
{
    public PropertyDescriptor Inner { get; private set; }
    public AliasedPropertyDescriptor(string alias, PropertyDescriptor inner)
        : base(alias, null)
    {
        Inner = inner;
    }
    public override bool CanResetValue(object component)
    {
        return Inner.CanResetValue(component);
    }
    public override Type ComponentType
    {
        get { return Inner.ComponentType; }
    }
    public override object GetValue(object component)
    {
        return Inner.GetValue(component);
    }
    public override bool IsReadOnly
    {
        get { return Inner.IsReadOnly; }
    }
    public override Type PropertyType
    {
        get { return Inner.PropertyType; }
    }
    public override void ResetValue(object component)
    {
        Inner.ResetValue(component);
    }
    public override void SetValue(object component, object value)
    {
        Inner.SetValue(component, value);
    }
    public override bool ShouldSerializeValue(object component)
    {
        return Inner.ShouldSerializeValue(component);
    }
}

这样定义的属性可以像这样使用:

[Required]
[BindAlias("original-url")]
public string Original_Url { get; set; }