【问题标题】:Method with Dictionary Parameter in Asp.Net Web APIAsp.Net Web API 中带有字典参数的方法
【发布时间】:2012-08-14 10:26:47
【问题描述】:

我需要向包含 Dictionary 作为参数的方法发出 GET 请求。我浏览但找不到任何关于如何发送 Dictionary 的信息,因此我的请求命中了我的方法。方法签名如下

public void AddItems(Dictionary<string,object> Items)

最好的问候,

凯末尔

【问题讨论】:

  • @kkcocabiyik 您是否能够将项目作为 URL 查询参数传递到您的 GET 请求中?如果是这样,您可以发布要使用的语法示例吗?谢谢!

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


【解决方案1】:

【讨论】:

  • Asp。 Net Web Api 是 asp.net mvc 的一部分
  • @KirillBestemyanov 从营销的角度来看是的。从实现的角度来看,存在一些重叠,但是也有很多与 MVC 不同的 Web API 代码。然而,在模型绑定器的情况下,我相信代码是共享的。
  • @KirillBestemyanov 这不是真的。正如达雷尔所说,它可能会作为其中的一部分进行营销,但这远非事实。 Web API 首先是独立的。和模型绑定本身有很大不同,见:blogs.msdn.com/b/jmstall/archive/2012/04/16/…
  • 这个答案没有帮助而且很容易产生误导,因为这个问题与 Web API 有关,它与 MVC 5 的工作方式不同。
  • 你可能会添加正确答案而不是这个?这个答案是 1 年半前基于 mvc 4 和 web api 1.0 写的。
【解决方案2】:

我写了一个完全符合你要求的 ModelBinder:

public class DictionaryModelBinder : DefaultModelBinder
{
    private const string _dateTimeFormat = "dd/MM/yyyy HH:mm:ss";

    private enum StateMachine
    {
        NewSection,
        Key,
        Delimiter,
        Value,
        ValueArray
    }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var stream = controllerContext.HttpContext.Request.InputStream;
        string text;

        stream.Position = 0;
        using (var reader = new StreamReader(stream))
        {
            text = reader.ReadToEnd();
        }

        int index = 0;
        return Build(text, ref index);
    }

    private static Dictionary<string, object> Build(string text, ref int index)
    {
        var state = StateMachine.NewSection;
        var dictionary = new Dictionary<string, object>();
        var key = string.Empty;
        object value = string.Empty;

        for (; index < text.Length; ++index)
        {
            if (state == StateMachine.NewSection && text[index] == '{')
            {
                dictionary = new Dictionary<string, object>();
                state = StateMachine.NewSection;
            }
            else if (state == StateMachine.NewSection && text[index] == '"')
            {
                key = string.Empty;
                state = StateMachine.Key;
            }
            else if (state == StateMachine.Key && text[index] != '"')
            {
                key += text[index];
            }
            else if (state == StateMachine.Key && text[index] == '"')
            {
                state = StateMachine.Delimiter;
            }
            else if (state == StateMachine.Delimiter && text[index] == ':')
            {
                state = StateMachine.Value;
                value = string.Empty;
            }
            else if (state == StateMachine.Value && text[index] == '[')
            {
                state = StateMachine.ValueArray;
                value = value.ToString() + text[index];
            }
            else if (state == StateMachine.ValueArray && text[index] == ']')
            {
                state = StateMachine.Value;
                value = value.ToString() + text[index];
            }
            else if (state == StateMachine.Value && text[index] == '{')
            {
                value = Build(text, ref index);
            }
            else if (state == StateMachine.Value && text[index] == ',')
            {
                dictionary.Add(key, ConvertValue(value));
                state = StateMachine.NewSection;
            }
            else if (state == StateMachine.Value && text[index] == '}')
            {
                dictionary.Add(key, ConvertValue(value));
                return dictionary;
            }
            else if (state == StateMachine.Value || state == StateMachine.ValueArray)
            {
                value = value.ToString() + text[index];
            }
        }

        return dictionary;
    }

    private static object ConvertValue(object value)
    {
        string valueStr;
        if (value is Dictionary<string, object> || value == null || (valueStr = value.ToString()).Length == 0)
        {
            return value;
        }

        bool boolValue;
        if (bool.TryParse(valueStr, out boolValue))
        {
            return boolValue;
        }

        int intValue;
        if (int.TryParse(valueStr, out intValue))
        {
            return intValue;
        }

        double doubleValue;
        if (double.TryParse(valueStr, out doubleValue))
        {
            return doubleValue;
        }

        valueStr = valueStr.Trim('"');

        DateTime datetimeValue;
        if (DateTime.TryParseExact(valueStr, _dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out datetimeValue))
        {
            return datetimeValue;
        }

        if (valueStr.First() == '[' && valueStr.Last() == ']')
        {
            valueStr = valueStr.Trim('[', ']');
            if (valueStr.Length > 0)
            {
                if (valueStr[0] == '"')
                {
                    return valueStr
                        .Split(new[] { '"' }, StringSplitOptions.RemoveEmptyEntries)
                        .Where(x => x != ",")
                        .ToArray();
                }
                else
                {
                    return valueStr
                        .Split(',')
                        .Select(x => ConvertValue(x.Trim()))
                        .ToArray();
                }
            }
        }

        return valueStr;
    }
}

更多解释和完整帖子可以在我的博客中看到:

Json To Dictionary generic model binder

【讨论】:

    【解决方案3】:

    如果您在 webApi 控制器中接收 Dictionary 时遇到问题,相对简单的解决方案是将参数切换到 List insetead。它会自动映射。

    【讨论】:

      【解决方案4】:

      你可以这样使用字典作为参数:

      protected object DictionaryFunction()
      {
          Dictionary<int,YourObjectName> YourDictionaryObjectName=new Dictionary<int,YourObjectName>();
          ...
          ...
      
          return YourDictionaryObjectName;
      }
      
      protected MyFunction()
      {
          Dictionary<int,YourObjectName> MyDictionary=(Dictionary<int,YourObjectName>)DictionaryFunction();
      }
      

      【讨论】:

        猜你喜欢
        • 2022-01-25
        • 2012-03-29
        • 2013-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多