3

I have a model class that goes like

public class Mod
{
    public string StaticProp1 {get; set;}
    public string StaticProp2 {get; set;}

    public string EditableProp1 {get; set;}
}

I want a view in which I can edit EditableProp1 but where StaticProp1, StaticProp2 are displayed but not editable.

I created a strongly-typed view :

@model Mod

@using (Html.BeginForm()) 
{
    <p>@Model.StaticProp1</p>
    <p>@Model.StaticProp2</p>

    @Html.TextBoxFor(m => m.EditableProp1)

    <input type="submit" value="Save" />
}

In my Controller, when I deal with the action I find the EditableProp1 fine.

[HttpPost]
public ActionResult Edit(Mod model, FormCollection collection)
{
    string editableProp = model.EditableProp1; //This works fine

    string staticProp1 = model.StaticProp1; //Missing  

    return View(model);
}

This causes a problem if I post back for some reason as staticProp1 will now be null and the view won't be able to display it.

I know that I can add

@Html.HiddenFor(m => m.StaticProp1)
@Html.HiddenFor(m => m.StaticProp2)

to my view and that it will work fine, but I am wondering if there is another better way.

My values are already on the form (<p>@Model.StaticProp1</p>). Is there a way to bind the model to un-editable tags like that? Is there an HTML helper that does something like this?

By the way, if it isn't obvious, I am just starting out with MVC so if I am completely missing the point please let me know!

Hugo Migneron
  • 4,867
  • 1
  • 32
  • 52
  • If `StaticProp` comes from a database or something, you can read them in again and set the model data in the postback method – jamesSampica Oct 01 '13 at 20:10
  • 2
    Why exactly do you want to avoid the HiddenFor? This is a common use case for it. – ramsey_tm Oct 01 '13 at 20:15
  • I wanted to avoid it because there are a good few of them (my model is more complicated then what I showed here). It just felt like they cluttered the view, and since the values are already on the form I thought that maybe there was another way. Something like @Html.LiteralFor(...) – Hugo Migneron Oct 01 '13 at 20:18
  • Well you could use a @Html.TextBoxFor with a custom css class (to remove the text box decorations) and the readonly attribute so it cannot be updated or create your own helper to make that a bit cleaner. – ramsey_tm Oct 01 '13 at 20:22

2 Answers2

2

Every property of a model you want to persist has to be in the form (in an editor or hidden field). You can use, as you propose, Html.HiddenFor() for this. If you want to avoid overloading your view with hidden fields, you could store only the id of an entity in the hidden field and fetch the rest of the data based on the id in the Post action. Or use Html.TextBoxFor() with a readonly attribute, see this question for more information about it (I like the approach in the second answer as well).

Community
  • 1
  • 1
Henk Mollema
  • 44,194
  • 12
  • 93
  • 104
  • I believe the disabled attribute will cause the field not to post, which is currently his problem. The readonly attribute is the one he wants. – ramsey_tm Oct 01 '13 at 20:31
  • That makes sense, I think the `readonly` attribute is the way to go indeed. I added a related question. – Henk Mollema Oct 01 '13 at 20:35
  • 1
    Thanks, the approches work fine. I just wanted to make sure that I wasn't missing anything obvious which doesn't seem to be the case. – Hugo Migneron Oct 02 '13 at 19:02
1

I think the question relates more to model binding and how it works. If you don't want to use hidden field here (which I think fits your scenario), you can custom Model Bind by inheriting a class from:

DefaultModelBinder  
KrishnaDhungana
  • 2,604
  • 4
  • 25
  • 37