昨天我蔡工简单沟通了下webform的使用,我主张,舍弃那些html表单类的服务器端控件,包括textbox button dropdonwlist radiolist等,继续使用repeater、label这些控件。
为什么要舍弃表单控件,因为对对象的赋值太繁琐。
我们之前写的2个函数:assignForm()和readForm()
protected void assignForm()
{
txtid.Text = mBbsactivity.id.ToString();
ddlcataId.SelectedValue = mBbsactivity.cataId.ToString();
txttitle.Text = mBbsactivity.title;
txtcont.Text = mBbsactivity.cont;
txtsignStartDate.Text = LIB.trans.displayDate(mBbsactivity.signStartDate, "");
txtsignEndDate.Text = LIB.trans.displayDate(mBbsactivity.signEndDate, "");
txtstartDate.Text = LIB.trans.displayDate(mBbsactivity.startDate, "");
txtendDate.Text = LIB.trans.displayDate(mBbsactivity.endDate, "");
txtmaxMemberQuantity.Text = mBbsactivity.maxMemberQuantity.ToString();
txtadjustQuantity.Text = mBbsactivity.adjustQuantity.ToString();
ddlidNeedCheck.SelectedValue = mBbsactivity.idNeedCheck.ToString();
}
/// <summary>
/// 读取表单数据到model
/// </summary>
private void readForm()
{
…………
#region 赋值model
mBbsactivity.id = varid; //id
mBbsactivity.cataId = varcataId; //活动分类
mBbsactivity.title = vartitle; //标题
mBbsactivity.cont = varcont; //内容
mBbsactivity.signStartDate = varsignStartDate; //报名开始日期
mBbsactivity.signEndDate = varsignEndDate; //报名截止日期
mBbsactivity.startDate = varstartDate; //活动开始日期
mBbsactivity.endDate = varendDate; //活动结束日期
mBbsactivity.maxMemberQuantity = varmaxMemberQuantity; //人数限制
mBbsactivity.adjustQuantity = varadjustQuantity; //显示人数调整参数
mBbsactivity.idNeedCheck = varidNeedCheck; //是否要审核
#endregion
}
这种形式要杜绝,一律使用映射的形式。可以考虑automap,当然我觉得automap有些麻烦,自己写了一个函数如下,看我写的函数是否足够用,不够用再考虑automap。
public static D Mapper<D, S>(S s, D d)
{
try
{
var Types = s.GetType();//获得类型
var Typed = typeof(D);
foreach (System.Reflection.PropertyInfo sp in Types.GetProperties())//获得类型的属性字段
{
foreach (System.Reflection.PropertyInfo dp in Typed.GetProperties())
{
if (dp.Name == sp.Name && dp.PropertyType == sp.PropertyType && dp.Name != "Error" && dp.Name != "Item")//判断属性名是否相同
{
var val = sp.GetValue(s, null);
if (val != null) dp.SetValue(d, val, null);//获得s对象属性的值复制给d对象的属性
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return d;
}
}
那表单使用何种形式呢?如果不考虑兼容性,可使用vue的V-model方式,考虑兼容性的话,则可遍历form内表单的方式:
//把form里的表单构造成key/value数组
function getFormData($form) {
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function (n, i) {
indexed_array[n['name']] = n['value'];
});
return indexed_array;
}
getformdata()这个函数我写在viewjs的文件夹的根目录app.js里,所以viewjs下子文件夹里的js都可直接调用。
把这个函数的结果,用JSON.stringify转成字符串,然后使用ajax提交给后台就可。
//提交修改数据
function formEditSubmit() {
var url = domain + controllerName + "/update";
var formData = getFormData($('#formEdit'));
$.ajax({
type: "post",
url: url,
data: { "formData": JSON.stringify(formData) },
dataType: "json",
error: function (request) {
},
success: function (result) {
}
}
);
}
如果使用webapi,则直接提交到webapi,如果还是使用webform,我考虑的是在webform的base里,定义几个virtual函数,用于接收来之ajax的请求,然后在base的OnInit事件里,判断请求的类型以及应调取的函数。这样虽然每个webform都有接收ajax的入口,但入口是标准统一的,不会导致代码紊乱。
这样改进的webform还是webform吗?当然是,因为它还是事件驱动的,页面形式,所见即所得等都依然不变。
具体分层理念上,aspx.cs的职能对应controller层,只处理数据,不处理业务,所有业务仍然交给bll层处理。这样和我之前项目结构,可共存于同一解决方案。