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

アクション フィルターでの理想的なモデル バインディングではないことはわかっていますが、ファイル パスをモデルに渡すというアイデアが不足しています。

これは機能しているようで、次の方法でアクセスできる BaseModel<T> から継承するモデルに FilePath (文字列) プロパティを配置することでこれを達成しました。「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

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 に答える
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 に答える