70

I have a strange problem with my model passed to the View

Controller

[Authorize]
public ActionResult Sth()
{
    return View("~/Views/Sth/Sth.cshtml", "abc");
}

View

@model string

@{
    ViewBag.Title = "lorem";
    Layout = "~/Views/Shared/Default.cshtml";
}

The error message

The view '~/Views/Sth/Sth.cshtml' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Sth/Sth.cshtml
~/Views/Sth/abc.master  //string model is threated as a possible Layout's name ?
~/Views/Shared/abc.master
~/Views/Sth/abc.cshtml
~/Views/Sth/abc.vbhtml
~/Views/Shared/abc.cshtml
~/Views/Shared/abc.vbhtml

Why can't I pass a simple string as a model ?

gdoron
  • 147,333
  • 58
  • 291
  • 367
Tony
  • 12,405
  • 36
  • 126
  • 226

7 Answers7

122

Yes you can if you are using the right overload:

return View("~/Views/Sth/Sth.cshtml" /* view name*/, 
            null /* master name */,  
            "abc" /* model */);
nemesv
  • 138,284
  • 16
  • 416
  • 359
96

If you use named parameters you can skip the need to give the first parameter altogether

return View(model:"abc");

or

return View(viewName:"~/Views/Sth/Sth.cshtml", model:"abc");

will also serve the purpose.

18

You meant this View overload:

protected internal ViewResult View(string viewName, Object model)

MVC is confused by this overload:

protected internal ViewResult View(string viewName, string masterName)

Use this overload:

protected internal virtual ViewResult View(string viewName, string masterName,
                                           Object model)

This way:

return View("~/Views/Sth/Sth.cshtml", null , "abc");

By the way, you could just use this:

return View("Sth", null, "abc");

Overload resolution on MSDN

gdoron
  • 147,333
  • 58
  • 291
  • 367
  • 1
    Now I see, I was using the constuctor `string viewName, object model` – Tony Mar 21 '12 at 10:27
  • 2
    @Tony. You meant `method` not constructor I guess. And the `Overload resolution` Got the wrong method(for you...) – gdoron Mar 21 '12 at 10:29
  • Even just typecasting the string to object would probably have helped the overload resolution: `return View("Sth", (object) "abc");`, but calling the method `View(string, string, object)` is definitely clearer, in either case. – Owen Blacker May 21 '12 at 12:57
  • @OwenBlacker. I thought the same thing, but it will cause problem as the view expecting a `string` not an `object` as a model. so it will pass only stage one and then fail. – gdoron May 21 '12 at 12:59
  • 1
    @gdoron Ah, that would make sense. Using the `View(string, string, object)` overload, as you mentioned in your answer, certainly seems like The Right Answer™, any any case. – Owen Blacker May 21 '12 at 16:59
5

It also works if you pass null for the first two parameters:

return View(null, null, "abc");
Alex Dresko
  • 5,179
  • 3
  • 37
  • 57
4

It also works if you declare the string as an object:

object str = "abc";
return View(str);

Or:

return View("abc" as object);
Tim Mac
  • 1,149
  • 1
  • 8
  • 17
1

You also write like

return View(model: "msg");
Leandro Bardelli
  • 10,561
  • 15
  • 79
  • 116
Hiren Patel
  • 317
  • 4
  • 7
0

This seems so pretty obvious but maybe someone needs more clarification in the future:

If in your controller do:

  string id = "abc";
  return View(model: id);

Then in your view, you need:

@model string

In order to get the value, for e.g.:

<div>@Model</div>
Leandro Bardelli
  • 10,561
  • 15
  • 79
  • 116