0

I have a View that has some fields and I've added Model State validation in the Controller that checks if 2 specific fields are empty based on a value selected from a drop down list.

Here's my code that does the validation:

public ActionResult Create(Fund fund)
{
    if (fund.FundTypeId == 4)
    {
        if (string.IsNullOrEmpty(fund.AccountType))
        {
            ModelState.AddModelError("AccountType", "Account Type required");
        }
        if (string.IsNullOrEmpty(fund.FilePath))
        {
            ModelState.AddModelError("FilePath", "File Path required");
        }

    }
}

Here my code checks the Model State to see if it's valid. It correctly shows that the Model State is false and doesn't perform the insert and redirect. However I'm unable to return to the current View with the fund model as a parameter to properly display the error next to the field that caused the error.

if (ModelState.IsValid)
{ 
  // Perform the insert and redirect to Index page
}

// Need to have this view reflect the errors...
return View(fund); 

I get this error:

The model item passed into the dictionary is of type 'Fund', but this dictionary requires a model item of type 'System.Web.Mvc.HandleErrorInfo'.

Update:

Based on the "duplicate" of my question I'd have to be passing the wrong model from my Controller to my View and that my View must have a model of "System.Web.Mvc.HandleErrorInfo" defined which certainly is not the case.

I'm not passing a model from a View to a Partial View nor am I declaring a model in the Layout file so I can rule that out.

I can also confirm that my View and Controller are using the same model types.

@using FundOfFunds_MVC.Models
@model Bank.Sec.Framework.Fund

@{
    ViewBag.Title = "Create New FoF Fund";
    var fundTypeModel = ViewData["FundType"] as FundTypeModel;
}

Update:

What's happening is after the Model State gets errors added to it, it triggers an OnException method in the Fund Controller which then calls an OnException methods in a Base Controller that it inherits from:

public class BaseController : Controller
{
    private static readonly ILog databaseLogger = LogManager.GetLogger("DatabaseLogger");

    protected override void OnException(ExceptionContext filterContext)
    {
        GlobalContext.Properties["PageName"] = filterContext.RouteData.Values["controller"];
        GlobalContext.Properties["FunctionName"] = filterContext.RouteData.Values["action"];
        databaseLogger.Error("MVC Controller Error", filterContext.Exception);

        base.OnException(filterContext);
        filterContext.ExceptionHandled = true;
        this.View("Error").ExecuteResult(this.ControllerContext);
    }   
}

That last line where the "Error" view is being used is the culprit. This was code designed by folks that weren't very fluent in MVC so I'm trying my best to rectify this without reinventing the wheel.

Ari
  • 13
  • 5
  • Despite what you think, you do have a view which has `@model HandleErrorInfo`. That class is typically used when handling exceptions using the `[HandleError(..)]` attribute on a controller, so start by checking all your views (most likely in the `/Views/Shared` folder) for one that has that model –  Sep 10 '18 at 22:32
  • Correct. I have an "Error" view in the shared folder that has a HandleErrorInfo model. What's the next step? Do I have to do some kind of override? – Ari Sep 11 '18 at 13:38
  • You have not shown the relevant code, but somewhere that `Error.cshtml` view is being called and you passing it a model which is `Fund`. So I suggest you start by putting breakpoints in your controller and view, and stepping through it to find where the error is occurring. –  Sep 11 '18 at 23:04
  • What's happening is after the Model State gets errors added to it, it triggers an OnException method in the Fund Controller which then calls an OnException methods in a Base Controller that it inherits from. I'll add the details in my main question. – Ari Sep 12 '18 at 14:42
  • Adding errors to `ModelState` does not trigger exceptions (something else in you code is doing that), but your problem is the use of `this.View("Error").ExecuteResult(this.ControllerContext);` If you want to redirect to you error page in the `OnException`, then you can use `filterContext.Result = RedirectToAction(.....);` or `filterContext.Result = new ViewResult { ViewName = "~/Views/YourErrorView.cshtml" };` –  Sep 13 '18 at 02:28

1 Answers1

0

It seems your view is strongly-typed, and you're using a @model Fund as the model of this View.
Keep returning a fund Model as you did, but if you want to display errors in your view, you must add this line in your view :

 @Html.ValidationMessage("keyName")

Just replace keyName by the name of your key, in your case AccountType or FilePath.

AlexB
  • 7,302
  • 12
  • 56
  • 74
  • I tried that but it still didn't work. I'd essentially be doing this for each key in the view right? If so this did not work '
    @Html.EditorFor(model => model.FilePath) @Html.ValidationMessageFor(model => model.FilePath) @Html.ValidationMessage("FilePath")
    '
    – Ari Sep 07 '18 at 15:09