1
\$\begingroup\$

I have two ViewModels with the one referencing the other:

public class GiveViewModel
{
    [Required]
    public int GivenLifelines { get; set; }
    public string ToUser { get; set; }
    public string FromUser { get; set; }
}

 public class UserDetailsViewModel
{
    public GameDetail gameDetail { get; set; }
    public UserDetail userDetail { get; set; }
    public IEnumerable<GameItem> gameItems { get; set; }
    public IEnumerable<UserDetail> allUsers { get; set; }
    //REF
    public GiveViewModel givenLifeLines { get; set; }
}

The main viewmodel is used in the controller to get all the info on the foreign keys for the page. I have IEnumerables to list all users and game items, and references to the main models to get the current users details. This enables users to give points to other users while on their details page (the DetailsController).

Technically I do not use the givenLifeLines on the first load for the view. It is only used during the POST.

I can get the values back from the POST and use it on the [HttpPost] controller but it seems a bit awkward.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Give(UserDetailsViewModel model)
{
   int givenLifeLines = model.givenLifeLines.GivenLifelines; //got value
   string givenTo = model.givenLifeLines.ToUser; // got value
   ....
}

You see, the current logged in user selects another user based on their image by clicking the selected image:

<img src="~/@item.AppImage.ImagePath" class="img-responsive img-thumbnail user-image" data-username="@item.FirstName" style="width:100px;height:100px;" />

which gets added to a model textbox:

 @Html.TextBoxFor(model => model.givenLifeLines.ToUser, new { @class = "give-to form-control" })

That process is controlled by jQuery:

  $(".user-image").click(function () {
      $(".give-to").val($($(this)).attr('data-username'));
   })

This all works fine. I am getting the values I need in the model for the POST, but I get the feeling that this is not a good idea. Ideally I would want the textbox to be disabled, however, if I do that, the value is then not passed to POST controller model. A dirty work around would be to just display:none on the textbox and still have it enabled but that would feel wrong. I don't feel like I should be required to depend on jQuery like this.

Is there a better way to approach this that is more inline with the practices of model binding? Should I be separating my ViewModels like I have?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Have you tried making the textbox a HiddenFor() \$\endgroup\$
    – dreza
    Commented Sep 11, 2014 at 9:49
  • \$\begingroup\$ I am using HiddenFor() for the userId. I guess i could add more. I would really like to have HiddenFor(m => m.gameDetails) So that i can get everything from that model \$\endgroup\$
    – user26985
    Commented Sep 11, 2014 at 11:36
  • \$\begingroup\$ I find that if i use a hiddenfor(m => m.userDetails.userDetailsId) then i can just use linq to get everything in the controller. Which i think might be a better way to go about this \$\endgroup\$
    – user26985
    Commented Sep 11, 2014 at 11:55
  • 1
    \$\begingroup\$ yes, I would only post what you need to and let the controller re-fetch the data. That is definitely the approach I would take. \$\endgroup\$
    – dreza
    Commented Sep 11, 2014 at 19:41

1 Answer 1

2
\$\begingroup\$

First I would fix the variable naming to have a consistent naming structure. In the first class you have variables starting with capital letters (I agree) but in the second they start with lowercase.

I would suggest only passing in what you need for the view and leaving the rest out.

Can you show us your view? I see you have two IEnumerables that look like they are passing domain data to the view. How are you displaying them?

Is GivenLifeLines a Foreign Key or a count? Hard to tell.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.