【问题标题】:QueryString not being parsed correctlyQueryString 未正确解析
【发布时间】:2012-01-28 13:19:49
【问题描述】:

我对控制器中的一项操作有一个请求,该控制器期望枚举作为查询字符串中的键。我可以看到在 QueryString 中设置了相同的内容,但是服务器抛出了一个异常,说没有设置相同的内容并且错误:

参数字典包含不可为空类型的参数“enumVar”的空条目。

被抛出。

以下是异常详情:

异常类型:System.ArgumentException

异常消息:参数字典包含方法“System.Web.Mvc.ActionResult GetContent(Int64, NameSpace.Enums.MyEnum, System.String, Int32, Int32, Int32, Int32, Int64)' 在'NameSpace.Controllers.MyController' 中。可选参数必须是引用类型、可空类型或声明为可选参数。

参数名称:参数

请求网址:http://myawesomeurl.local/app/My/GetContent?abc=a_123&xyz=434&enumVar=EnumValue&teamId=a_123&a=0&b=1&c=3&qwerty=123&token=234234231

请求路径:app/My/GetContent

如果您需要更多信息,请告诉我。我不确定我应该如何解决这个问题。

更新: 我的枚举定义:

public enum DisplayMode
{
    EnumValue,
    EnumValue1,
    EnumValue2
}

另外我应该提到,请求只是有时而不是总是失败,这是不一致的。这是我们的异常数据库中记录的错误。

【问题讨论】:

  • 您能发布您的枚举定义以及GetContent() 的操作方法吗?
  • 我添加了一个更新。如果您仍然需要我的操作的定义,请告诉我。仅供参考,它没有丢失任何东西。
  • 请显示您的操作方法(至少参数定义)。您是说使用相同的查询字符串时有时会出错,有时不会?
  • @Jan 这是正确的!奇怪啊!如果它是一致的,那么我会发现问题或者会调试更多.. :/

标签: c# asp.net asp.net-mvc-3 exception-handling query-string


【解决方案1】:

专业提示:不要命名动作方法参数action

MVC 将实际的控制器操作方法名称放在其中,无论您在查询字符串或表单中得到什么(假设您在路由中使用{action} 段)。路由变量优先于一切,因此,如果您碰巧尝试将 Enum 与保留的参数名称绑定,那么它就不会出错

【讨论】:

  • 谢谢!!我不知道为什么模型绑定不会获取查询字符串,而这一切都是因为参数名称被称为操作。这很有效,并且节省了大量时间。
【解决方案2】:

看起来默认模型绑定器没有被编入枚举。最好的办法是继承 DefaultModelBinder 类并处理属性是枚举的情况。

public class U413ModelBinder : DefaultModelBinder 
{ 
    /// <summary> 
    /// Fix for the default model binder's failure to decode enum types when binding to JSON. 
    /// </summary> 
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, 
        PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) 
    { 
        var propertyType = propertyDescriptor.PropertyType; 
        if (propertyType.IsEnum) 
        { 
            var providerValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
            if (null != providerValue) 
            { 
                var value = providerValue.RawValue; 
                if (null != value) 
                { 
                    var valueType = value.GetType(); 
                    if (!valueType.IsEnum) 
                    { 
                        return Enum.ToObject(propertyType, value); 
                    } 
                } 
            } 
        } 
        return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder); 
    } 
} 

代码和逻辑由this question提供。

【讨论】:

  • 但与问题不同的是,我没有传递int,而是传递了一个字符串,即命名值
  • @user917670 您将不得不实现字符串的逻辑,但这是相同的想法。默认模型绑定器无法为您的 Action 方法的 Enum 参数分配字符串的值。
  • 它是否解释了它在某些情况下有效但在其他情况下无效的不稳定行为?
  • 声明It looks like the Default Model Binder is not dailed into enumeration不正确。枚举值是整数,并且 c# 没有默认的从字符串到枚举的隐式转换,因此原始问题不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多