views:

30

answers:

1

Hi guys,

I have some fields in my ViewModel that I only need for the output in my View. But they are always getting send when submitting the form. That's not only annoying, but also dangerous, because I definitly don't want that databinding for these viewmodel fields.

Are there any change to define a OneWay Databinding for some of my viewmodel properties?

Thx in advance

EDIT:

The problem ist, that the Pictures and ValidSizes List is send back to the server when I click to an ActionLink.

http://localhost:52176/?PageSize=30&Index=31&Pictures=System.Collections.Generic.List%601[System.String]&Size=100&ValidSizes=System.Collections.Generic.List%601[System.Web.Mvc.SelectListItem]

public class PicturesViewModel
{
    public const int SMALL = 100;
    public const int MIDDLE = 150;
    public const int BIG = 250;

    public int PageSize { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="PicturesViewModel"/> class.
    /// </summary>
    public PicturesViewModel()
    {
        Pictures = new List<string>();
        Size = SMALL;
        Index = 1;
        PageSize = 30;
    }

    /// <summary> Gets or sets the index. </summary>
    public int Index { get; set; }

    /// <summary>
    /// Gets or sets the picture links.
    /// </summary>
    /// <value>The picture links.</value>
    public List<string> Pictures { get; private set; }

    /// <summary>
    /// Gets or sets the size.
    /// </summary>
    /// <value>The size.</value>
    public int Size { get; set; }

    private List<SelectListItem> validSizes = null;

    /// <summary>
    /// Gets the valid sizes.
    /// </summary>
    /// <value>The valid sizes.</value>
    public IEnumerable<SelectListItem> ValidSizes
    {
        get {
            if (validSizes != null)
                return validSizes;

            validSizes = new List<SelectListItem>
            {
                new SelectListItem(){Text = "Small", Value = SMALL.ToString()},
                new SelectListItem(){Text = "Middle", Value = MIDDLE.ToString()},
                new SelectListItem(){Text = "Big", Value = BIG.ToString()}
            };

            return validSizes;
        }
    }
}

EDIT2:

    <div id="pager_left"> 
        <%= Html.ActionLink("Prev", "Prev", Model)%>
    </div></td>

That's the Action Link that causes the binding.

+1  A: 
  1. Use separate ViewModel for form input
  2. Use IEnumerable instead of List
  3. Use [Bind(Exclude="Pictures, ValidSizes")] on the action input parameter
  4. Use private setters
  5. Don't create form input elements for Pictures/ValidSizes if you don't need them

and so on.

Update:

You assign different ViewModel not to a view, but to the controller action that handles link click. And from your questions it seems that what you need is not "oneway" binding, but rather avoiding extra characters in URL - because, if your ValidSizes is IEnumerable it won't be altered, and anyway in your URL its data is wrong, won't cause update - so it's already "one-way" binding.

This is what I can find for your problem: http://forums.asp.net/t/1328683.aspx

As for solution, I never use ActionLink helper myself, because it is a leaky abstraction and I don't like to fight with it. Simple html link tag is always much better.

<a href="<%= Html.BuildUrlFromExpression<>() %>" />

I actually use my own few-lines version of the BuildUrlFromExpression for this. Also see in the link above how you can pass parameters via anonymous object instead of Model (new { PageSize = Model.PageSize, index = Model.index }).

queen3
1) How can I assign different ViewModels to a view? 2.) ValidSizes already uses IEnumerable. 3.) The same result as without. 4) They are already using private setters. 5.) I did not create any form elements for it - at least not for the Pictures. The only thing I'm doing is calling a ActionLink.
BitKFu
Ah great! Especially the hint with the anonymous class helped me alot.
BitKFu