MVC Model Mapping

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
12 năm cách đây
Howdy all

I would like to use automapping function. To map the category model to the product model. The reason for this is on the category template drop down list I need to add a QTY box and Just have one single add to cart button at. Whilst also displaying various data information in the list box held in the dbo.product.

I have created a new div clas product block with a header table
<div class="product-block"><table style> etc
in the

CategoryTemplateInProductGridOrList and can see that it calls on ProductBox.CSHTML

@foreach (var product in Model.Products)
            {
                <div class="item-box">
                    @Html.Partial("_ProductBox", product)
                </div>
            }


I have been thinking that there are two options to my approach the first that I'm currently working on is adapting the product box to contain my information but I'm have aliment issues in the CSS. Or auto map the category model to the product model. So I can build on file instead of the two.

I'm just wondering how I would go about mapping and what code is necessary and where to place it.

All help as we know would be highly regarded

Kind Regards

Richard....
12 năm cách đây
Not sure I completely understand your scenario but to use automapper you need to perform 2 steps.

1. Administration.Infrastructure.AutoMapperStartupTask.cs you need to map your entities properties using the format in that file.  It's pretty self-explanatory.

2. In Administration.MappingExtensions.cs you need to setup the appropriate extension methods.  Again, the examples are pretty straight forward.

Restart your app and that's it!

On a side note, automapper is a pretty neat tool but I am starting to remove it's usage from all my projects.  It's just safer to map your two entities yourself because you KNOW exactly what is going on.  The performance benefits are also much much better.

Good luck.
12 năm cách đây
Hi

Thank you for the reply!

It's just safer to map your two entities yourself because you KNOW exactly what is going on.  The performance benefits are also much much better.

I want to map the Category model/views to the product model/view so I can a display a table list in the CategoryTemplateGridorlist page. So when customer navigates through our categories and ends up on the fianl sibbling category there is a table list that displays the products and holds data in the dbo.product table.

So for example in the CategoryTemplateGridorlist.cshtml in the code

@foreach (var product in Model.Products)
            {
                <div class="item-box">
                    @Html.Partial("_ProductBox", product)
                </div>
            }


it calls on the productbox but I was thinking that I could take it completely out of the equation and just add the product list table with a qty option and add to cart button in that page then have a pop up that displays the the overall product page.

I hope this makes more sense

I'm working on various solution to work around this problem and using the mapping technique, I thought could be one. Which I have never used.

All help highly regarded

Richard
12 năm cách đây
I'm still a little confused because what you are describing is already in the box.

So when customer navigates through our categories and ends up on the fianl sibbling category there is a table list that displays the products and holds data in the dbo.product table.

If you navigate to http://demo.nopcommerce.com/c/4/notebooks, 'notebooks' is the last sibling and there is a table of products on that page.

