0

I don't know how to best describe my requirement, but here goes. I'm trying to render a view from the following controller/model in a nopCommerce application:

CustomerController.cs snippet:

[NonAction]
protected CustomerNavigationModel GetCustomerNavigationModel(Customer customer)
{
   var model = new CustomerNavigationModel();
   model.HideAvatar = !_customerSettings.AllowCustomersToUploadAvatars;
   model.HideRewardPoints = !_rewardPointsSettings.Enabled;
   model.HideForumSubscriptions = !_forumSettings.ForumsEnabled || !_forumSettings.AllowCustomersToManageSubscriptions;
   model.HideReturnRequests = !_orderSettings.ReturnRequestsEnabled || _orderService.SearchReturnRequests(customer.Id, 0, null).Count == 0;
   model.HideDownloadableProducts = _customerSettings.HideDownloadableProductsTab;
   model.HideBackInStockSubscriptions = _customerSettings.HideBackInStockSubscriptionsTab;
   return model;
}

CustomerNavigationModel.cs:

public partial class CustomerNavigationModel : BaseNopModel
{
    public bool HideInfo { get; set; }
    public bool HideAddresses { get; set; }
    public bool HideOrders { get; set; }
    public bool HideBackInStockSubscriptions { get; set; }
    public bool HideReturnRequests { get; set; }
    public bool HideDownloadableProducts { get; set; }
    public bool HideRewardPoints { get; set; }
    public bool HideChangePassword { get; set; }
    public bool HideAvatar { get; set; }
    public bool HideForumSubscriptions { get; set; }

    public CustomerNavigationEnum SelectedTab { get; set; }
 }

public enum CustomerNavigationEnum
{
    Info,
    Addresses,
    Orders,
    BackInStockSubscriptions,
    ReturnRequests,
    DownloadableProducts,
    RewardPoints,
    ChangePassword,
    Avatar,
    ForumSubscriptions
}

MyAccountNavigation.cshtml snippet:

 @model CustomerNavigationModel
 @using Nop.Web.Models.Customer;
 @if (!Model.HideInfo)
 {
      <li><a href="@Url.RouteUrl("CustomerInfo")" class="@if (Model.SelectedTab == CustomerNavigationEnum.Info)
          {<text>active</text>}
          else
          {<text>inactive</text>}">@T("Account.CustomerInfo")</a></li>}

Views: @Html.Partial("MyAccountNavigation", Model.NavigationModel, new ViewDataDictionary())

I am aware that it is unable to render MyAccountNavigation because it doesn't exist in the controller. However, depending on which page the syntax is placed it works. So is there a way to achieve that without changing the code in the controller? Thanks in advance.

scoo-b
  • 1
  • 1
    Where is your partial view located? Views that work, where are they located? Views that don't work, where are they located? –  Sep 10 '12 at 09:01
  • Partial view file is ~/Views/Customer/MyAccountNavigation.cshtml, views that work are in the folder ~/Views/Customer/. If I insert "@Html.Partial("MyAccountNavigation", Model.NavigationModel, new ViewDataDictionary())" in any file in ~/Views/Shared/ it won't work. – scoo-b Sep 11 '12 at 01:30

2 Answers2

0

Whatever I understand from your question is you need to execute "MyAccountNavigation" partial view from many pages and for that you can put this partial view in Shared folder.

Please correct me if I am wrong.

Edited text

BaseController :

ExcecuteCore method

you can store your menu or that model in ViewBag like

var customerNavigationModel = assigned your value;
ViewBag.MenuData = customerNavigationModel;

From view

@{Html.RenderPartial("MyAccountNavigation", ViewBag.MenuData);}
alok_dida
  • 1,723
  • 2
  • 17
  • 36
  • I have moved MyAccountNavigation.cshtml into Shared folder and changed syntax to: @Html.Partial("MyAccountNavigation", new ViewDataDictionary(this.ViewData)), but returns the error: Object reference not set to an instance of an object. Line 18: @if (!Model.HideInfo). – scoo-b Sep 11 '12 at 04:18
  • This is error is coming due to Model is null. You need to first check Model != null and than check value of HideInfo. – alok_dida Sep 12 '12 at 09:12
  • How will I be able to view the model from "protected CustomerNavigationModel GetCustomerNavigationModel(Customer customer)"? I have tried "@Html.Partial("~/Views/Customer/MyAccountNavigation.cshtml",new Nop.Web.Models.Customer.CustomerNavigationModel())", but the properties aren't passed into the Model. I ONLY want to change the syntax in the View if that is possible. – scoo-b Sep 18 '12 at 02:08
  • @scoo-b . I can say that you want to pass CustomerNavigationModel in that partial view. For this you need to store CustomerNavigationModel in ViewBag from controller and fetch the same value from the view. Check my edited code. – alok_dida Sep 18 '12 at 04:41
0

MVC looks for the partial view in a specific order. For your partial view to work, you need to place MyAccountNavigation.cshtml' into~/Views/Shared/`

I've looked at the source and this is what happens:

 public RazorViewEngine(IViewPageActivator viewPageActivator)
            : base(viewPageActivator)
        {
            AreaViewLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };
            AreaMasterLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };
            AreaPartialViewLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.cshtml",
                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
                "~/Areas/{2}/Views/Shared/{0}.cshtml",
                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
            };

            ViewLocationFormats = new[]
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/{1}/{0}.vbhtml",
                "~/Views/Shared/{0}.cshtml",
                "~/Views/Shared/{0}.vbhtml"
            };
            MasterLocationFormats = new[]
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/{1}/{0}.vbhtml",
                "~/Views/Shared/{0}.cshtml",
                "~/Views/Shared/{0}.vbhtml"
            };
            PartialViewLocationFormats = new[]
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/{1}/{0}.vbhtml",
                "~/Views/Shared/{0}.cshtml",
                "~/Views/Shared/{0}.vbhtml"
            };

            FileExtensions = new[]
            {
                "cshtml",
                "vbhtml",
            };
        }

We are interested in AreaPartialViewLocationFormats and PartialViewLocationFormats.

This explains why your view is found when you try to use it within Customer related views, and it doesn't work anywhere else.