MVC RenderAction от View Error после ошибки модели

У меня странная проблема с RenderAction. Поскольку моя модель представления очень сложна, я постараюсь упростить процесс широкими штрихами, как показано ниже:

  1. Браузер запрашивает действие контроллера.
  2. Действие заполняет модель сложного вида и переходит к виду
  3. Представление содержит renderAction для создания дочернего / частичного представления. (В этой точке я использую renderAction вместо частичного вида из-за сложности модели, в которой нуждается частичный вид.)
  4. Это происходит по мере необходимости, и представление отображается в браузере без ошибок.
  5. Если я создаю ошибку модели после отправки неверных данных, а затем возвращаю ту же модель в то же представление, возникает ошибка при вызове renderAction. При отладке доступ к контроллеру осуществляется, но действие пропускается, и приложение переходит непосредственно к утилизации в нижней части контроллера.

Казалось бы, единственное отличие состоит в том, что основное действие контроллера (а не частичное), которое заполняет модель большого представления, сначала достигается посредством get, а затем завершается неудачей, когда достигается через сообщение. Я часами играл с моделью - даже воссоздал модель с нуля - так что это не может быть связано с моделью.

Вот трассировка стека:

    at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
   at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage)
   at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm)
   at System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm)
   at System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter)
   at System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper htmlHelper, String actionName, Object routeValues)
   at ASP._Page_Views_Pricelist__drawProductPricelistProductRow_cshtml.Execute() in c:\Users\Administrator\Documents\ProofPix_TFS\ProofPix\ProofPixAdmin\Views\Pricelist\_drawProductPricelistProductRow.cshtml:line 35
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
   at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
   at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
   at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
   at System.Web.Mvc.HtmlHelper.RenderPartialInternal(String partialViewName, ViewDataDictionary viewData, Object model, TextWriter writer, ViewEngineCollection viewEngineCollection)
   at System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper htmlHelper, String partialViewName, Object model)
   at ASP._Page_Views_Pricelist_edit_cshtml.Execute() in c:\Users\Administrator\Documents\ProofPix_TFS\ProofPix\ProofPixAdmin\Views\Pricelist\Edit.cshtml:line 121
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
   at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
   at System.Web.WebPages.StartPage.RunPage()
   at System.Web.WebPages.StartPage.ExecutePageHierarchy()
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
   at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
   at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
   at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)

Вот действие renderAction:

Html.RenderAction("_pricelistProductOptions", new { id = Model.Product.ProductId, ShowHtml = false });

Ваша помощь очень ценится. Кстати (вроде новичок)!

