MVC4 ViewData.TemplateInfo.HtmlFieldPrefix generates an extra dot - asp.net-mvc-4

I'm trying to get name of input correct so a collection of objects on my view model can get bound.
#{ViewData.TemplateInfo.HtmlFieldPrefix = listName;}
#Html.EditorFor(m => m, "DoubleTemplate", new {
Name = listName,
Index = i,
Switcher = (YearOfProgram >= i +1)
})
As you can see here, I pass in the "listName" as the prefix for my template, the value of listName = "MyItems".
And here is my template:
#model Web.Models.ListElement
#if (ViewData["Switcher"] != null)
{
var IsVisible = (bool)ViewData["Switcher"];
var index = (int)ViewData["Index"];
var thisName = (string)ViewData["Name"] + "[" + index + "].Value";
var thisId = (string)ViewData["Name"] + "_" + index + "__Value";
if (IsVisible)
{
#*<input type="text" value="#Model.Value" name="#thisName" id ="#thisId" class="cell#(index + 1)"/>*#
#Html.TextBoxFor(m => m.Value, new { #class ="cell" + (index + 1)})
#Html.ValidationMessageFor(m => m.Value)
}
}
but I found that the generated name becomes this: MyItems.[0].Value
It has one extra dot. How can I get rid of it?
Incidentally, I tried to manually specify the name inside the template and found the name gets overridden by the Html helper.
Update
The reason why I have to manually set the HtmlFieldPrefix is the property name (MyItems which is a list of objects) will get lost when MyItems is passed from main view to the partial view. By the time, the partial view called my template and passed in one object in MyItems, the template itself has no way to figure out the name of MyItems as it has been lost since the last "pass-in".
So that's why I have to manually set the html field prefix name. And I even tried to use something similar to reflection(but not reelection, I forgot the name) to check the name of passed in object and found it returned "Model".
Update 2
I tried Stephen's approach, and cannot find the html helper PartialFor().
I even tried to use this in my main view:
Html.Partial(Model, "_MyPartialView");
In Partial View:
#model MvcApplication1.Models.MyModel
<h2>My Partial View</h2>
#Html.EditorFor(m => m.MyProperty)
Here is my templat:
#model MvcApplication1.Models.ListElement
#Html.TextBoxFor(m => m.Value)
Here is my Model:
public class MyModel
{
private List<ListElement> myProperty;
public List<ListElement> MyProperty
{
get
{
if (myProperty == null)
{
this.myProperty = new List<ListElement>() { new ListElement() { Value = 12 }, new ListElement() { Value = 13 }, new ListElement() { Value = 14 }, new ListElement() { Value = 15 }, };
}
return this.myProperty;
}
set
{
this.myProperty = value;
}
}
}
public class ListElement
{
[Range(0, 999)]
public double Value { get; set; }
}
And here is my controller:
public ActionResult MyAction()
{
return View(new MyModel());
}
It only generates raw text("12131415") for me, instead of the wanted text box filled in with 12 13 14 15.
But if I specified the template name, it then throws an exception saying:
The template view expecting ListElement, and cannot convert
List<ListElement> into ListElement.

There is no need set the HtmlFieldPrefix value. MVC will correctly name the elements if you use an EditorTemplate based on the property type (and without the template name).
Assumed models
public class ListElement
{
public string Value { get; set; }
....
}
public class MyViewModel
{
public IEnumerable<ListElement> MyItems { get; set; }
....
}
Editor template (ListElement.cshtml)
#model YourAssembly.ListElement
#Html.TextBoxFor(m => m.Value)
Main view
#model YourAssembly.MyViewModel
...
#Html.EditorFor(m => m.MyItems) // note do not specify the template name
This will render
<input type="text" name="MyItems[0].Value" ...>
<input type="text" name="MyItems[1].Value" ...>
....
If you want to do this using a partial, you just can pass the whole model to the partial
MyPartial.cshtml
#model #model YourAssembly.MyViewModel
#Html.EditorFor(m => m.MyItems)
and in the main view
#Html.Partial("MyPartial")
or create an extension method
public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> expression, string partialViewName)
{
string name = ExpressionHelper.GetExpressionText(expression);
object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
var viewData = new ViewDataDictionary(helper.ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = name }
};
return helper.Partial(partialViewName, model, viewData);
}
}
and use as
#Html.PartialFor(m => m.MyItems, "MyPartial")
and in the partial
#model IEnumerable<YourAssembly.ListElement>
#Html.EditorFor(m => m)

