LastBye
LastBye

Reputation: 1173

String as a Model

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();
}

Upvotes: 26

Views: 39166

Answers (4)

Big Square
Big Square

Reputation: 85

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).

Upvotes: 1

Pete
Pete

Reputation: 3872

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);
}

Upvotes: 65

Andras Zoltan
Andras Zoltan

Reputation: 42363

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.

Upvotes: 12

Ant P
Ant P

Reputation: 25231

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()

Upvotes: 10

Related Questions