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层处理。这样和我之前项目结构,可共存于同一解决方案。