Call your partial this way:
#Html.Partial("_SeatTypePrices", Model.SeatTypePrices, new ViewDataDictionary
{
TemplateInfo = new TemplateInfo() {HtmlFieldPrefix = nameof(Model.SeatTypePrices)}
})
Partial view:
#model List
#Html.EditorForModel()
Editor template implementation:
#using Cinema.Web.Helpers
#model Cinema.DataAccess.SectorTypePrice
#Html.TextBoxFor(x => Model.Price)
This way your partial view will contain list of items with prefixes.
And then call EditorForModel() from your EditorTemplates folder.

I found that I can change the value of HtmlFeildPrefix in my template.
So what I did to solve my problem was just to assign the correct value to HtmlFeildPrefix in the template directly rather than in the page which calls the template.
I hope it helps.

If I want to pass the HtmlFieldPrefix I use the following construct:
<div id="_indexmeetpunttoewijzingen">
#Html.EditorFor(model => model.MyItems, new ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "MyItems"
}
})
</div>

Related

RadioButton list Binding in MVC4

I have a radiobuttonList which is binding data from Enum Class and its working correctly in the view.
But my concern is how can I set inital value of radiobutton to CROCount.ONE.I have tried to set the initial value in the following way but couldnot get the desired result.
public enum CROCount
{
ONE = 1,
TWO = 2
}
ViewModel is
public class RegistraionVM
{
....
public EnumClass.CROCount CROCount { get; set; }
}
I generated the radio button list as follows.
<div>
#foreach (var count in Enum.GetValues(typeof(SMS.Models.EnumClass.CROCount)))
{
<label style="width:75px">
#Html.RadioButtonFor(m => m.RegistrationVenue, (int)count,
new { #class = "minimal single" })
#count.ToString()
</label>
}
</div>
Binding performed in the Controller is
public ActionResult Index(int walkInnId)
{
try
{
var _studentReg = new RegistraionVM
{
CROCount=EnumClass.CROCount.ONE
};
return View(_studentReg);
}
catch (Exception ex)
{
return View("Error");
}
}
Your binding your radio button to property CROCount (not RegistrationVenue) so your code should be
#Html.RadioButtonFor(m => m.CROCount, count, new { id = "", #class = "minimal single" })
Note that the 2nd parameter is count (not (int)count) so that you generate value="ONE" and value="TWO". Note also the new { id = "", removes the id attribute which would otherwise result in duplicate id attributes which is invalid html.

MVC Ajax with Dynamic Partial View Creation

How can I create dynamic ajax.actionlinks that will call dynamic partial views.
For example:
I have a page that will generate x number of comments
Each comment can be voted up or down (individually)
The number of up votes and down votes are counted into a single integer
Each comment div will have its own ajax.actionlink
Each ajax.actionlink will pass to the controller the ID of the comment
The controller will calculate the total votes and call the partial view to display back into the div with the correct ID.
What have I done so far:
I have been able to create successful ajax.actionlink
That will call a controller and sum the votes
That will call the partial view and display the votes
What is the issue
I don't want to hard code 30-100 different ajax.actionlinks to call 30-100 hard coded partial views.
How can I accomplish this dynamically?
Existing Code:
My ajax.actionlink inside my razor view
#Html.Raw(Ajax.ActionLink("[replacetext]", "VoteUp",
new { UserPostID = #Model.Id },
new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "CountVote" }).ToHtmlString().Replace("[replacetext]",
"<img src=\"/Images/up_32x32.png\" />"))
My div inside the same razor view to display the returning results from the partial view.
<div id="CountVote" class="postvotes"></div>
My controller
public PartialViewResult VoteUp(int UserPostID)
{
try
{
UserVotes vote = new UserVotes();
vote.SubmitedVote = 1;
vote.UserId = Convert.ToInt32(Session["id"]);
vote.UserPostID = UserPostID;
ViewBag.SumVotes = postRepository.InsertUserPostVote(vote);
}
catch (Exception e)
{
xxx.xxx.xxxx().Raise(e);
}
return PartialView("_TotalVotes");
}
And finally my partial view (_TotalVotes.cshtml)
#ViewBag.SumVotes
Now my main view for Viewpost shows the comments in a loop using the viewbag.
foreach (var item in (List<UserComment>)ViewData["Comments"])
{
CommentVote = "cv" + i.ToString();
<div class="postlinewrapper">
<div class="postvotesframe">
<div class="postvotes">
#Html.Raw(Ajax.ActionLink("[replacetext]", "VoteUp",
new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "CountVote" }).ToHtmlString().Replace("[replacetext]",
"<img src=\"/Images/up_32x32.png\" />"))
</div>
<div id="#CommentVote" class="#CommentVote">0</div>
<div class="postvotes">
#Html.Raw(Ajax.ActionLink("[replacetext]", "VoteDown",
new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "CountVote" }).ToHtmlString().Replace("[replacetext]",
"<img src=\"/Images/down_32x32.png\" />"))
</div>
</div>
<div class="postleftbar">
#Html.Raw(item.Comment)
</div>
<div class="postrightbar">
<div>
<div class="post_spec">
<div class="post_spec_title">Call Sign: </div>
<div class="post_spec_detail">#item.CallSign</div>
</div>
<div class="post_spec">
<div class="post_spec_title">When: </div>
<div class="post_spec_detail">#item.CommentDate.ToString("dd/MM/yyyy")</div>
</div>
</div>
<br />
<br />
</div>
</div>
i += 1;
}
I have implemented the login to increase or decrease votes up and down:
public PartialViewResult VoteUp(int userPostId)
{
try
{
UserVotes vote = new UserVotes();
vote.SubmitedVote = 1;
vote.UserId = Convert.ToInt32(Session["id"]);
vote.UserPostID = userPostId;
ViewBag.SumVotes = postRepository.InsertUserPostVote(vote);
}
catch (Exception e)
{
xxxx.xxxx.xxxx().Raise(e);
}
return PartialView("_TotalVotes");
}
public PartialViewResult VoteDown(int userPostId)
{
try
{
UserVotes vote = new UserVotes();
vote.SubmitedVote = -1;
vote.UserId = Convert.ToInt32(Session["id"]);
vote.UserPostID = userPostId;
ViewBag.SumVotes = postRepository.InsertUserPostVote(vote);
}
catch (Exception e)
{
xxx.xxxx.xxxx().Raise(e);
}
return PartialView("_TotalVotes");
}
Now all this code works for 1 ajax call just fine, but what I need to is to display separate ajax calls for separate divs dynamically.
Try it this way.
Main view
I'm supposing you have a model with a collection property Comments of Comment items
#model MyNamespace.CommentAndOtherStuff
<ul>
#foreach(item in Model.Comments)
{
<li>
<a href="#Url.Action("VoteUp", "VoteControllerName", new { UserPostId = item.Id })"
class="vote-link"
data-id="#item.Id">#item.Votes</a><img src="vote.jpg" />
</li>
}
</ul>
And your controller just returns a class called VoteResult as JSON.
[HttpPost]
public ActionResult VoteUp(int UserPostID)
{
...
var model = new VoteResult
{
UserPostID = UserPostID,
Votes = service.tallyVote(UserPostID)
};
return Json(model);
}
Now hook all of those up with a jQuery event handler and setup an AJAX call
$(document).ready(function() {
$("a.vote-link").on("click", function(event) {
event.preventDefault();
var link = $(this); // the link instance that was clicked
var id = link.attr("data-id");
var url = link.attr("href");
$.ajax({
url: url,
type: "post"
})
.done(function(result) {
// JSON result: { UserPostID: 1, Votes: 5 }
// replace link text
link.html(result.Votes);
});
});
});
But I want a partial view html fagment.
[HttpPost]
public ActionResult VoteUp(int UserPostID)
{
...
var model = new VoteResult
{
UserPostID = UserPostID,
Votes = service.tallyVote(UserPostID)
};
return PartialView("_TotalVotes", model);
}
_TotalVotes partial
#model MyNamespace.VoteResult
#if (Model.Votes < 0)
{
<span class="unpopular">#Model.Votes</span>
}
else
{
<span class="awesome">#Model.Votes</span>
}
And adjust the AJAX callback
.done(function(result) {
link.html(result);
});
Now you could write a helper for the link fragment but it obfuscates things in my opinion (it's a judgement call). All you really need here is the class name and the data-id which your javascript will bind.
Using the Ajax helpers here seems an unnecessary overhead and I suggest you just use jquery methods to update the DOM. Your current code suggests you might be missing some logic to make a comment voting system work, including indicating what action the user may have already performed. For example (and assuming you want it to work similar to SO), if a user has previously up-voted, then clicking on the up-vote link should decrement the vote count by 1, but clicking on the down-vote link should decrement the vote count by 2 (the previous up-vote plus the new down-vote).
Refer to this fiddle for how this might be styled and behave when clicking the vote elements
Your view model for a comment might look like
public enum Vote { "None", "Up", "Down" }
public class CommentVM
{
public int ID { get; set; }
public string Text { get; set; }
public Vote CurrentVote { get; set; }
public int TotalVotes { get; set; }
}
and assuming you have a model that contains a collection of comments
public class PostVM
{
public int ID { get; set; }
public string Text { get; set; }
public IEnumerable<CommentVM> Comments { get; set; }
}
and the associated DisplayTemplate
/Views/Shared/DisplayTemplates/CommentVM.cshtml
#model CommentVM
<div class="comment" data-id="#Model.ID" data-currentvote="#Model.CurrentVote">
<div class="vote">
<div class="voteup" class="#(Model.CurrentVote == Vote.Up ? "current" : null)"></div>
<div class="votecount">#Model.TotalVotes</div>
<div class="votedown" class="#(Model.CurrentVote == Vote.Down ? "current" : null)"></div>
</div>
<div class="commenttext">#Html.DisplayFor(m => m.Text)</div>
</div>
Then in the main view
#model PostVM
.... // display some properties of Post?
#Html.DisplayFor(m => m.Comments)
<script>
var voteUpUrl = '#Url.Action("VoteUp")';
var voteDownUrl = '#Url.Action("VoteDown")';
$('.voteup').click(function() {
var container = $(this).closest('.comment');
var id = container.data('id');
var voteCount = new Number(container.find('.votecount').text());
$.post(voteUpUrl, { id: id }, function(response) {
if (!response) {
// oops, something went wrong - display error message?
return;
}
container.find('.votecount').text(response.voteCount); // update vote count
if (response.voteCount < voteCount) {
// the user previously upvoted and has now removed it
container.find('.voteup').removeClass('current');
} else if (response.voteCount == voteCount + 1) {
// the user had not previously voted on this comment
container.find('.voteup').addClass('current');
} else if (response.voteCount == voteCount + 2) {
// the user previoulsy down voted
container.find('.votedown').removeClass('current');
container.find('.voteup').addClass('current');
}
});
});
$('.votedown').click(function() {
... // similar to above (modify logic in if/elseif blocks)
});
</script>
and the controller method
public JsonResult VoteUp(int id)
{
int voteCount = // your logic to calculate the new total based on the users current vote (if any) for the comment
return Json(new { voteCount = voteCount });
}

using MVC4 Strongly typed view with Knockout

I am trying to use knockout with MVC strongly typed view. Since my model will have over 20 properties, I prefer to use strongly-typed view model to post back data by using ko.mapping.toJS and ko.Util.postJson. The Eligible field was passed back correctly, however the following code does not post back the selected option from drop down list, it just showed value as 0 when I looked that selectOptionModel on the controller. Can someone point out what I did wrong?
the view model from server side is as follows:
public class SelectOptionModel
{
public bool Eligible { get; set; }
public int selectedOption { get; set; }
public IEnumerable<SelectListItem> AvailableOptions
{
get
{
return Enum.GetValues(typeof(OptionEnum)).Cast<OptionEnum>()
.Select(x => new SelectListItem
{
Text = x.ToString(),
Value = x.ToString()
});
}
}
}
public enum OptionEnum
{
[Description("First")]
FirstOption = 1,
[Description("Second")]
SecondOption = 2,
[Description("Third")]
ThirdOption = 3
}
The razor view is like following:
#model TestKo.Models.SelectOptionModel
...
subViewModel = ko.mapping.fromJS(#Html.Raw(Json.Encode(Model)));
...
}
#using (Html.BeginForm()){
<button type="submit" class="button" id="SaveBtn">Save</button>
<div data-bind="with:vm">
<div>
#Html.LabelFor(model => model.Eligible)
#Html.CheckBoxFor(model => model.Eligible, new { data_bind = "checked: selectOptionVM.Eligible" })
</div>
<div>
#Html.LabelFor(model => model.selectedOption)
#Html.DropDownListFor(model => model.selectedOption, Model.AvailableOptions,
new
{ data_bind = "options: selectOptionVM.AvailableOptions, optionsText: 'Text', optionsValue: 'Value', value: selectOptionVM.selectedOption"
})
</div>
</div>
}
The javascript for the knockout view model is:
sectionVM = function (data) {
var self = this;
var selectOptionVM = data;
return {
selectOptionVM: selectOptionVM
}
}
$(document).ready(function () {
var viewModel = {
vm: new sectionVM(subViewModel)
};
ko.applyBindings(viewModel);
$("#SaveBtn").click(function () {
var optionModel = ko.toJS(viewModel.vm.selectOptionVM);
ko.utils.postJson($("form")[0], optionModel)
});
});
The controller part:
[HttpPost]
public ActionResult Create(SelectOptionModel selectOptionModel)
{
try
{
// TODO: Add insert logic here
var modelSaved = selectOptionModel;
return RedirectToAction("Index");
}
catch
{
return View();
}
}
I'm venturing a bit of a guess here, but this could be the problem: the id-bit of your selected option will always be a string (because it will go in the <option value="" attribute). Your endpoint expects an int. As far as I can see, you don't convert the selectedOption before sending it to the server. try parseInt(selectedOption, 10) before sending it to the server. Also, use the network tool in your browser to debug the info that is being sent to the controller. That might help you to zone in on the problem.
Actually it works. Somehow it was not working previously, but after I cleared cache, cookies etc, it just worked. Thanks everyone!

