Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Value cannot be null or empty. Parameter name: contentPath" on a most unexpected line on postback when ModelState has errors

It's been two hours straight I have been haggling with this monstrosity.

I get this error:

Value cannot be null or empty. Parameter name: contentPath

On this line in my view:

@Html.ValidationMessageFor(model => model.IssueName, 
  "", new { @class = "text-danger" })

The stack trace given below seems to suggest that a call to Url.Content has been made, but I have made no such call. Below is the stack trace and that is followed by some more lines of code around the line which causes the error:

[ArgumentException: Value cannot be null or empty. Parameter name: contentPath] System.Web.Mvc.UrlHelper.GenerateContentUrl(String contentPath, HttpContextBase httpContext) +125
System.Web.Mvc.UrlHelper.Content(String contentPath) +26
ASP._Page_Views_Journal_EditIssue_cshtml.Execute() in MyProject\Views\Journal\EditIssue.cshtml:45
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +197
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105
System.Web.WebPages.StartPage.RunPage() +17
System.Web.WebPages.StartPage.ExecutePageHierarchy() +64
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +78
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +256
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +291 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList
1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList1 filters, ActionResult actionResult) +52
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +173 System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult
1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
System.Web.Mvc.Async.WrappedAsyncVoid
1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
System.Web.Mvc.Async.WrappedAsyncVoid
1.CallEndDelegate(IAsyncResult asyncResult) +22
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid
1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9644097 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

The lines of code around the line that throws the exception are:

<div class="form-group">
    @Html.LabelFor(model => model.IssueName, htmlAttributes: new { @class = "control-label col-md-2"})
    <div class="col-md-10">
        @Html.EditorFor(model => model.IssueName, new { htmlAttributes = new { @class = "form-control", id = "IssueName" } })
        @Html.ValidationMessageFor(model => model.IssueName, "", new { @class = "text-danger" })
    </div>
</div>

IMPORTANT

Strangely, the exception is raised only when I come back from a post-back and never when I first load the view, and not even when the ModelState has no errors. It only is raised when the ModelState has errors after a post-back.

Here is some server side code, though I don't see any reason why it might be doing something wrong:

[HttpPost]
public async Task<ActionResult> EditIssue(EditIssueViewModel viewModel)
{
    viewModel.AvailableTags = BusinessManager.GetAllTags();

    if (viewModel.IssuePDFFile == null || viewModel.IssuePDFFile.ContentLength == 0)
    {
        ModelState.AddModelError("", "Please select a file to upload.");
        return View(viewModel);
    }

    var fileInfo = new FileInfo(viewModel.IssuePDFFile.FileName);
    if (!StaticData.AcceptedContentTypes.Contains(viewModel.IssuePDFFile.ContentType, StringComparer.InvariantCultureIgnoreCase) ||
        !fileInfo.Extension.Equals(".pdf", StringComparison.InvariantCultureIgnoreCase))
    {
        ModelState.AddModelError("", "You can only select a PDF file.");
        return View(viewModel);
    }

    if (!ModelState.IsValid)
    {
        var errors = ModelState.Values.SelectMany(v => v.Errors)
            .Select(e => new { e.ErrorMessage, e.Exception });

        var errorList = errors.ToList();

        errorList.ForEach(e => Debug.Print(e.ErrorMessage));
        errorList.ForEach(e => ModelState.AddModelError("", e.ErrorMessage));

        return View(viewModel);
    }

    var operationResult = await BusinessManager.EditIssueAsync(viewModel);

    if (!operationResult.Succeeded)
    {
        ModelState.AddModelError("", operationResult.FailureMessage);
        return View(viewModel);
    }

    viewModel = (EditIssueViewModel)BusinessManager.GetIssueWithRelationships(viewModel.IssueId);
    viewModel.SuccessMessage = operationResult.SuccessMessage;
    return View(viewModel);
}
like image 398
Water Cooler v2 Avatar asked Jul 06 '16 18:07

Water Cooler v2


1 Answers

Holy crap!

If you ever, ever, ever get this error, please remember, there is but one, and only one, cause for this error.

Somewhere in the network of lines on your view, you have passed a null value to the @Url.Content method. Period.

The line it reports an exception at may have nothing to do with the exception and may be a mile or two away from the culprit.

Search, search, search like crazy. :-)

That's how I found the solution to this and relief from my misery.

like image 180
Water Cooler v2 Avatar answered Nov 16 '22 23:11

Water Cooler v2