3

我是 ASP.NET MVC 的新手,我被困在一个点上。我在一个机密网站上工作。我的情况是,我有很多类别,用户可以在其中发布他们的广告,并且每个广告类别都有不同的视图。我创建了一个控制器动作,例如

 public ActionResult PostAd(string CategoryName, string SubCategoryName)
 {
        if(categoryName == "Vehicle" && SubCategoryName == "Cars")
        {
             var model = new CarAdViewModel();

             // set CarAdViewModel properties...

             return View("CarAdCreateView", model);
        }
        else if(categoryName == "Vehicle" && SubCategoryName == "Bikes")
        {
            var model = new BikeAdViewModel();

             // set BikeAdViewModel properties...

             return View("BikeAdViewModel", model);
        }
        else if(categoryName == "Property" && SubCategoryName == "RentHouse")
        {
             var model = new RentHouseAdViewModel();

             // set RentHouseAdViewModel properties...

             return View("RentHouseAdViewModel", model);                 
        }
        else................... so on and so on
 }

我的问题是我有大量的类别和子类别,几乎 60 多个。如果我继续像上面那样为 60 多个类别和子类别编码,我的PostAd方法将会爆炸并变得难以管理。

请告诉我一些可以让我摆脱这个问题的最佳实践或模式。

4

4 回答 4

3

不幸的是,你正在做的一些事情是无法避免的。需要有某种形式的基于类别的模型和视图选择。

使用工厂模式。创建一个基类:

public abstract class BaseCategory
{
  public abstract string GetViewName();
  public abstract Object CreateModelFromFormData();
}

对于每个类别,创建一个派生自抽象函数的子类BaseCategory并实现抽象函数。

在您的操作中,执行以下操作:

public ActionResult PostAd(string categoryName, string subCategoryName)
{
  BaseFactory factory;
  if (categoryName == "Vehicle")
  {
    if (subCategoryName == "Cars")
    {
      factory = new CarsFactory();
    }
    else ...
  }
  else ...

  return View(factory.GetViewName(), factory.CreateModelFromFormData());
}

我对这个架构有几个原因:

  1. 我有目的地if/else用于工厂选择。将为每个操作调用创建和重新创建您的控制器。因此,预先填充列表将不断且不必要地为不会被选择的类别创建对象。一个简单的if/else会更有效率。如果你想防止if/else,你可以将你的工厂放在 a 中Dictionary并根据类别进行选择,但这将是很多不必要的构造函数操作。

  2. 我创建了CreateModelFromFormData一个函数,因为我假设您需要从发布的表单数据中复制数据。这可能需要传入数据,但我让函数无参数。

  3. 我使用基类/派生类,因为表单数据的复制可能需要从正在创建的模型和正在发布的表单数据中自定义。此外,保存到持久存储(文件或数据库)也可能是特定于类别的。

于 2013-07-19T16:26:29.750 回答
1

www.asp.net 上对我的问题的一个漂亮的解决方案,这里是链接:http ://forums.asp.net/t/1923868.aspx/1?ASP+NET+MVC+Conditional+ViewModel+Abstraction

编辑:

我的代码是:

public class AdsController : Controller
{
     private readonly IAdService _adService;
     public AdsController(IAdService adService)
     {
         _adService = adService;
     }

     public ActionResult PostAd(string Category, string SubCategory)
    {
        //Here I will call
        var strategy = GetStrategy(CategoryName, SubCategoryName);
        strategy.FillModel(_adService );
        return View(strategy.ViewName, strategy.Model);
    }
}
于 2013-07-22T05:03:01.560 回答
1

这将是一些可能的解决方案之一

public class PostAdData
{
    public string CategoryName;
    public string SubCategoryName;
    public string ViewName;
    public Type Model;
}

public class PostController : Controller
{
    private readonly List<PostAdData> _theData;

    public HomeController()
    {
        _theData = InitializeData();
    }


    public ActionResult PostAd(string categoryName, string subCategoryName)
    {
        var data = _theData.FirstOrDefault(c => c.CategoryName == categoryName && c.SubCategoryName == subCategoryName);
        if (data != null)
        {
            var model = Activator.CreateInstance(data.Model);
            return View(data.ViewName, model);
        }
        return View("Error");
    }

    [NonAction]
    public List<PostAdData> InitializeData()
    {
        var result = new List<PostAdData>
                         {
                             new PostAdData
                                 {
                                     CategoryName = "Vehicle",
                                     SubCategoryName = "Cars",
                                     ViewName = "CarAdCreateView",
                                     Model = typeof (CarAdViewModel)
                                 }
                         };
        return result;
    }
}
于 2013-07-19T16:15:37.500 回答
1

您应该使这些数据成为驱动力。您创建一个具有类别和子类别的复合主键的查找表。然后它有一个带有 View 的表。然后,您只需为每个类别/子类别/视图组合添加行。

如果您绝对不想要数据库,那么您可以使用简单的哈希集或字典。

var views = new Dictionary<Tuple<string,string>,string>();

views.Add(new Tuple<string,string>("Vehicle", "Cars"), "CarAdCreateView");

然后在您的 PostAd 中,您只需查找正确的视图。

于 2013-07-19T20:11:32.637 回答