【问题标题】:how can I make this c# method generic?我怎样才能使这个 c# 方法通用?
【发布时间】:2018-05-03 21:54:10
【问题描述】:

我有下面的类,用于验证用户是否提交了带有无效属性的 API 请求。我想让这个类通用。例如,我想将这个类与任何类型的请求对象一起使用。比如UserSearchRequest、GroupSearchRequest、XSearchRequest等。

我最初已将 DeserializeObject 的类型明确设置为 UserSearchRequest,它按预期工作,但现在我正在尝试通用化此实现。我尝试为 BindModel() 签名提供 T,但需要当前签名才能支持 IModelBinder 接口。

我目前的想法是有一个类构造函数,它接受一个 Type 参数,然后将它设置为一个成员变量,然后在 BindModel 方法中引用它。但我无法让这个工作。我在这里做错了什么?

using System;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
using Models.Requests;
using Newtonsoft.Json;

namespace MyCorp.Api
{
    public class CustomModelBinder : IModelBinder
    {
        Type _bindModelType;

        public CustomModelBinder(Type bindModelType)
        {
            _bindModelType = bindModelType;
        }

        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            var settings = new JsonSerializerSettings
            {
                MissingMemberHandling = MissingMemberHandling.Error
            };

            try
            {
                bindingContext.Model =
                    JsonConvert.DeserializeObject<_bindModelType.GetType()>(
                    actionContext.Request.Content.ReadAsStringAsync().Result,
                    settings);
            }
            catch (Exception ex)
            {
                var split = ex.Message.Split("'".ToCharArray());
                var message = "{0}.{1} is not a valid property";
                var formattedMessage = string.Format(message, split[3], split[1]);
                bindingContext.ModelState.AddModelError("extraProperty", formattedMessage);
            }
            return true;
        }
    }
}

【问题讨论】:

  • 你必须创建一个泛型方法:msdn.microsoft.com/en-us/library/… - 这样你就可以使用运行时已知的类型调用泛型方法(不要这样做_bindModelType.GetType(),只需使用_bindModelType
  • @DennisKuypers 我尝试只使用 _bindModelType 但返回编译错误:“找不到类型或命名空间名称 '_bindModelType'。”所以我尝试了 typeof(_bindModelType) 和 _bindModelType.GetType() 但这些方法都不起作用
  • 强制转换为对象?
  • 您可以使用反射获取DeserializeObject&lt;T&gt; 的方法信息,然后使用MakeGenericMethod 使用_bindModelType 使用您的类型参数创建方法 - 我会在一分钟内添加答案跨度>
  • 我刚刚看到您不需要泛型,因为您可以将类型传递给非泛型方法...JsonConvert.DeserializeObject(actionContext.Request.Content.ReadAsStringAsync().Result, _bindModelType, settings)

标签: c# asp.net generics asp.net-web-api


【解决方案1】:

在移动设备上编写,可能无法编译,但应该为您指明正确的方向。

using System;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
using Models.Requests;
using Newtonsoft.Json;

namespace MyCorp.Api
{
    public class CustomModelBinder<T> : IModelBinder
    {
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            var settings = new JsonSerializerSettings
            {
                MissingMemberHandling = MissingMemberHandling.Error
            };

            try
            {
                bindingContext.Model =
                    JsonConvert.DeserializeObject<T>(
                    actionContext.Request.Content.ReadAsStringAsync().Result,
                    settings);
            }
            catch (Exception ex)
            {
                var split = ex.Message.Split("'".ToCharArray());
                var message = "{0}.{1} is not a valid property";
                var formattedMessage = string.Format(message, split[3], split[1]);
                bindingContext.ModelState.AddModelError("extraProperty", formattedMessage);
            }
            return true;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2015-10-30
    • 1970-01-01
    • 2014-08-13
    • 2020-01-03
    • 1970-01-01
    相关资源
    最近更新 更多