Which format does ASP.NET expect when sending array with gaps? - c#

This is my HTML:
<ul id="limitations" name="limitations" class="dropdown-menu">
<li>
<div class="checkbox checkbox-default">
<input type="checkbox" id="limitation-checkbox-0" value="8" name="limitations[0]" data-name="ALS ">
<label for="limitation-checkbox-0" style="color:black">ALS </label>
</div>
</li>
<li>
<div class="checkbox checkbox-primary">
<input type="checkbox" id="limitation-checkbox-1" value="10" name="limitations[1]" data-name="Arthrogryposis Multiplex Congenita (AMC) & Amyoplasia">
<label for="limitation-checkbox-1" style="color:black">Arthrogryposis Multiplex Congenita (AMC) & Amyoplasia</label>
</div>
</li>
<li>
<div class="checkbox checkbox-success">
<input type="checkbox" id="limitation-checkbox-2" value="2" name="limitations[2]" data-name="Cerebral Palsy (CP), (GMFS)">
<label for="limitation-checkbox-2" style="color:black">Cerebral Palsy (CP), (GMFS)</label>
</div>
</li>
<li>
<div class="checkbox checkbox-info">
<input type="checkbox" id="limitation-checkbox-3" value="4" name="limitations[3]" data-name="Hearing impairment deafness or hard of hearing">
<label for="limitation-checkbox-3" style="color:black">Hearing impairment deafness or hard of hearing</label>
</div>
</li>
... MORE <li> ...
</ul>
When I post the form, the model binder for List<int> limitations works only if the checkboxes are selected from, if there is a gap in the array, all items after the gap are not binded.
For example:
Consider the first(8) and the third(10) checkboxes are checked.
The value binded to List<int> limitations is [8].
Or if all the checkboxes are checked, List<int> limitations is binded witn an empty list.
I tried changing names of the checkboxes from name="limitations[0..n]" to name="limitations[]" but that caused ASP.NET to completely ignore the values.
Isn't there a standard for such things?!
I know how I can overcome this with javascript manipulation, but I really rather not going that awkward route for such a trivial case.
Using asp.net core 1.0.0 and .Net4.6.1

ASP.Net model binding hasn't changed this behavior between ASP.Net 4 and ASP.Net Core. The answer here is still valid.
Your naming convention is a little off. If you have multiple <input type="checkbox"...> with the same name, it should serialize automatically to the an array that ASP.Net's model binding can accommodate.
Try using name="limitations" instead of name="limitations[0]" throughout your inputs and see if that works as expected.

Related

Composing HTML code (called through Razor) inside Knockout foreach loop

my situation is the current one:
<fieldset name="sortSearch">
#Html.CreateSortingControl("views.restricted.widgets.alertdetailwidget.sorting", "searchCriteria.Sorting", "changeSortingDirection", "changeSortingField", GetValueList(SortingValueProvider.ValueProviderId))
</fieldset>
In practice I am calling some CS code that will create some a markup with a dropdown and some bindings. For example when a value is selected in this dropdown the function changeSortingField will be called. Everything works properly.
What goes wrong is that I want to encapsulate this markup in a Knockout foreach loop that depends on an observable. Sort of this:
<!-- ko foreach: {data: FieldSortings, as: 'sortings' }-->
<fieldset name="sortSearch">
#Html.CreateSortingControl("views.restricted.widgets.alertdetailwidget.sorting", "searchCriteria.Sorting", "changeSortingDirection", "changeSortingField", GetValueList(SortingValueProvider.ValueProviderId))
</fieldset>
<!-- /ko -->
Which means that when FieldSortings increses, the new markup should appear and indeed it does.
Problem is that with this logic none of my functions is anymore called, such as when I select a value from my dropdown the bindings don't work anymore. It feels like that the markup is computed only once (I think). Should I use some kind of particular composition to call the Razor function on the fly? Thanks in advance!
EDIT: the markup returned by razor is:
<div class="input-group custom-sort">
<section data-bind="validationElement: searchCriteria.Sorting.Field">
<label class="select">
<select data-i18n="[aria-label]accessibility.select.value" class="input-xs select-Sorting-Field" data-bind="value: searchCriteria.Sorting.Field,event: {change: changeSortingField}">
<option value="" css="searchcriteria-sorting-field-"><Select Order by></option>
<option value="DetectionDate" data-default="true" css="searchcriteria-sorting-field-DetectionDate">Detection date</option>
<option value="Impact" css="searchcriteria-sorting-field-Impact">Impact</option>
<option value="Score" css="searchcriteria-sorting-field-Score">Score</option>
</select>
<strong class="tooltip tooltip-top-right">
<i class="fa txt-color-teal"></i>
<span data-i18n="views.restricted.widgets.alertdetailwidget.sorting"></span>
</strong>
</label>
<div class="note note-error" style="display: none;" data-bind="validationMessage: searchCriteria.Sorting.Field"></div>
</section>
<label class="input-group-addon" for="sorting-control" data-bind="click: changeSortingDirection">
<span class="sr-only">Change the sorting direction</span>
<input type="checkbox" name="sorting-control" id="sorting-control" data-bind="checked: searchCriteria.Sorting.IsDescending">
<i></i>
</label>
And FieldSortings is an Observable array defined as:
self.FieldSortings = ko.observableArray([]);
Found the problem. Inside a Knockout foreach loop you need to refer to outsider variables and functions with the $parent . Due to this reason it couldn't make the bindings necessaries to work.