In Update view, the dropdown selected value is not set if the selected field is nullable in viewmodel

Say for example my viewmodel is as follows:
public class MyViewModel
{
public int? SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
}
And the view is as follows:
#model MyViewModel
#Html.DropDownListFor(
x => x.SelectedCategoryId,
Model.Categories,
"--Select--"
)
In the update view, if the model has a value for the SelectedCategoryId it is not shown selected in the dropdownlist. The "--Select--" is always selected. The same logic works for other dropdownlist if their Id field are not nullable.
Any suggestions?
Suggesting you a simple approach.
If you are using IEnumerable <SelectListItem> then there is no need to user different variable for Maintaining Selected value.. Just mark your category selected when you are populating Categories SelectList.
SelectListItem category = new SelectListItem
{
Text = "CategoryId",
Value = "CatagoryName",
Selected = true
};
Categories.Add(category);
public class MyViewModel
{
public IEnumerable<SelectListItem> Categories { get; set; }
}
..............................................
#model MyViewModel
#Html.DropDownList("Name",
Model.Categories,
"--Select--"
)
In the end I used jquery to select the dropdown if the Id has a value.
In the view, I create a hidden field (don't use the #Html.HiddenFor)
#Html.Hidden("SelectedCategorySubId", Model.SelectedCategorySubId.GetValueOrDefault(), new { #id = "hdnSelectedCategorySubId" })
In JS file,in the call back method of ajax call (to load the drop down),after adding data to dropdown, get the hidden field value and then select that value in dropdown.
$.ajax({
type: 'POST',
url: "GetSubCategory",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(param),
success: function (subCategoryList) {
if (subCategoryList != null && subCategoryList != '') {
$("#SelectedCategorySubId").append('<option>--- Select ---</option>');
$.each(subCategoryList, function (i, subCategory) {
$("#SelectedCategorySubId").append($('<option/>', {
value: subCategory.Value,
text: subCategory.Text
}));
});
//Set selected value from hidden field
var selectedCategorySubId = $("#hdnSelectedCategorySubId").val();
// alert("Sub Cat" + selectedCategorySubId);
$("#SelectedCategorySubId").val(selectedCategorySubId);
}//end if
else {
//alert("empty subcategoryList " + subCategoryList);
$("#tdSubCategory").hide();
}
}
And update the hidden field if the dropdown changes
//Update hidden field, if cat changes
$("#SelectedCategorySubId").change(function () {
$("#hdnSelectedCategorySubId").val($(this).val());
});
I hope this helps someone.

View not binding correcty with the model

I can figure out why it's not binding. So I have a form where a ListBox is in a partial view which I reload everytime I click on a checkbox to fill the listbox.
The code of my ModelView for the form is :
<div class="row-fluid">
<div class="span3">
<label>Fonction(s):</label>
</div>
<div class="span9" id="ListeFonction">
#Html.Partial("ListerFonction", Model)
</div>
</div>
<div class="row-fluid">
<div class="span5 offset3">
<div class="fonctions_container">
#foreach (extranetClient.Models.Classes.FonctionContact fonction in ViewBag.Fonctions)
{
string coche = "";
if ((#Model.ListeFonctions).Any(c => c.IdFonction == fonction.IdFonction))
{
coche = "checked";
}
<input type="checkbox" #coche class="checkbox" value="#fonction.IdFonction" />#fonction.LibelleFonction <br />
}
</div>
</div>
</div>
So as you can see, I render a partial view just after the "Email" Textbox. The code for it is :
#Html.LabelFor(contact => contact.SelectedFonctionIds, "ListeFonctions")
#Html.ListBoxFor(contact => contact.SelectedFonctionIds, new MultiSelectList(Model.ListeFonctions, "IdFonction", "LibelleFonction"), new { disabled = "disabled")
The model associated to that view looks like that:
private List<int> _selectedFonctionIds;
public List<int> SelectedFonctionIds
{
get
{
return _selectedFonctionIds ?? new List<int>();
}
set
{
_selectedFonctionIds = value;
}
}
public List<FonctionContact> ListeFonctions = new List<FonctionContact>();
public MultiSelectList ListeFonctionsSelectList
{
get
{
return new MultiSelectList(
ListeFonctions,
"IdFonction", // dataValueField
"LibelleFonction" // dataTextField
);
}
}
public Contact() { }
public Contact( List<FonctionContact> listeFonctions, List<int> selectedFonctionIds)
{
this.ListeFonctions = listeFonctions;
this.SelectedFonctionIds = selectedFonctionIds;
}
public Contact(int idContact, string nom, string prenom, string email, string telephoneFixe, string telephonePort) {
this.IdContact = idContact;
this.Nom = nom;
this.Prenom = prenom;
this.Email = email;
this.TelephoneFixe = telephoneFixe;
this.TelephonePort = telephonePort;
}
public Contact(int idContact, string nom, string prenom, List<int> selectedFonctionIds, List<FonctionContact> listeFonctions, string email, string telephoneFixe, string telephonePort)
{
this.IdContact = idContact;
this.Nom = nom;
this.Prenom = prenom;
this.SelectedFonctionIds = selectedFonctionIds;
this.ListeFonctions = listeFonctions;
this.Email = email;
this.TelephoneFixe = telephoneFixe;
this.TelephonePort = telephonePort;
}
But the ListBox of the partial view is not binding with the model. I get well the other informations but not these in the listbox. Somebody has an idea ?
Why are you forcing the ListBox's id here:
#Html.ListBoxFor(contact => contact.SelectedFonctionIds,
new MultiSelectList(Model.ListeFonctions, "IdFonction", "LibelleFonction"),
new { disabled = "disabled", **id="idFonctions"** })
ListBoxFor helper is supposed to generate the ListBox's id for you, and the Id should be the same as the attribute it should bind with. Shouldn't it be SelectedFonctionIds?
Was the binding working before you started using the PartialView? Because from your previous question, I see that you had:
#Html.ListBoxFor(contact => contact.SelectedFonctionIds, Model.ListeFonctionsSelectList, new { disabled = "disabled" })
in your View (i.e., you didn't set the id attribute).