0

我已经使用反射使用动作过滤器绑定到我的模型。我遇到的问题是我无法访问子类来将值设置为属性-> FilePath(字符串)。

以下是我想要实现的目标。

1)使用动作过滤器上传图像,所以我不会在我的控制器动作中引用 HttpContext 。

2) 强制一致性,因为我使用此方法的所有模型都必须从通用基础抽象类 BaseModel<T> 继承。

3)自动将文件路径绑定到模型实体

BaseModel<T> 的泛型类型实体正在实现一个接口 (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;
    }

我知道它在动作过滤器中不是理想的模型绑定,但我已经没有将文件路径传递给模型的想法。

这似乎确实有效,我通过将 FilePath (字符串)属性放在继承自 BaseModel<T> 的模型上来完成此操作,该模型可以通过以下方式访问。由于“x”对象可作为 concreate 实例使用。

foreach (MemberInfo info in i.GetMembers())
{
   PropertyInfo baseInfo = baseType.GetProperty(info.Name);

   if (baseInfo != null)
   {
      baseInfo.SetValue(x, filePath, null);
      return;
    }
 }

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

任何帮助将不胜感激(即使这意味着重新思考)

4

2 回答 2

0

对于上传图片

当您在 index.cshtml 中单击新建时,您的 [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;
                }
}

认为这将帮助你...

于 2012-09-24T15:09:17.250 回答
0

通过http://codecallback.com/找到我正在寻找的东西

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

http://codecallback.com/forum/3/thread/4/asp-net-mvc-3-model-binding-to-sub-class-with-action-filter-using-reflection

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

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);

于 2012-09-25T10:01:47.587 回答