Form post to another page

I am fairly new to C# and asp.net and am having trouble showing something submitted in a form. The form element is a tag. The drop-down info is pulled from a data base and displays correctly. It's just getting it to post to another page after the form is submitted is where I am having the problem. Any help would be appreciated.
Contact.aspx:
<form action="Default.aspx" method="post" data-transition="pop">
<div data-role="fieldcontain">
<label for="topEmails">Business Entity ID:</label>
<select name="topEmails" id="topEmails" data-native-menu="false"
runat="server">
</select>
</div>
<input type="submit" data-iconpos="right" data-inline="true"
data-icon="plus" name="sendMessage" id="sendMessage" value="Send Info">
</form>
Contact.aspx.cs:
AdventureWorks2012DataContext db = new AdventureWorks2012DataContext();
var emails = (from b in db.EmailAddresses
select new { b.EmailAddressID, b.BusinessEntityID }).Take(20);
topEmails.DataTextField = "BusinessEntityID";
topEmails.DataValueField = "BusinessEntityID";
topEmails.DataSource = emails;
topEmails.DataBind();
Default.aspx.cs:
FormSuccessBID.InnerHtml = "Business Entity ID: " + Request.Form["topEmails"] + "";
Any ideas why this wouldn't be working?
Update:
Contact.aspx:
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
<h2 style="text-align: center;">Contact Kyle</h2>
<form action="Default.aspx" method="post" data-transition="pop">
<div data-role="fieldcontain">
<label for="userFName">First Name:</label>
<input type="text" name="firstName" id="uFName">
</div>
<div data-role="fieldcontain">
<label for="userLName">Last Name :</label>
<input type="text" name="lastName" id="uLName">
</div>
<div data-role="fieldcontain">
<label for="productsCategories">Products:</label>
<select name="productCategories" id="productCategories" data-native-menu="false" runat="server"></select>
</div>
<div data-role="fieldcontain">
<label for="topEmails">Business Entity ID:</label>
<select name="topEmails" id="topEmails" data-native-menu="false" runat="server"></select>
</div>
<input type="submit" data-iconpos="right" data-inline="true" data-icon="plus" name="sendMessage" id="sendMessage" value="Send Info">
</form>
</asp:Content>
You're missing "runat='server'" in your form definition.
In ASP.NET you're also allowed one form per page. Not sure from what you're posted if you're trying to put multiple forms on there, but if you are, it's not going to work.
I think all you need to do to accomplish what you want is have an ASP.NET button on the page, with the postbackURL set to the page you want to go to. (Of course, you need to do this in a server-side form)
I think you're mixing ASP.NET methods with other, different technologies. (From the look of it, you probably used classic ASP or PHP perhaps?)
If you can't use .NET for whatever reason, the ID/name of the field is not going to be what you're expecting. You need to inspect the form post and find its value - something along the lines of "clt00_somethingelse_topEmails". (Again, this is going to be a heck of a lot easier if you use the .NET way of doing things, but you may have a requirement not to)

How to Insert the values displayed in viewpage to backend

