26

I thought this should have been an easier task :

Edit:

It seems till this day Asp.Net MVC couldn't provide a neat solution on this case:

If you want to pass a simple string as a model and you don't have to define more classes and stuff to do so... Any ideas ??

Pass simple string as a model


here I'm trying to have a simple string model.

I'm getting this error :

"Value cannot be null or empty" / "Parameter name: name" 

The View :

@model string
@using (Html.BeginForm())
{ 
        <span>Please Enter the code</span> 
        @Html.TextBoxFor(m => m) // Error Happens here
        <button id="btnSubmit" title="Submit"></button>
}

The Controller :

public string CodeText { get; set; }

public HomeController()
{
    CodeText = "Please Enter MHM";
}

[HttpGet]
public ActionResult Index()
{
    return View("Index", null, CodeText);
}

[HttpPost]
public ActionResult Index(string code)
{
    bool result = false;
    if (code == "MHM")
        result = true;

    return View();
}
LastBye
  • 1,143
  • 4
  • 19
  • 37
  • Have you tried initializing CodeText before returning the View in the Index action? `CodeText = ""; return View(Codetext);` – dlebech May 31 '13 at 08:08
  • @dlebech I did that in the constructor – LastBye May 31 '13 at 08:10
  • Did you already try `@Html.TextBox("code", Model)`? I'm actually not sure if you even need to specify a name for the model binding to work in the post. – rliu May 31 '13 at 08:41
  • @roliu the result: "The view 'Index' or its master was not found" – LastBye May 31 '13 at 08:45
  • possible duplicate of [EditorFor(..) throws an exception when my model is null in my ASP.NET MVC application](http://stackoverflow.com/questions/7279972/editorfor-throws-an-exception-when-my-model-is-null-in-my-asp-net-mvc-applic) – Samuel Caillerie May 31 '13 at 08:47
  • I'll watch this question/thread to see if there be any exact solution which you don't have to define a class for passing a simple string, if there weren't any other suggestions, will go for the only one alternative I've found earlier and @Ant P also mentioned below. – LastBye May 31 '13 at 09:03
  • @LastBye That error message usually means you don't even have a file called `Index.cshtml` in a location that ASP.NET searches for. What? If the issue was with the `TextBox` then you would usually get a very different error message... – rliu May 31 '13 at 16:51
  • @roliu I know that, can't remember what I did but anyway went trough the wrapper approach cause A.MVC still doesn't provide a better option yet for strings. – LastBye May 31 '13 at 19:32
  • @LastBye Ah, the answer below seems to hint to why it happened (because of the overloading issue). I think ultimately it doesn't make huge sense to have a string as your backing model. In this case I would say a `ViewBag` property makes more sense. The benefit of a model is that it's easy to refactor views since everything is typed. But if it's just a string... what's the point? – rliu May 31 '13 at 20:34
  • @roliu not sure on what I'm going to do, this is a kind of training there is a security key which I stored in the server and I'm checking an input result with the key. Do you think using ViewBag is better here? – LastBye Jun 01 '13 at 10:08
  • @LastBye You just want to have a textbox where they type in a key? If the only reason you were even passing a string from the server to the browser is to prepopulate the textbox with a string then you can just use this overload: http://msdn.microsoft.com/en-us/library/dd492984(v=vs.108).aspx. You can choose to just hardcode a value, or you can pass it via the `ViewBag` or `ViewData` (for instance, if you wanted to localize it). I personally don't know the best practice, but it doesn't sound like it really matters how you do it? Maybe you should ask a new question with more context – rliu Jun 01 '13 at 10:50
  • @roliu thanks for the info and your help friend, sorry for the late reply, I did the job with all the possible forms. – LastBye Jun 09 '13 at 09:29

4 Answers4

64

There's a much cleaner way of passing a string as a model into your view. You just need to use named parameters when returning your view:

[HttpGet]
public ActionResult Index()
{
    string myStringModel = "I am passing this string as a model in the view";
    return View(model:myStringModel);
}
Pete
  • 3,842
  • 3
  • 31
  • 42
12

I know you've already accepted an answer here - I'm adding this because there's a general gotcha associated with using a string model.

String as a model type in MVC is a nightmare, because if you do this in a controller:

string myStringModel = "Hello world";
return View("action", myStringModel);

It ends up choosing the wrong overload, and passing the myStringModel as a master name to the view engine.

In general it is easier simply to wrap it in a proper model type, as the accepted answer describes, but you can also simply force the compiler to choose the correct overload of View() by casting the string to object:

return View("action", (object)myStringModel);

The other issue you're having here of using TextBoxFor having issues with an 'unnamed' model - well you shouldn't be surprised by that... The only reason to use TextBoxFor is to ensure the fields are named correctly for binding when the underlying value is a property on a model type. In this case there is no name, because you're passing it as a top-level model type for a view - so you it could be argued that you shouldn't be using TextBoxFor() in the first place.

Andras Zoltan
  • 41,961
  • 13
  • 104
  • 160
  • I did accepted that because of no other choice, knew the approach and that wasn't what I was looking for, tough you mentioned : "String as a model type in MVC is a nightmare" do you recommend 1.using casted string as an object or 2.using a wrapper viewmodel or 3. using EditorForModel or even a mixture of these ? I learned from your detailed info +1, waiting to see your next answer while reading it again... – LastBye May 31 '13 at 10:59
  • After reading your answer line-by-line cause the first time I had a glanced look over it, I can say this is totally correct, what I want to know is 1. Even when I go for these 2 approaches again do you think it could be any better to change the textboxfor to the Editor.. or not? and 2. with the shorthand of simply casting the string as object and playing with it that way, do you recommend this over the wrapper approach or the wrapper approach? thanks – LastBye May 31 '13 at 11:08
  • 1
    The forced cast to `object`, then `EditorForModel` solution would only be something I'd use in a demo or prototyping project. I might also use it in non-customer-facing parts of a website, perhaps, but eventually I'm sure it'd end up being turned into a proper model type - because then there's no compromise. So if this is a production website and it needs to be maintained in any way, I'd go for a wrapper type. – Andras Zoltan May 31 '13 at 11:09
  • Im complete new to .net and this is the answer that was working, i was trying to apply an example in codeschool, they just pass the model to string , and it was using the View(String, String) Creates a ViewResult object using the view name and master-page name that renders a view to the response. – cabaji99 Sep 17 '16 at 23:42
10

Either wrap the string in a view model object:

Model:

public class HomeViewModel
{
    public string CodeText { get; set; }
}

Controller:

private HomeViewModel _model;

public HomeController()
{
    _model = new HomeViewModel { CodeText = "My Text" };
}

[HttpGet]
public ActionResult Index()
{
    return View("Index", _model);
}

View:

@Html.TextBoxFor(m => m.CodeText);    

Or use EditorForModel:

@Html.EditorForModel()
Ant P
  • 24,820
  • 5
  • 68
  • 105
  • Not agree, What is your idea on these : http://stackoverflow.com/a/9802612/50506 , http://www.heartysoft.com/aspnet-mvc-gotcha-string-model – LastBye May 31 '13 at 08:10
  • The new version which you made a ViewModel class will work absolutely cause I did it before asking, here the question is how to simply pass a string as a model. and about the overload you said that's wrong cause if you pass to parameters it doesn't understand the 2nd parameter is a masterpage or the object as a string. – LastBye May 31 '13 at 08:13
  • 1
    @LastBye You're correct - I hadn't considered that. The rest of my answer still applies, however. – Ant P May 31 '13 at 08:14
  • As I said earlier want to know if there is a way doing this without implementing a new class, what would be your final solution? EditorForModel instead of TextBoxFor? (Why do you think it could be better here, can you provide a working snippet here based on the above code? – LastBye May 31 '13 at 08:24
1

You can simply use an overload of View() method.

View(string ViewName, object model)

in action method, call View with that signature.

return View("MyView", myString);

in view(.cshtml), define the model type as string

@model string

Then, @Model will return the string (myString).

Dharman
  • 30,962
  • 25
  • 85
  • 135
Big Square
  • 55
  • 6