根据属性c#

时间:2018-11-15 20:38:03

标签: c# .net-core-2.1

我正在使用客户端来调用API。在API中-我希望从请求正文中填充模型-但我希望根据单个属性的名称以不同的方式构造模型。基本上,我想使用数据模型创建类似开关/案例方案的东西,但是不确定如何实现此目的。最后一个模型包含基于我要达到的目标的伪代码(显然,通用类型无法按照我所描述的方式工作,但我认为它可以完成我的示例)。这是我的示例:

控制器:

[HttpPost("customer", Name = "Submit Customer")]
public IActionResult ActivateCustomer([FromBody]Customer customer)
{
    //Do something with the Customer object.
    return Ok();
}

客户模型:

public class Customer
 {
     public CustomerInfo customerInfo { get; set; }
     public SponserInfo sponserInfo { get; set; }
 }

CustomerInfo:

public class CustomerInfo
{
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }

    //etc.
}

SponserA:

public class SponserA
{
    public int ReferenceId { get; set; }
    public string Password { get; set; }
}

SponserB:

public class SponserB
{
    public string UserName{ get; set; }
    public string Relation { get; set; }
    public string Department { get; set; }
}

SponserInfo :(我想要的伪代码)

public class SponserInfo
{
    public string SponserName { get; set; }
    public T SponserInfo { get; set; }

    switch(this.SponserName)
    {
        case "Sponser A's Name":
            T = SponserA;
            break;
        case "Sponser B's Name":
            T = SponserB;
            break;
    }
}

3 个答案:

答案 0 :(得分:1)

怎么样呢?

public abstract class SponsorInfo
{
    public string SponserName { get; set; }

    protected SponsorInfo(string sponserName)
    {
        SponserName = sponserName;
    }
}

public class SponsorA : SponsorInfo
{
    public int ReferenceId { get; set; }
    public string Password { get; set; }

    public SponsorA(string sponserName, int referenceId, string password) 
        : base(sponserName)
    {
        ReferenceId = referenceId;
        Password = password;
    }
}

public class SponsorB : SponsorInfo
{
    public string UserName { get; set; }
    public string Relation { get; set; }
    public string Department { get; set; }

    public SponsorB(string sponsorName, string userName, string relation, string department) 
        : base(sponsorName)
    {
        UserName = userName;
        Relation = relation;
        Department = department;
    }
}

然后,不理会客户类(但要解决输入错误):

public class Customer
{
    public CustomerInfo customerInfo { get; set; }
    public SponsorInfo sponsorInfo { get; set; }
}

,然后在您的控制器中添加switch语句,并根据数据的外观构造SponsorASponsorB。这两个都是SponsorInfo,因此您可以将其作为sponsorInfo对象中的Customer附加。

答案 1 :(得分:0)

为什么不创建一个包含所有字段的名为Sponsor的模型,然后如果ReferenceId为空,您会知道它是哪种赞助商?

public class SponsorInfo 
{
    public int? ReferenceId { get; set; }
    public string Password { get; set; }
    public string UserName { get; set; }
    public string Relation { get; set; }
    public string Department { get; set; }
}

[HttpPost("customer", Name = "Submit Customer")]
public IActionResult ActivateCustomer([FromBody]Customer customer)
{
    //Do something with the Customer object.
    if (customer.sponsorInfo.ReferenceId == null || !customer.sponsorInfo.ReferenceId.HasValue)
    {
        //is SponsorB
    }
    else
    {
        //is SponsorA
    }
    return Ok();
}

答案 2 :(得分:0)

这是一种可扩展的方式。

属性将赞助者名称映射到子类,因此SponsorInfo不必知道所有子类。

它对所有赞助者类型都使用抽象基类(Sponsor)(也由@ Flydog57建议)。

分配了SponsorInfo.SponsorName时,将创建其子类的实例(因此您必须首先分配SponsorName)。

您可以根据实际从模型映射属性的方式进行调整。

using System;
using System.Linq;
using System.Reflection;


/// <summary>
/// Attribute to indicate the name mapped to a <see cref="Sponsor"/> subclass.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class SponsorAttribute : Attribute
{
    public SponsorAttribute(string name)
    {
        this.Name = name;
    }

    /// <summary>
    /// The value that <see cref="SponserInfo.SponserName"/> must match for the attribute class to be used.
    /// </summary>
    public virtual string Name { get; set; }
}

public abstract class Sponsor
{
    public int ReferenceId { get; set; }
    public string Password { get; set; }
}

[Sponsor("Sponser A's Name")]
public class SponsorA : Sponsor
{
}

[Sponsor("Sponser B's Name")]
public class SponsorB : Sponsor
{
    public string Department { get; set; }
}

// More subclasses can be added.

public class SponsorInfo
{
    /// <summary>
    /// The Sponsor name.
    /// Changing this sets <see cref="Sponsor"/> to a new instance of the corresponding class.
    /// </summary>
    public string SponsorName
    {
        get { return _sponsorName; }
        set
        {
            if (_sponsorName != value)
            {
                _sponsorName = value;

                // Find a Sponsor subclass with a SponsorAttribute.Name matching the given value:
                Type sponsorType = Assembly.GetExecutingAssembly().GetTypes()   // you might want to also scan other assemblies
                    .Where(t =>
                        t.IsSubclassOf(typeof(Sponsor))
                        && (t.GetCustomAttribute<SponsorAttribute>()?.Name?.Equals(_sponsorName) ?? false)
                    ).FirstOrDefault();   // null if none is found

                if (sponsorType == null)
                    Sponsor = null;     // no matching class
                else
                    Sponsor = (Sponsor)Activator.CreateInstance(sponsorType);  // new instance of the matching class
            }
        }
    }
    private string _sponsorName;

    public Sponsor Sponsor { get; set; }   // renamed from "SponsorInfo" because that's the name of this class
}


这是公共领域(CC0)的双重许可,也是Stack Overflow的常规许可。