Hi I'm working with MVC3 i want to insert the values displayed in front end into the table in backend.How can i achieve this?
Following is my view,
#model TravelReady_SupervisorInput.Models.TravelReadyModel
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script language="javascript">
$(document).ready(function () {
$("#es").hide();
$("#n").hide();
$("#date").hide();
});
</script>
<h2 class="filter">Associate Details</h2>
<fieldset class="fs">
#foreach (var item in Model.lstTravelReadyEntities)
{
<label class="Detail1"><b>Associate Id : </b>#item.Var_AssoId </label>
<label class="Detail1"><b>Vertical :</b>#item.Var_Vertical</label>
<label class="Detail1"><b>Visa ValidFrom :</b>#item.Dt_VisaValidFrom </label><br /><br />
<label class="Detail2"><b>Associate Name :</b>#item.Var_AssociateName</label>
<label class="Detail2"><b>Account Name :</b>#item.Var_AccountName</label>
<label class="Detail2"><b>Visa ValidDate :</b>#item.Dt_VisaValidTill</label><br /><br />
<label class="Detail3"><b>Grade HR :</b>#item.Var_Grade</label>
<label class="Detail3"><b>Project Name :</b>#item.Var_Project_Desc</label><br />
}
<h2> Response Details</h2><br />
Supervisor Response :
<input type="radio" class="radi" name="radio" value="Yes" onclick="javascript:Getyfunc();">Yes
<input type="radio" name="radio" value="No" onclick="javascript:Getnfunc()">No
<div id="es">
<label style="padding-left:10px;">*Supervisor Inputs :
<select id="dropdown" name="dropdown">
<option value="0">Select</option>
<option value="1">Available for Deployment/Release</option>
<option value="2">Travel Planned</option>
<option value="3">To Deploy For Same Account</option>
</select>
</label>
<label>Comments If Any
<textarea name="comments" id="cmts"></textarea>
</label>
<br />
<br />
<label id="date">*Date of Travel
<input type="text" id="datepicker" onclick="$(this).datepicker().datepicker ('show')"/>
</label>
<br />
<br />
</div>
<div id="n">
<label style="padding-left:10px;">*Supervisor Inputs :
<select id="dropdown" name="dropdown">
<option value="0">Select</option>
<option value="1">Critical Project Resource</option>
<option value="2">Associate Unwilling to Travel</option>
</select>
</label>
<label>Comments If Any
<textarea name="comments" id="cmts"></textarea></label>
<br />
<br />
</div>
<input type="submit" id="sbt" value="Submit" name="Submit" onclick="javascript:InsertDetails();"/>
</fieldset>
This is the child window of the page.Here i'm using partial view also.i want to get all the values which are displayed in a page to be inserted into the table.can Anyone please help me out of this
You should create a ViewModel for your view that will store your model and other data that you want to pass to your controller such as Supervisor Responses and Comments. Take advantage of the MVC extensions such as EditorFor, TextAreaFor, etc
Okay so what you have here is simply the View part of the Model-View-Controller. You seem to have a ViewModel for the list to display on the page, but you are still missing some key pieces:
Another ViewModel to hold your form data you want to send to the Controller. Assuming you want to leave the structure of your View as is, you can simply add this new ViewModel as a property of your existing TravelReadyModel.
Change your HTML form elements to use the HTML Helpers that end in "For" to auto-bind the values back to your new ViewModel. Surround these in an HTML.BeginForm().
Add a controller method for the Post back of the data.
Assuming that you have no DB backend support at all right now, use Entity Framework to setup the DB access.
In the simplest form of a MVC application, the Controller will interact directly with the Entity Framework DataContext and add the newly posted ViewModel from the View to the DB.
There is a lot a research you are going to need to do here, but this should get you started. Here is a great comprehensive tutorial that will walk your through everything above and more!
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

Basic MVC: If-else logic in cshtml page

I am just learning MVC and I've created a form but I would like to set conditional formatting ... like with an if-else construct. I know this is basic, but can I put it on the form? If so, how do I code that? What I would like to do is gray out the background of a input box if the checkbox is NOT checked. Thanks in advance
<div class="left">
Emulate Access
</div>
<div class="right">
<input type="checkbox" name="Emulate" />
</div>
<div class="clear" />
<div class="left">
Emulate Associate:
</div>
<div class="right">
<input type="text" name="NmAssoc" />
</div>
I would use JQuery http://jquery.com/. It works great for this sort of thing.

Html.RadioButton sets all values to selected value

