0

I have a controller with two methods:

  • Index(), that loads the model with data from DB.
  • GetFile(), that returns a file for the user to download.

If GetFile() fails, I want to return to the view, with an errormessage. I am NOT sending the model from the View to the controller-method GetFile().

My problem is:

  • If I want to return to the view from GetFile(), I will have to initialize the model and call the DB for the data. In my eyes, this is a waste of resources and should be avoided.

My question: is there a way to return to the View, without initializing the model again (call DB)

TorK
  • 567
  • 2
  • 10
  • 27

3 Answers3

4

You can specify View name in View() method:

...
if(error)
{
     return View("Error");
}
return View(model);
...

In this case you have to have Error.cshtml file in controller View folder or in Share view folder. In tahat view you don't need to define model.

You can also use TempData to send error message to controller after redirect:

...
if(error)
{
     TempData["ErrorMessage"] = "Error";
     return Redirect("Index");
}
return View(model);
...

Then in Index or Layout view:

...
<div class="error">@TempData["ErrorMessage"]</div>
...

If you want render same view but without model you have to check if model isn't null before you use model.

...
if(Model != null)
{
     //---display model
}
else
{
     <div>Error message</div>
}
...
py3r3str
  • 1,879
  • 18
  • 23
  • yes that is possible, but I want to return to the same view but adding errormessages. – TorK May 04 '15 at 08:06
  • I would like to add that you can supply the error message as the viewmodel as the second parameter like this: `return View("Error", "Something went wrong...");`. –  May 04 '15 at 08:06
  • It works. But I wanted to know if it was possible to return to the view with the model without getting the data from DB again (I hoped it was saved in memory or something). Looks like this is not possible without sending the model from the view to the cotroller – TorK May 04 '15 at 08:35
1

If I redirect to Index(), my errormessage dissapear.

That's why you should use TempData: Difference Between ViewData and TempData?

In your controller:

TempData["ImportError"] = "Some error string";
return RedirectToAction("Index");

In your Index view:

@TempData["ImportError"]
Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • 1
    I think he don't want to load Index (and call DB) when there is error – clement May 04 '15 at 08:21
  • @clement no, OP says: _"If I redirect to Index(), my errormessage dissapear. If I want to return to the view from GetFile(), I will have to initialize the model and call the DB for the data. "_ OP doesn't want to show `GetFile()` again. – CodeCaster May 04 '15 at 08:22
  • He also said __I want to return to the same view but adding errormessages.__ – clement May 04 '15 at 08:24
  • And that's when `TempData` comes in handy if you don't want to alter or wrap your model. – CodeCaster May 04 '15 at 08:24
  • if he just wants to host one errormessage it does the trick, yes, but it looks like he wants to host more than one string... __show the errormessages__ so multiple tempdata could be great, or one object as I mentionned – clement May 04 '15 at 08:25
  • From OP: Primarily, I wanted to return to the View WITHOUT retrieving data from DB again. Looks like this is not possible without sending the model from the View to the controller. – TorK May 04 '15 at 08:40
  • @TorK you can save the model in `TempData` as well. – CodeCaster May 04 '15 at 08:42
  • I have not passed the model to GetFile(). So how would I manage to save it to TempData from GetFile() (without initializing it again) – TorK May 04 '15 at 08:45
  • @TorK well then instead of telling about your code, you may want to show it in your post. – CodeCaster May 04 '15 at 08:46
  • @CodeCaster: yes and I am sorry for that. I have edited my question. – TorK May 04 '15 at 08:51
0

The cleanest solution for me is to create your custom object that host all errors. With that object returned to the View, you can display as you want errors by using List and/or one errormessage (a understandable text for end-users for instance). This is a Container that has multiple fields that you can maybe edit to fill your needs:

public class Container<T>
    {
        private List<Error> _errors;
        private string _errorMessage;
        private bool _hasErrors;
        public T Value { get; set; }

        public bool HasErrors
        {
            get
            {
                if (!_hasErrors && !string.IsNullOrEmpty(this.ErrorMessage))
                {
                    _hasErrors = true;
                }
                return _hasErrors;
            }
            set
            {
                _hasErrors = value;
            }
        }

With that, in the view, you just check if your Model.hasError, otherwise you can use the Model.Value.

T could be string, custom object, or collection list of whatever you want... so you could use it on the whole project

clement
  • 4,204
  • 10
  • 65
  • 133
  • _"The cleanest solution"_ - no, you're just rebuilding the `ModelState`. Explain why this is a good solution and what it adds over existing mechanisms for error handling and display. – CodeCaster May 04 '15 at 08:21