Asp.net mvc 3 ASP.NET MVC 3模型通过使用反射的操作过滤器绑定到子类

Asp.net mvc 3 ASP.NET MVC 3模型通过使用反射的操作过滤器绑定到子类,asp.net-mvc-3,binding,model,filter,action,Asp.net Mvc 3,Binding,Model,Filter,Action,我已经发布了一个使用反射的动作过滤器绑定到我的模型。我遇到的问题是无法访问子类以将值设置为属性-->文件路径(字符串) 以下是我想要实现的目标 1) 使用操作过滤器上载图像,这样我就不会在控制器操作中引用HttpContext 2) 强制一致性,因为使用此方法的所有模型都必须继承自通用的基抽象类BaseModel 3) 自动将文件路径绑定到模型图元 BaseModel的泛型类型实体正在实现一个接口(IUpload),它将强制使用我希望能够设置的属性(FilePath),以进一步实现一致性和泛型

我已经发布了一个使用反射的动作过滤器绑定到我的模型。我遇到的问题是无法访问子类以将值设置为属性-->文件路径(字符串)

以下是我想要实现的目标

1) 使用操作过滤器上载图像,这样我就不会在控制器操作中引用HttpContext

2) 强制一致性,因为使用此方法的所有模型都必须继承自通用的基抽象类BaseModel

3) 自动将文件路径绑定到模型图元 BaseModel的泛型类型实体正在实现一个接口(IUpload),它将强制使用我希望能够设置的属性(FilePath),以进一步实现一致性和泛型

这是我在操作筛选器中的绑定尝试

   private void MyCustomBindVoid(ActionExecutingContext filterContext, string filePath)
    {
        foreach (object x in filterContext.ActionParameters.Values)
        {
            Type baseType = GetGenericTypeBase(x.GetType(), typeof(BaseModel<>));

            if (baseType == null)
            {
                throw new NullReferenceException("All view models must inherit from the BaseModel abstract class.");
            }

            foreach (PropertyInfo prop in baseType.GetProperties())
            {
                Type entity = Type.GetType(prop.PropertyType.AssemblyQualifiedName, true, false);

                if (entity != null)
                {
                    foreach (Type i in entity.FindInterfaces((type, criteria) => true, null))
                    {
                        if (i == typeof(IUpload))
                        {
                            foreach (MemberInfo info in i.GetMembers())
                            {
                                PropertyInfo entityInfo = entity.GetProperty(info.Name);

                                if (entityInfo != null)
                                {
                                    entityInfo.SetValue("I_CANNOT_FIGURE_HOW_TO_GET_THE_OBJECT_TO_BIND_HERE", filePath, null);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private Type GetGenericTypeBase(Type type, Type genericType)
    {
        while (type != typeof(object))
        {
            if (type.IsGenericType && type.GetGenericTypeDefinition() == genericType)
            {
                return type;
            }

            type = type.BaseType;
        }

        return null;
    }
这将再次导致在控制器操作中编写相同的代码,因为我必须手动将BaseModel上的FilePath属性设置为实体的FilePath属性

对于上传图像,我们将非常感谢您的任何帮助(即使这意味着一次彻底的反思)

当您在index.cshtml中单击Createnew时,您的[Httpget]创建操作将被调用,然后您将使用下面的代码,如下所示

@using (Html.BeginForm("Create", "Category", FormMethod.Post, new { id = "frmCategory", enctype = "multipart/form-data" }))
{
内部控制器

public ActionResult Create(CategoryModel category, HttpPostedFileBase CategoryImage)
        {

            if (ModelState.IsValid)
            {
                category.newCreateCategory(category, CategoryImage);
                return RedirectToAction("Index");
            }
            return View(category);
        }
模型中

 public void newCreateCategory(CategoryModel objModel, HttpPostedFileBase CategoryImage)
            {
                Category objcategory = new Category();
                if (CategoryImage != null && CategoryImage.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(CategoryImage.FileName);
                    var path = Path.Combine(HttpContext.Current.Server.MapPath("~/Content/CategoryImage"), fileName);
                    objcategory.CatImage = fileName;
                }
}

在我看来,这将有助于你……

找到我想要的东西

完整的解释可以在下面找到

我所需要做的就是像这样创建子类的实例

PropertyInfo entityInfo = entity.GetProperty(info.Name);
if (entityInfo != null)
{
  object y = prop.GetValue(x, null); /* THIS IS THE FIX */
  entityInfo.SetValue(y, filePath, null);
  return;
}

这样做将允许我用[UploadFileAttribute(param,param)]来修饰我的操作,并让所有的文件上传、路径生成和绑定到通用实体模型的属性得到处理,所以我所要做的就是调用MyRepository.Create(model.entity)

为什么要在动作过滤器中进行绑定,而不是在自定义模型绑定器中进行绑定?我想你可能误解了动作过滤器的用户。你真的需要使用反射吗?一定有更好的方法。在动作过滤器中绑定的原因就是这样我可以获取上传图像的名称,并将其直接绑定到模型,而不必使用动作过滤器和自定义模型绑定器来实现同样的效果。你会怎么做?在HttpContext中添加一个项目?谢谢你的回复,但这绝对不是我需要的。实际上,我所需要的是能够在模型点击控制器操作之前将自动生成的文件名绑定到模型。谢谢
PropertyInfo entityInfo = entity.GetProperty(info.Name);
if (entityInfo != null)
{
  object y = prop.GetValue(x, null); /* THIS IS THE FIX */
  entityInfo.SetValue(y, filePath, null);
  return;
}