【问题标题】:Dynamic Form Building and Passing Query Parameters动态表单构建和传递查询参数
【发布时间】:2012-01-19 16:10:14
【问题描述】:

我正在处理基于我数据库中的一些元数据表动态生成的表单。我创建名称为 setting_1、setting_53、setting_22 的输入标签,其中数字是元数据的主键。由于内容是动态的,我使用 FormCollection 作为 POST 请求的唯一参数。

问题 1:是否有类似 FormCollection 的类用于 GET 请求?我想直接访问查询参数。

问题 2:如果我需要传递这些查询参数,是否有一种简单/安全的方法来构建我的 URL?

我最担心的一个问题是某些设置是通过 OAuth 填充的,因此用户将被重定向到外部页面。我必须将查询字符串作为“状态”传递,一旦用户返回,我就需要恢复它。我将需要使用此状态来获取用户在表单输入过程中离开的位置。这就是为什么我需要一个非常简单的机制来传递查询参数的原因。

有没有人处理过这样的动态页面?传递这些页面是否有良好的模式和实践?

【问题讨论】:

    标签: asp.net-mvc-3 oauth query-parameters formcollection formbuilder


    【解决方案1】:

    好吧,您当然可以在控制器操作中查看Request.QueryString

    但如果是我这样做,我会改为编写自定义模型绑定器。

    这是一个示例模型绑定器。我没有测试过这个!

    public class MyModelBinder: DefaultModelBinder
    {
        private static void BindSettingProperty(
            ControllerContext controllerContext, 
            ModelBindingContext bindingContext, 
            PropertyDescriptor propertyDescriptor)
        {
            if (propertyDescriptor.PropertyType != typeof(IDictionary<string, string>))
            {
                throw new InvalidOperationException("This binder is for setting dictionaries only.");
            }
            var originalValue = propertyDescriptor.GetValue(bindingContext.Model) as IDictionary<string, string>;
            var value = originalValue ?? new Dictionary<string, string>();
            var settingKeys = controllerContext.HttpContext.Request.QueryString.AllKeys.Where(k => k.StartsWith("setting_", StringComparison.OrdinalIgnoreCase));
            foreach (var settingKey in settingKeys)
            {
                var key = settingKey.Substring(8);
                value.Add(key, bindingContext.ValueProvider.GetValue(settingKey).AttemptedValue);
            }
            if (value.Any() && (originalValue == null))
            {
                propertyDescriptor.SetValue(bindingContext.Model, value);
            }
        }
    
        protected override void BindProperty(
            ControllerContext controllerContext, 
            ModelBindingContext bindingContext, 
            PropertyDescriptor propertyDescriptor)
        {
            if (propertyDescriptor.Name.StartsWith("setting_", StringComparison.OrdinalIgnoreCase)
            {
                BindSettingProperty(controllerContext, bindingContext, propertyDescriptor);
            }
            else
            {
                base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
            }
        }
    }
    

    【讨论】:

    • 您有构建自定义模型绑定器的链接吗?这种方法是否允许我报告错误?我已经在手动构建一个对象,所以模型绑定器不应该做太多的工作。
    • 我添加了一个示例。使用风险自负!
    猜你喜欢
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多