РЕДАКТИРОВАТЬ (добавлено действие)

        // POST: /Pricelist/Edit/5

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(adminEditPricelistVM adminEditPricelistVM)
    {

        if (ModelState.IsValid)
        {
            //Code removed for simplicity

            return RedirectToAction("Edit", new { id = pricelist.PricelistId });
        }

        int vendorId = (int)adminEditPricelistVM.VendorId;
        Vendor vendor = (from b in db.Vendors where b.VendorId == vendorId select b).SingleOrDefault();

        adminEditPricelistVM.ProductCategories = (from a in db.ProductCategories
                                                  from b in db.VendorProductCategory
                                                  where b.VendorId == vendorId && a.ProductCategoryId == b.ProductCategoryId
                                                  select a).OrderBy(o => o.SortOrder).ToList();

        List<Product> products = (from a in db.Products where a.DiscontinuedDate == null && a.VendorId == 1 select a).OrderBy(o => o.SortOrder).ToList();

        //repopulate ProductCategory and Vendor nav properties in the Formula items as these are no longer populated after post
        foreach(PricingFormula pf in adminEditPricelistVM.PricingFormulas){
            pf.ProductCategory = (from a in adminEditPricelistVM.ProductCategories where a.ProductCategoryId == pf.ProductCategoryId select a).SingleOrDefault();
            pf.Vendor = vendor;
        }


        adminEditPricelistVM.Pricelist.PricingFormulas = new List<PricingFormula>();
        adminEditPricelistVM.Pricelist.PricingFormulas.AddRange(adminEditPricelistVM.PricingFormulas);

        List<PricelistProduct> thisFilteredPP = (from a in adminEditPricelistVM.Pricelist.PricelistProducts where a.ProductId > 0 select a).ToList();
        List<PricelistProductOption> thisOptionsToDelete = new List<PricelistProductOption>();
        List<PricelistProductOptionsDetail> thisOptionDetailsToDelete = new List<PricelistProductOptionsDetail>();

        //filter pricelistProducts so only selected options remain in list
        foreach (PricelistProduct pp in thisFilteredPP)
        {
            pp.PricelistId = adminEditPricelistVM.Pricelist.PricelistId;
            var x = pp.ProductId;


            foreach (PricelistProductOption ppo in pp.PricelistProductOptions)
            {
                //repopulate PricelistProduct object
                ppo.PricelistProduct = pp;
                ppo.PricelistProductId = pp.PricelistProductId;

                int numPODs = (from a in ppo.PricelistProductOptionsDetails where a.ProductOptionsDetailId > 0 select a).Count();

                if (numPODs == 0)
                {
                    thisOptionsToDelete.Add(ppo);

                }
                else
                {

                    foreach (PricelistProductOptionsDetail ppod in ppo.PricelistProductOptionsDetails)
                    {
                        //repopulate  PricelistProductOption object
                        ppod.PricelistProductOption = ppo;
                        ppod.PricelistProductOptionsId = ppo.PricelistProductOptionId;

                        if (ppod.ProductOptionsDetailId == 0)
                        {
                            thisOptionDetailsToDelete.Add(ppod);
                        }
                        else //POD is selected but if it is the default option and it is the only option and it is priced at 0.00, then we will remove it to as it is the default setting.
                        {

                            if (ppod.Price == 0 && numPODs == 1)
                            {
                                ProductOptionsDetail prodOpDet = (from c in db.ProductOptionsDetails where c.ProductOptionsDetailId == ppod.ProductOptionsDetailId select c).SingleOrDefault();
                                if (prodOpDet.IsDefault == true)
                                {
                                    thisOptionsToDelete.Add(ppo);
                                }
                            }
                        }
                    }

                    foreach (PricelistProductOptionsDetail dppod in thisOptionDetailsToDelete)
                    {
                        ppo.PricelistProductOptionsDetails.Remove(dppod);
                    }
                    thisOptionDetailsToDelete.Clear();
                }
            }

            foreach (PricelistProductOption dppo in thisOptionsToDelete)
            {
                pp.PricelistProductOptions.Remove(dppo);
            }
            thisOptionsToDelete.Clear();
        }

        adminEditPricelistVM.Pricelist.PricelistProducts = new List<PricelistProduct>();
        adminEditPricelistVM.Pricelist.PricelistProducts.AddRange(thisFilteredPP);

        adminEditPricelistVM.PPPVMs =
               (from product in products
                join pricelistProduct in adminEditPricelistVM.Pricelist.PricelistProducts on product.ProductId equals pricelistProduct.ProductId into gj
                from subpricelistProduct in gj.DefaultIfEmpty()
                select new adminEditProductsPricelistProductsVM()
                {
                    CategoryId = (int)product.ProductCategoryId,
                    Product = product,
                    PricelistProduct = subpricelistProduct
                }).ToList();

        //repopulate PricelistProducts.Product and PricelistProducts.ProductCategory in Pricelist
        foreach (PricelistProduct pp in adminEditPricelistVM.Pricelist.PricelistProducts)
        {
            pp.Product = (from p in products where p.ProductId == pp.ProductId select p).SingleOrDefault();
            pp.ProductCategory = (from a in adminEditPricelistVM.ProductCategories where a.ProductCategoryId == pp.ProductCategoryId select a).SingleOrDefault();
            pp.Pricelist = adminEditPricelistVM.Pricelist;
        }

        ViewBag.PricingFormulaRoundingTypes = (from c in db.PricingFormulaRoundingTypes select c).ToList();

        var errors = ModelState.Select(x => x.Value.Errors).ToList();
        return View(adminEditPricelistVM);

    }

2 ответа

Вы используете движок Razor (файлы *.cshtml)? В этом случае вы должны использовать:

@Html.Action("actionName", "controllerName", new { id="myId" })

и, кажется, вы поместили имя представления "_pricelistProductOptions" вместо действия. Я сомневаюсь, что у вас есть: public ActionResult _pricelistProductOptions(....) право?

Этот ответ - всего лишь шаг, так как фактическая ошибка не отображается, только трассировка стека.

//repopulate PricelistProducts.Product and PricelistProducts.ProductCategory in Pricelist
foreach (PricelistProduct pp in adminEditPricelistVM.Pricelist.PricelistProducts)
{
    pp.Product = (from p in products where p.ProductId == pp.ProductId select p).SingleOrDefault();

Возможно, в вашем продукте больше товаров PricelistProductsс ProductId это не соответствует ни с одним из продуктов в вашем products список, в результате чего pp.Product устанавливается на ноль.

При рендеринге вашего действия для каждого объекта в Model.PricelistProducts с

html.RenderAction("_pricelistProductOptions", new { id = Model.Product.ProductId, ShowHtml = false });

это (вероятно) System.NullReferenceException: Object reference not set to an instance of an object. как ты не можешь позвонить Model.Product.ProductId, поскольку Model.Product нулевой.

Другие вопросы по тегам