5

I am running into an issue where I have multiple forms with a number of controls on them (20-40). The problem is that when I handle the postback, I need to put their values into variables and if they are not asp.net server controls (i.e select, input, etc...) I sometimes need to make sure they even exist. So, if I have a plain html checkbox, which is unchecked, it will not be posted to the server and you need to check for its existence, before being able to get its value. After that I need to pass them into a method to save to the database. The method handles all my crud and business validation. Setting this up is tedious at best and very time consuming. What are people doing to handle this? I am using ASP.Net 4.0 Web forms and VB.Net. One thought was to pass the http context into the method and let the code in the method look for the values. Still, doesn't seem that good of a solution. Any advice would really be appreciated, since I know I am not the only one who has run into this problem. Thanks in advance.

Wade

Wade73
  • 4,359
  • 3
  • 30
  • 46
  • 3
    What do you mean by "if they are not asp.net controls", are they usercontrols? Also, what do you mean by "they even exist"? Can you please post the code if possible? – Nexus23 Dec 20 '12 at 20:06
  • If they are HTML controls, such as a select, input, textarea, etc... What I mean by if they exist, is that a checkbox (not asp.net server control) which has not been checked, will not be posted back to the server (http://stackoverflow.com/questions/11424037/does-input-type-checkbox-only-post-data-if-its-checked). So I am not sure how code will help as the issue is about the best way to handle a large amount of posted values. HTH. – Wade73 Dec 20 '12 at 20:40
  • 1
    Are you in the possibility to create a class that is representing your form fields/data structure. If so then create for each form such a class. Then you know what to expect back from your form. If your checkboxes are not returned, then they are false. – ChiYoung Dec 20 '12 at 21:07
  • 1
    In general, if you use ASP.NET with WebForms, you also use the facilities it brings. It means, you will not use plain (w/o runtat=server) HTML controls, but instead always use controls with runat=server, including HREF, INPUT, etc... so you don't have to worry about all this because they will be automatically equipped with the viewstate (client side state moved back&forth between server and client) – Simon Mourier Mar 07 '13 at 23:52
  • Simple text showing some problematic example would help understand what you mean. – Tengiz Mar 12 '13 at 22:11

4 Answers4

2

For large forms, you can:

  1. create javascript object on client, convert it to JSON string, put JSON string to ASP .NET control Hidden or invisible textarea;
  2. submit form and deserialize JSON to object on server.

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.validate.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.validation.net.webforms.min.js" type="text/javascript"></script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:HiddenField runat="server" ID="Hidden1" />
    <input type="checkbox" id="CheckBox1" checked />
    <input type="checkbox" id="CheckBox2" />
    <input type="text" id="text1" name="text1" value=""/>
    <asp:Button runat="server" Text="Button" ID="Button1" OnClientClick="createJSON()" OnClick="Button1_Click" />
    <script type="text/javascript">

        function createJSON() {
            $('#Hidden1').val(JSON.stringify({
                field1: $('#CheckBox1').is(':checked'),
                field2: $('#CheckBox2').is(':checked'),
                field3: $('#text1').val()
            }));
        }

        $(document).ready(function () {
            $("#form1").validate({
                onsubmit: false,
                rules: {
                    text1: {
                        required: true,
                        digits: true
                    }
                }
            });

            $("#Button1").click(function (evt) {
                var isValid = $("#form1").valid();
                if (!isValid) evt.preventDefault();
            });
        });
    </script>
    </form>
</body>
</html>

Default.aspx.cs

using System;
using System.Web.Script.Serialization;

public class myClass
{
    public bool field1;
    public bool field2;
    public string field3;
}

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        var result = (myClass)(new JavaScriptSerializer()).Deserialize(Hidden1.Value, typeof(myClass));
    }
}

enter image description here

enter image description here

Install validation:

PM> Install-Package JQuery.Validation

PM> Install-Package JQuery.Validation.WebForms

Boris Gappov
  • 2,483
  • 18
  • 23
  • Very interesting solution. How do you handle an integer field? My biggest problem was that I might have 10 integer fields, so now I need to parse each field and if successful convert to an integer. What I am trying to do is see what the easiest way to accomplish this. – Wade73 Mar 14 '13 at 16:44
  • use any validation. for example http://plugins.jquery.com/validationengine/ When you using MVC, validation already included in project, just use it. Wait, i write example – Boris Gappov Mar 14 '13 at 16:45
