在Web API C#中映射可选参数

时间:2017-09-26 16:46:44

标签: c# asp.net-web-api

我正在使用Postman拨打Get电话。在URL我有可选参数,其中包含underscore。我想使用class将这些值分配给DataContract,但我无法做到。如果我单独阅读它们就没有问题了。

这对我来说是新的,所以探索最好的方法是什么。找到一些链接,其中建议是针对单个参数,但希望确保我在这里没有遗漏任何内容。

致电:http://{{url}}/Host?host_name=Test&host_zipcode=123&host_id=123

工作:如果我将它们作为单个参数读取,我可以读取这些参数值。

[HttpGet]
[Route("api/Host")]
public async Task<HostResponse> GetHostInfo([FromUri (Name = "host_name")] string hostName, [FromUri (Name = "host_zipcode")] string hostZipCode, [FromUri(Name = "host_id")] string hostId)
{
}

不工作:当我尝试使用class DataContract时,我无法阅读。

[HttpGet]
[Route("api/Host")]
public async Task<HostResponse> GetHostInfo([FromUri] HostInfo hostInfo)
{
}

[DataContract]
public class HostInfo
{
    [DataMember(Name = "host_name")]
    public string HostName { get; set; }

    [DataMember(Name = "host_zipcode")]
    public string HostZipCode { get; set; }

    [DataMember(Name = "host_id")]
    public string HostId { get; set; }
}

我也尝试过:

public class DeliveryManagerStatus
{
    [JsonProperty(PropertyName = "country")]
    public string Country { get; set; }

    [JsonProperty(PropertyName = "delivery_provider")]
    public string DeliveryProvider { get; set; }

    [JsonProperty(PropertyName = "job_id")]
    public string JobId { get; set; }
}

如何将这些属性分配给类?

2 个答案:

答案 0 :(得分:1)

您可以使用IModelBinderdetails)实现来解析它。这是一个基于DataMember的示例(从DataMember属性获取键名):

public class DataMemberBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var props = bindingContext.ModelType.GetProperties();
        var result = Activator.CreateInstance(bindingContext.ModelType);
        foreach (var property in props)
        {
            try
            {
                var attributes = property.GetCustomAttributes(typeof(DataMemberAttribute), true);
                var key = attributes.Length > 0
                    ? ((DataMemberAttribute)attributes[0]).Name
                    : property.Name;
                if (bindingContext.ValueProvider.ContainsPrefix(key))
                {
                    var value = bindingContext.ValueProvider.GetValue(key).ConvertTo(property.PropertyType);
                    property.SetValue(result, value);
                }
            }
            catch
            {
                // log that property can't be set or throw an exception
            }
        }
        bindingContext.Model = result;
        return true;
    }
}

和用法

public async Task<HostResponse> GetHostInfo([FromUri(BinderType = typeof(DataMemberBinder))] HostInfo hostInfo)

在快速搜索中,如果你找到它,我无法找到任何基于AttributeBased的粘合剂尝试和分享

答案 1 :(得分:0)

使用您的HostInfo类将您的呼叫更改为:

gunicorn --bind 0.0.0.0:8000 myprojectname.wsgi

由于查询字符串长度的限制,如果可能,我建议您更改路由以接受正文中的复杂类型。