After tinkering around to solve [this][1] problem, I think the core of the problem is the following:
When you use the Html.RadioButton() html helper with an Enum as value field, you can only choose your option once. AFter reposting the page, the helpers will ignore the value set in the call and set all radio buttons to the same value, being the value you selected the previous post back.
Am I doing something wrong?
Example (watch the value of the buttons)
<fieldset>
<legend>Test</legend>
<div>
<label for="SearchBag.EffectIndicatorAny" id="EffectIndicatorAnyLabel">
Any
</label>
<%=Html.RadioButton("SearchBag.EffectIndicator", "Any" , ViewData.Model.SearchBag.EffectIndicatorIsAny, new { #id = "SearchBag.EffectIndicatorAny" })%>
</div>
<div>
<label for="SearchBag.EffectIndicatorSolid" id="EffectIndicatorSolidLabel">
Solid
</label>
<%=Html.RadioButton("SearchBag.EffectIndicator", "Solid", ViewData.Model.SearchBag.EffectIndicatorIsSolid, new { #id = "SearchBag.EffectIndicatorSolid" })%>
</div>
<div>
<label for="SearchBag.EffectIndicatorEffect" id="EffectIndicatorEffectLabel">
Effect
</label>
<%=Html.RadioButton("SearchBag.EffectIndicator", "Effect", ViewData.Model.SearchBag.EffectIndicatorIsEffect, new { #id = "SearchBag.EffectIndicatorEffect" })%>
</div>
</fieldset>
Will generate
<fieldset>
<legend>Effect</legend>
<div class="horizontalRadio">
<label for="SearchBag.EffectIndicatorAny" id="EffectIndicatorAnyLabel">
Any
</label>
<input checked="checked" id="SearchBag.EffectIndicatorAny" name="SearchBag.EffectIndicator" type="radio" value="Any" />
</div>
<div class="horizontalRadio">
<label for="SearchBag.EffectIndicatorSolid" id="EffectIndicatorSolidLabel">
Solid
</label>
<input id="SearchBag.EffectIndicatorSolid" name="SearchBag.EffectIndicator" type="radio" value="Solid" />
</div>
<div class="horizontalRadio">
<label for="SearchBag.EffectIndicatorEffect" id="EffectIndicatorEffectLabel">
Effect
</label>
<input id="SearchBag.EffectIndicatorEffect" name="SearchBag.EffectIndicator" type="radio" value="Effect" />
</div>
</fieldset>
And will generate the second time:
<fieldset>
<legend>Effect</legend>
<div class="horizontalRadio">
<label for="SearchBag.EffectIndicatorAny" id="EffectIndicatorAnyLabel">
Any
</label>
<input id="SearchBag.EffectIndicatorAny" name="SearchBag.EffectIndicator" type="radio" value="Solid" />
</div>
<div class="horizontalRadio">
<label for="SearchBag.EffectIndicatorSolid" id="EffectIndicatorSolidLabel">
Solid
</label>
<input checked="checked" id="SearchBag.EffectIndicatorSolid" name="SearchBag.EffectIndicator" type="radio" value="Solid" />
</div>
<div class="horizontalRadio">
<label for="SearchBag.EffectIndicatorEffect" id="EffectIndicatorEffectLabel">
Effect
</label>
<input id="SearchBag.EffectIndicatorEffect" name="SearchBag.EffectIndicator" type="radio" value="Solid" />
</div>
</fieldset>
This is due to a bug in the ASP.NET MVC Beta code. I wrote a full explanation of the issue at asp.net MVC forum. Refer to this link
In case anybody cares here is a real quick and dirty work around in anticipation for the next update of the framework. It only regexreplaces the value with your value.
It's not unit tested, not guaranteed not whatever.
Put it in your HtmlHelper class library or wherever you put HtmlHelper extentions.
add the following usings:
System.Text.RegularExpressions;
System.Web.Mvc.Html;
/*ToDo: remove when patched in framework*/
public static string MonkeyPatchedRadio(this HtmlHelper htmlHelper, string name, object value, bool isChecked, object htmlAttributes){
string monkeyString = htmlHelper.RadioButton(name, value, isChecked, htmlAttributes);
monkeyString = Regex.Replace(monkeyString, "(?<=value=\").*(?=\".*)", value.ToString());
return monkeyString;
}
I know it can be done better and whatnot, but I really hope it will be fixed soon anyway.
If you feel like making it better, it's community wiki, so go ahead
One thing to check. Are you using the updated model to render your view? I.e. is the same model data that was updated from the post passed to the view the second time it's displayed?

Categories

Resources