在MVC4中使用Web Api自定义模型绑定器的问题

时间:2013-11-08 18:55:10

标签: asp.net-mvc-4 asp.net-web-api

我正在使用Mvc4和WebApi。 我正在为webApi使用Dto对象。 我有如下的枚举。

public enum Status
{
 [FlexinumDefault]
  Unknown = -1,
  Active = 0,       
  Inactive = 100,   

}

Dto结构如下。

[DataContract]
public class abc()
{
[DataMemebr]
[Required]
int Id{get;set;}

[DataMember]
[Required]
Status status{get;set}
}

我创建了Custom Model Binder,它将验证dto对象中的enum(status)属性,如果未传递枚举值,则返回false。

如果状态枚举属性未在dto对象中传递,我们应该抛出异常

 public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext)
        {
            var input = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);


            if (input != null && !string.IsNullOrEmpty(input.AttemptedValue))
            {
                if (bindingContext.ModelType == typeof(Enum))
                {
                    //var actualValue = null;
                    var value = input.RawValue;

在api控制器中,我有像

这样的动作方法
public void Create([FromUri(BinderType = typeof(EnumCustomModelBinder))]abcdto abc)
        {

在global.asax.cs中 我设置了像

 GlobalConfiguration.Configuration.BindParameter(typeof(Enum), new EnumCustomModelBinder());

我面临的问题是custombinder

var input = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

,输入值为空。

请建议


1 个答案:

答案 0 :(得分:0)

我找到了解决方案

这很好用,但缺少模型绑定器的默认实现。

public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            var json = actionContext.Request.Content.ReadAsStringAsync().Result;
            if (!string.IsNullOrEmpty(json))
            {
                var jsonObject = (JObject) Newtonsoft.Json.JsonConvert.DeserializeObject(json);
                var jsonPropertyNames = jsonObject.Properties().Select(p => p.Name).ToList();

                var requiredProperties = bindingContext.ModelType.GetProperties().Where(p =>p.GetCustomAttributes(typeof(RequiredAttribute),
                                                                                           false).Any()).ToList();

                var missingProperties = requiredProperties.Where(bindingProperty => !jsonPropertyNames.Contains(bindingProperty.Name)).ToList();

                if (missingProperties.Count > 0)
                {

                    missingProperties.ForEach(
                        prop =>
                            {
                                if (prop.PropertyType.IsEnum)
                                    actionContext.ModelState.AddModelError(prop.Name, prop.Name + " is Required");

                            });
                }

                var nullProperties = requiredProperties.Except(missingProperties).ToList();

                if (nullProperties.Count > 0)
                {
                    nullProperties.ForEach(p =>
                        {
                            var jsonvalue = JObject.Parse(json);
                            var value = (JValue)jsonvalue[p.Name];
                            if (value.Value == null)
                            {
                                actionContext.ModelState.AddModelError(p.Name, p.Name + " is Required");
                            }

                        });
                }

            }
            // Now we can try to eval the object's properties using reflection.
            return true;
        }