1

From the moment that some controls they not post back any value, like the check box if is not checked you have two options.

  1. Know all your controls before and after the post back / or
  2. Create with javascript all the names of the controls and post them back in a hidden field.

Now, on the post back you have all the posted values on the HttpContext.Current.Request.Form where you can read them all.

On the client side you can use simple javascript or jQuery to create the list of all input controls and send them on a hidden input. Here is an example:

var inputs, index, cNames = ""; 
inputs = document.getElementsByTagName('input');
for (index = 0; index < inputs.length; ++index) {
    cNames += "&" + inputs[index].name;
}   

document.getElementById("AllControls").value = cNames;

or the same with jQuery

    var cAllNames = "";
    $('input').each(function() {
        cAllNames += "&" + $(this).attr("name");
    });
    jQuery('#AllControls').val(cAllNames);

and on your page you have a hidden control like

<input type="hidden" name="AllControls" id="AllControls" />

and on the post you have all the names of your controls in a line like:

AllControls=&__VIEWSTATE&__EVENTVALIDATION&cbBoxTest&AllControls&Button1

There you can split that string, each name is seperated with the &, and there you can see what is used, what is not. You can either pass additional informations about that controls - the same way I send the name of each.

Aristos
  • 66,005
  • 16
  • 114
  • 150
  • I am looking to see how people handle the stuff on the server side. I do know all the controls and right now I have to touch each field (make sure it has a value, validate it, etc...), but it seems people out there have to have found a better way to handle this. Do they create a class and use the request form to fill it? I am looking for the best practice for doing this. Thanks. – Wade73 Mar 08 '13 at 03:07
  • @Wade73 I do use a class that I create the list of the controls that I will like to show on the page, then I render them on the page, and on the post back I know them and read the data. In some case I save the list on the view state. What do you like to say you about that ? – Aristos Mar 08 '13 at 07:53
  • An example would be nice. Do you do something special in the class or is it just a list of fields? – Wade73 Mar 08 '13 at 12:15
  • @Wade73 Sorry that I delay to replay. My code is very strong connected with the rest of my modules, so I need to make a stand alone version of it and write it here, I will try to find some time to do that before the end of the bounty. In general is a class that keep, render, and handle a list of simple html controls. – Aristos Mar 10 '13 at 16:45
1

For each web form create a model class that has public properties with all the fields that may be on the form. Create name, validation and default value attributes and apply them to the properties. During the postback, find out what the model class is needed, create an instance, iterate its public properties and apply: if post has the field with property name - validate the value and apply to the field, if not - apply the default. Something like (i'll use c# but I guess it's clear anyway)

MyCrudModelForSomeForm {
    [MyWebFormField(Default = 42, Type = typeof(int), Name = "txtAmount")]
    public int SomeInt { get; set; }
    [MyWebFormField(Default = "Hello", Type = typeof(string), Name = "txtMessage", Validate = "$[A-Z]{6}^")]
    public string SomeString { get; set; }
    [MyWebFormField(Default = "Zimbabwe", Type = typeof(string), Name = "txtCountryChoice")]
    public string SomeOtherString { get; set; }
}

That's basically the custom implementation of M(odel) from MVC concept.

durilka
  • 1,399
  • 1
  • 10
  • 22
0

The ASP.NET Webforms arch does not support multiple forms

If you have created a page that has multiple forms then i would suggest use jQuery and Post Individual form to the respected handler to process the request

This will be simple and elegant

Amit Bagga
  • 648
  • 3
  • 11
  • My problem is not with the posting or even anything to do with the client side code. I am looking for better ways to handle these fields when they are posted to the server. – Wade73 Mar 12 '13 at 10:05
  • @Wade73, the best way is to map the values to a class as ChiYoung mentioned. That way you have all posted variables in once easy to manage place. – Andrew Grothe Mar 14 '13 at 12:12
  • Make a view model as suggested and Map the Form values to the model with Nullable types where required. – Amit Bagga Mar 18 '13 at 07:16