The only other thing I can think of that you are trying to do is place the products into a table as a list with no images???
12 năm cách đây
Maybe I'm slightly confused there is alot going on. To explain further in the list view I know there a table view but I'm trying to redesign the whole page. Here is an example of the code.

    @*product list*@
    @if (Model.Products.Count > 0)
    {
       @*list mode*@
            <div class="product-list">
             <div class="Product">
              Product List
             </div>
              <br />
            <div class="product-block">
              <table style="width: 100%;"border="solid #ffc600">
                 <thead>
                 <tr>
                 <th>&nbsp;</th>
                 <th>Code</th>
                 <th>Description</th>
                 <th>Size</th>
                 <th>PackSize</th>
                 <th>QTYINSTOCK>
                 <th>Price</th>
                 <th>RRP</th>
                 <th>QTY</th>
              </tr>
              </thead>
             <tbody>

              @foreach(var product in Model)
               {
               <tr>
                 <td class="picture">
                 <a href="@Url.RouteUrl("Product", new { productId = Model.Id, SeName = Model.SeName })" title="@Model.DefaultPictureModel.Title">
                 <img style="border-width: 0px;" alt="@Model.DefaultPictureModel.AlternateText" src="@Model.DefaultPictureModel.ImageUrl" title="@Model.DefaultPictureModel.Title" />
                 </a></td>
                 <td>@product.Code</td>
                 <td>@product.Description</td>
                 <td>@product.Size</td>
                 <td>@product.PackSize</td>
                 <td>@QTYINSTOCK</td>
                 <td>@product.Price</td>
                 <td>@product.RRP</td>
                 <td></td>
              </tr>
            }
            </tbody>  
           </table>


So with this display it takes out the display and add to cart buttons and displays more Wholesale Information. What we would like as a company is to have this list view a QTY input button on each product and then have one button to add to the cart. The main information will be displayed via a Pop up window when the consumer clicks on the image.

This is my I'm trying to map the CategoryModel to the Product and ProductVariant Models.

I hope this explains a bit better.

All help highly regarded.

Richard
12 năm cách đây
Ok. I think I understand what you are trying to accomplish. I think....

It looks like you want to map category and product properties to some sort of custom view.  This is where View Models come into play and what makes MVC3 a great platform.  You can Google 'MVC3 View Models' for a more detailed explanation.  Here is short example of what you can do with them.

The thing to remember with view View Models is that they are decoupled from your actual entities.  This means you can put whatever you need in them and map the properties back to your entities however you want.  For instance.

public class MyCustomViewModel
        {
            public int Id { get; set; }
            public string ProductName { get; set; }
            public string ProductSku { get; set; }

            public int CategoryId { get; set; }
            public string CategoryName { get; set; }

            //etc.
        }


Then from your controller:

public ActionResult MyAction()
{
  var products = _productService.GetAllProducts();
  var categories = _categoryService.GetAllCategories();
  var model = new IList<MyCustomViewModel>();
  foreach(var p in products)
  {
     //note: categories may be lazy loaded from product
     var modelItem = p.ToMyCustomViewModel(categories.FirstOrDefault(x => x.Id == p.CategoryId))
     model.Add(modelItem);
   }
  
   return View(model);
}

  

Finally, setup your own mapping extension:

public static MyCustomViewModel ToMyCustomViewModel(this Product entity, Category category)
{
  if(entity == null)
     return null;

    var model = new MyCustomViewModel
       {
          Id = entity.Id,
          ProductName = entity.ProductName,
          CategoryName = category.Name
          //etc.
       };

    return model;
}


This is how any custom views would be done.  If you wanted your popup to be modal and client side, just create a JsonViewModel and return a JsonResult.  The possibilities are limitless.

Hope this helps.
12 năm cách đây
Hi Joe

I took on bored what you wrote thank you

I need to change the loop in the Categories.ViewMode.List, I have created a new View that that contains a specific structured table with a Table Header and body.

On Navigating through the Product List I have become aware that there is a loop and my header appears above every single product where as I just need it to appear once.

I tested putting it into the

CategoryTemplate.ProductsInGridOrLines.cshtml

but Id prefer to have it as a seperate view and foreach the model. Would you be aware of where I would be able to remove this loop so it just becomes a basic table form displaying the product.

Richard
11 năm cách đây
Hi

Hoping you maybe able to help me with this Non Action and Public Action methods. As we know how the Categories and SubCategories map to the products in the Db.

With the sibblings we disscussed in this post im trying to pass a getchildsibblingonly method. Which does work until I pass the final category int into the product.Id. Within the partial view on the front end I can navigate to the product list but the partail category Navigation vanishes I need it to remain on the subcategory's. Logically I have highlighted the code that I think is causing the issue but I have tryed various different operator's the block still vanishes.


Non Action Method

 
[NonAction]
        private IList<CategoryNavigationModel> GetOnlySiblings(Category currentCategory)
        {
            var result = new List<CategoryNavigationModel>();
            int Id = 0;
            if (currentCategory != null)
                Id = currentCategory.Id;

                
            foreach (var category in _categoryService.GetAllCategoriesByParentCategoryId(Id))
            {
                var model = new CategoryNavigationModel()
                {
                    Id = category.Id,
                    Name = category.GetLocalized(x => x.Name),
                    SeName = category.GetSeName(),
                    IsActive = currentCategory != null && currentCategory.Id == category.ParentCategoryId,
                    NumberOfParentCategories = 0
                };
                result.Add(model);
            }
            return result;
        }


Here is the Public Action method


[ChildActionOnly]
        //[OutputCache(Duration = 120, VaryByCustom = "WorkingLanguage")]
        public ActionResult CategoryNavigation(int currentCategoryId, int currentProductId)
        {
            string cacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_NAVIGATION_MODEL_KEY, currentCategoryId, currentProductId, _workContext.WorkingLanguage.Id);
            var cacheModel = _cacheManager.Get(cacheKey, () =>
            {
                var currentCategory = _categoryService.GetCategoryById(currentCategoryId);
                if (currentCategory == null && currentProductId > 0)
                {
                    var productCategories = _categoryService.GetProductCategoriesByProductId(currentProductId);
                    if (productCategories.Count > 0)
                        currentCategory = productCategories[0].Category;
                }
                var breadCrumb = currentCategory != null ? GetCategoryBreadCrumb(currentCategory) : new List<Category>();
                var model = GetOnlySiblings(currentCategory);
                return model;
            });

            return PartialView(cacheModel);
        }


A good example would be If I changed the following

var result = new List<CategoryNavigationModel>();
            int Id = 0;
            if (currentCategory != null)
               Id = currentCategory.Id;


to

var result = new List<CategoryNavigationModel>();
            int Id = 0;
            if (currentCategory != null)
               Id = 1;


All parentcategories return to the first category which is Baby Range. So If go to another category DIY it returns all subcategories within Baby Range..

If you could help greatly appriecated...

Richard
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.