【问题标题】:How to pass Javascript dictionary to controller where C# dictionary value is an object如何将 Javascript 字典传递给 C# 字典值是对象的控制器
【发布时间】:2019-12-21 06:40:04
【问题描述】:

想象一下这个 Javascript 字典:

var things = {};
things['1'] = 10;
things['2'] = 11;

这里有一点 ajax 代码:

$.ajax({
    url: '/Controller/Foo',
    type: 'POST',
    data: {
        things: things
    },

以下是可行的方法:

[HttpPost]
public IActionResult Foo(Dictionary<string, int> things)

事情会显示 1 映射到 10 和 2 映射到 11。

这里有些东西不起作用:

[HttpPost]
public IActionResult Foo(Dictionary<string, object> things)

事情会显示 1 映射到 null 和 2 映射到 null。

我无法更改字典类型。实际上,该 Dictionary 是在整个应用程序中使用的复杂对象的一部分(在 C# 方面)。你看到的是一个愚蠢的例子。

此外,JSON.stringify 根本没有帮助。事实上,如果我对字典进行字符串化,我得到的计数为 0,没有值。

使用 C# 来表达我的观点,我认为期望更多的是(而不是目前正在发生的):

int x = 5;
object foo = (object)x;

字典是这样定义的,因为可以这样做:

things[key] = 1;

things[key] = "string";

这就是它被声明为对象的原因。

如果这很重要,我正在使用 ASP.NET Core(和 jquery 3.4.1)。

谢谢。

【问题讨论】:

    标签: javascript c# jquery asp.net-mvc asp.net-core


    【解决方案1】:

    您可以自定义DictionaryModelBinder,如下所示:

     public class DictionaryModelBinder:IModelBinder
    {
        public  Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException(nameof(bindingContext));
    
            var result = new Dictionary<string, object> {};
            var form = bindingContext.HttpContext.Request.Form;
            if (form==null)
            {
                bindingContext.ModelState.AddModelError("FormData", "The data is null");
                return Task.CompletedTask;
            }
            foreach ( var k in form.Keys){
                StringValues v = string.Empty;
                var flag = form.TryGetValue(k, out v);
                if (flag)
                { 
                    result.Add(k, v );
                }
            }
    
            bindingContext.Result = ModelBindingResult.Success(result);
            return Task.CompletedTask;
        }
    }
    

    控制器:

    [HttpPost]
        public IActionResult Foo([ModelBinder(BinderType = typeof(DictionaryModelBinder))]Dictionary<string, object> things)
        {
            // the stuff you want
        }
    

    【讨论】:

      【解决方案2】:

      我不认为你可以绑定到object 作为参数(或Dictionary 值类型),因为:

      复杂类型必须具有公共默认构造函数和公共可写属性才能绑定。发生模型绑定时,将使用公共默认构造函数实例化该类。

      我认为您可以强烈键入您的 object(听起来这不是您的选择)或更改您的端点以将其所有相关属性清楚地视为简单类型(stringbool、@987654327 @等)。

      参考:Model Binding in ASP.NET Core

      【讨论】:

        猜你喜欢
        • 2010-09-29
        • 1970-01-01
        • 2011-01-01
        • 1970-01-01
        • 2016-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多