【问题标题】:ASP.NET MVC Action Argument Dictionary Removing Elements with @ in themASP.NET MVC 动作参数字典删除带有 @ 的元素
【发布时间】:2013-10-25 14:49:08
【问题描述】:

我有一个带有 Dictionary 参数的控制器操作:

[HttpPost]
[AllowCrossSiteJson]
public ActionResult MyActionMethod(Dictionary<string, string> EnteredValues)

当我尝试使用 JSON 调用此方法时,带有 @ 符号的字典条目会从列表中删除。例如,如果我使用这个 JSON 调用方法:

{
    "EnteredValues": {
        "__EVENTTARGET": "",
        "__EVENTARGUMENT": "",
        "__LASTFOCUS": "",
        "ctl00$txtContractQuickSearch": "Contract Search",
        "ctl00$txtAdvisorQuickSearch": "Rep Search",
        "New Business.@StartDate": "1/1/2013",
        "New Business.@EndDate": "10/25/2013",
        "New Business.@RegionCode": "All",
        "ShowChart": "on",
        "txtSearchContractNumber": "Contract Number",
        "txtSearchContractFirstName": "Owner First Name",
        "txtSearchContractLastName": "Owner Last Name",
        "DXScript": "1_42"
    }
}

这 3 个“新业务”条目被删除,因为它们有一个 @ 符号。为什么会发生这种情况,我该如何解决?

【问题讨论】:

  • 您能否在受影响的姓名前插入一个额外的@,例如"New Business.@@StartDate"?那应该从 Razor 语法中转义字符串。
  • 我没有使用 razor 渲染任何东西。

标签: c# asp.net asp.net-mvc json


【解决方案1】:

尝试用带单引号的 @ 符号来包装您的字典条目。

"'New Business.@StartDate'": "1/1/2013"

或者

"New Business.'@StartDate'": "1/1/2013"

【讨论】:

    【解决方案2】:

    在查看了 model bindersdynamic JSON objects 之后,我能够通过创建自己的 Dictionary 模型绑定器来解决这个问题:

    public class DictionaryStringModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            Dictionary<string, string> model = new Dictionary<string, string>();
            string contentType = controllerContext.RequestContext.HttpContext.Request.ContentType;
    
            if (contentType != null && contentType.Contains("application/json"))
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                controllerContext.RequestContext.HttpContext.Request.InputStream.Position = 0;
                string content = new StreamReader(controllerContext.RequestContext.HttpContext.Request.InputStream).ReadToEnd();
                var dynamicContent = Json.Decode(content);
                foreach (string property in dynamicContent.GetDynamicMemberNames())
                {
                    if (property == bindingContext.ModelName)
                    {
                        foreach (string dictionaryProperty in dynamicContent[property].GetDynamicMemberNames())
                        {
                            model.Add(dictionaryProperty, dynamicContent[property][dictionaryProperty]);
                        }
                        break;
                    }
                }
            }
            else
            {
                model = (Dictionary<string, string>)ModelBinders.Binders.DefaultBinder.BindModel(controllerContext, bindingContext);
            }
    
            return model;
        }
    }
    

    然后在 Globals.asax:Application_Start 中,我像这样绑定这个模型绑定器:

    ModelBinders.Binders[typeof(Dictionary<string, string>)] = new DictionaryStringModelBinder();
    

    我的字典现在是被反序列化的属性,即使键中有一个 @。请注意,这仅在字典位于动作参数(即不在动作参数的类中)和 JSON 的根目录中时才有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      • 2019-08-22
      • 2016-11-22
      • 2016-05-06
      • 1970-01-01
      相关资源
      最近更新 更多