【问题标题】:how to receive Dictionary in WebAPI from javascript json如何从javascript json接收WebAPI中的字典
【发布时间】:2017-10-11 17:41:34
【问题描述】:

我在 WebAPI 中有这个控制器功能:

public class EntityController : APIController
{
       [Route("Get")]
       public HttpResponseMessage Get([FromUri]Dictionary<string, string> dic)
       { ... }
}

我的请求在 javascript 中如下所示:

{
     "key1": "val1",
     "key2": "val2",
     "key3": "val3"
},

但解析失败。有没有办法在不编写太多代码的情况下完成这项工作?谢谢

我的全部要求:

http://localhost/Exc/Get?dic={"key1":"val1"}

【问题讨论】:

  • 既然你将数据作为 JSON body 发布,不应该是[FromBody],而不是[FromUri]吗?
  • @YeldarKurmangaliyev 我正在为这个 http 请求使用 GET 方法。所以参数只能通过url发送
  • 好吧,我误会你了。然后,如果您手动请求 /your-api/?key1=val1&amp;key2=val2&amp;key3=val3,您可以检查您的 API 是否可以读取此参数。如果是,请在浏览器的“网络”选项卡中检查您的 JS 向您的 WebAPI 发送了什么请求。
  • @YeldarKurmangaliyev 您将 JSON 拆分为它的值。我想将整个 json 发送到服务器,并希望按照描述序列化为 Dictionary
  • 你的 WebApi 根是什么?

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


【解决方案1】:

请看这里...需要进行一些调整。我认为您的困难在于如何调用 URL。

Complex type is getting null in a ApiController parameter

【讨论】:

  • 那不是复杂类型。它是一个字符串字典。它对我没有帮助。
【解决方案2】:

您可以使用自定义模型绑定器:

public class DicModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType != typeof(Dictionary<string, string>))
        {
            return false;
        }

        var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (val == null)
        {
            return false;
        }

        string key = val.RawValue as string;
        if (key == null)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Wrong value type");
            return false;
        }

        string errorMessage;

        try
        {
            var jsonObj = JObject.Parse(key);
            bindingContext.Model = jsonObj.ToObject<Dictionary<string, string>>();
            return true;
        }
        catch (JsonException e)
        {
            errorMessage = e.Message;
        }

        bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Cannot convert value: " + errorMessage);
        return false;
    }
}

然后使用它:

public class EntityController : APIController
{
    [Route("Get")]
    public HttpResponseMessage Get([ModelBinder(typeof(DicModelBinder))]Dictionary<string, string> dic)
    { ... }
}

在 ModelBinder 中,我使用 Newtonsoft.Json 库来解析输入字符串,然后将其转换为 Dictionary。您可以实现不同的解析逻辑。

【讨论】:

  • 嗨。感谢您的回答。您的解决方案有效。但我想问,这是最简单的方法吗?我应该使用 ModelBinder 作为最佳实践来处理这个问题吗?将这个参数作为字符串接收,并在控制器内部将其解析为 Dictionary 不是更简单吗?
  • 您可以在控制器内部进行解析,但随后失去了重用代码的能力。 ModelBinder 是可重用的,并且将解析逻辑与控制器中的逻辑分开,这是一件好事。如果有人正在查看您的方法,则可以立即看到参数是什么,而不必关心解析等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
  • 2015-09-10
  • 1970-01-01
  • 2018-08-08
相关资源
最近更新 更多