MVC下读取XML生成动态表单的例子

问题的提出:在MVC下动态表单怎么生成?

好的,我们来看下面的例子:

接着上次的MVCMembership来讲

我们首先添加一个目录XML。然后添加View:

1.checkXml.aspx 用来检查我们输入的XML格式(利用XSD检查)

2.New.aspx 用来新增XML表单的

3.Show.aspx 用来显示XML表单的

4.ShowResult.aspx 用来显示XML表单提交的结果的

一、数据库结构

要用到动态的表单,这里我们利用Sqlserver2005的XML类型来保存,建表的SQL如下:

use Test
/*==============================================================*/
/* DBMS name: Microsoft SQL Server 2005 */
/* Created on: 2009/5/8 7:56:50 */
/*==============================================================*/
if exists (select 1
from sysindexes
where id = object_id('XMLFORM')
and name = 'IDX_XML' and indid > 0
and indid < 255)
drop index XMLFORM.IDX_XML
go if exists (select 1
from sysindexes
where id = object_id('XMLFORM')
and name = 'IDX_ID' and indid > 0
and indid < 255)
drop index XMLFORM.IDX_ID
go if exists (select 1
from sysobjects
where id = object_id('XMLFORM')
and type = 'U')
drop table XMLFORM
go /*==============================================================*/ /* Table: XMLFORM */
/*==============================================================*/
create table XMLFORM (
ID int identity,
FORMXML xml not null,
constraint PK_XMLFORM primary key (ID)
)
go declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'XMLFORM',
'user', @CurrentUser, 'table', 'XMLFORM' go /*==============================================================*/ /* Index: IDX_ID */
/*==============================================================*/
create unique index IDX_ID on XMLFORM (
ID ASC ) go /*==============================================================*/ /* Index: IDX_XML */
/*==============================================================*/
create PRIMARY XML INDEX IDX_XML on XMLFORM (
FORMXML
)
go

好了我们建了一个名为XMLForm的表,其中ID自增,FORMXML为我们需要的XML表单的内容

二、编写XML的Controller

XMLController.cs

主要的action

1.New

image

 image image image

 [AcceptVerbs(HttpVerbs.Post), ValidateInput(false)]
public ActionResult New(string xmlContent)
{
System.Threading.Thread.Sleep(2000); //模拟提交等待 xmlContent = Server.UrlDecode(xmlContent); if (!string.IsNullOrEmpty(xmlContent))
{
//if (!CheckXML(xmlContent, out strError)) //服务器端检测,如果用了ajax检测,就没必要了 //{ // ModelState.AddModelError("_FORM",strError); // return View(); //} XMLFormDataContext db = new XMLFormDataContext();
TransactionOptions opt = new TransactionOptions();
ViewData["xmlContent"] = xmlContent;
opt.IsolationLevel = IsolationLevel.Serializable;
using (TransactionScope tran = new TransactionScope(TransactionScopeOption.RequiresNew, opt))
{
XMLFORM f = new XMLFORM();
try { f.FORMXML = XElement.Parse(xmlContent); db.XMLFORMs.InsertOnSubmit(f); db.SubmitChanges(); var id = db.XMLFORMs.Max(p => p.ID); ViewData["result"] = "success";
ViewData["id"] = (int)id;
tran.Complete();
return View();
}
catch { ViewData["result"] = "failure";
ModelState.AddModelError("_FORM", "envalid xml format");
return View();
}
}
}
else return View();
}
XML:
<Form Title="testForm">
<Input Text="ID" Name="txtID" Type="TextBox" Required="true"></Input>
<Input Text="Name" Name="txtName" Type="TextBox" Required="true"></Input>
<Input Text="Job" Name="txtJob" Type="TextBox" Required="false"></Input>
<Input Text="Validate" Name="btnValidate" Type="Button"></Input>
<Input Text="Commit" Name="btnComit" Type="Button"></Input>
</Form>
注意:我们使用了事务,所以不要忘了最后要提交。我就是忘了,找了3天错误   

2.Show

image

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Show(int? ID)
{
int nId = 0;
XElement doc = null;
if (int.TryParse(Request["id"], out nId))
{
try { XMLFormDataContext db = new XMLFormDataContext();
var q = from f in db.XMLFORMs
where f.ID == nId
select f.FORMXML
;
if (q.Count() > 0)
{
foreach (var qq in q)
{
doc = qq;
}
ViewData["xml"] = doc;
}
else { ModelState.AddModelError("_FORM", "Not Exists");
}
ViewData["id"] = nId;
}
catch (Exception e)
{
ModelState.AddModelError("_FORM", e.Message);
}
}
else { ModelState.AddModelError("_FORM", "Miss ID");
}
return View();
}

注意这里Show.asp的写法.不能用<input .../>直接输出控件字符串,而要

   Response.Write(Html.TextBox(i.Attribute("Name").Value, "", new { @class = "InputNormal" }));
否则提交后得不到form的值
代码如下:
  <%using (Html.BeginForm())
{ %> <%=Html.ValidationSummary()%> <h2> Show XML Form</h2> <div id="divResult"></div> <fieldset> <legend>XML Form Information</legend> <table cellpadding="0" cellspacing="0" width="90%"> <% XElement xml=(XElement)ViewData["xml"];
StringBuilder sbScript = new StringBuilder();
sbScript.AppendLine("<Script language='javascript'>");
sbScript.AppendLine("function checkControls() {");
var input = from p in xml.Elements()
where p.Name == "Input" && p.Attribute("Type").Value != "Button" select p; foreach (var i in input)
{
Response.Write("<tr>");
if (bool.Parse(i.Attribute("Required").Value))
{
sbScript.AppendLine(string.Format(
@"$('#{0}').formValidator({{onshow:'please input {1}',onfocus:'{1} required',oncorrect: 'OK' }})",
i.Attribute("Name").Value,
i.Attribute("Text").Value)
);
sbScript.AppendLine(
string.Format(".inputValidator({{ min: 1, empty: {{ leftempty: true, rightempty: true}}, onerror: '{1} required' }});",
i.Attribute("Name").Value,
i.Attribute("Text").Value
));
}
Response.Write(string.Format("<td>{0}</td>", i.Attribute("Text").Value));
Response.Write("<td>");
Response.Write(Html.TextBox(i.Attribute("Name").Value, "", new { @class = "InputNormal" }));
Response.Write("</td>");
Response.Write(string.Format("<td><div id='{0}Tip'></div></td>",i.Attribute("Name").Value));
Response.Write("</tr>");
}
sbScript.AppendLine("}</script>");
Response.Write(sbScript);
input = from p in xml.Elements()
where p.Name == "Input" && p.Attribute("Type").Value == "Button" select p; foreach (var b in input)
{
Response.Write("<tr>");
switch (b.Attribute("Text").Value.ToLower())
{
case "commit":
Response.Write(string.Format("<td colspan=3><input id='{0}' type='submit' value='{1}' /></td>", b.Attribute("Name").Value, b.Attribute("Text").Value));
break;
case "validate":
Response.Write(string.Format("<td colspan=3><input id='{0}' type='button' value='{1}' onclick='return jQuery.formValidator.pageIsValid();' /></td>", b.Attribute("Name").Value, b.Attribute("Text").Value));
break;
}
Response.Write("</tr>");
}
%> </table> </fieldset> <%} %>

XML内容的检测

我们可以利用XSD来检查。

代码如下

  #region 检查xml
[AcceptVerbs(HttpVerbs.Post), ValidateInput(false)]
public ActionResult checkXML(string xmlContent)
{
string strOut = string.Empty;
int nResult = (CheckXML(xmlContent, out strOut) == true) ? 1 : 0;
Dictionary<string, string> dicResult = new Dictionary<string, string>();
dicResult.Add("State", nResult.ToString());
dicResult.Add("Message", strOut);
return Json(dicResult);
}
private bool CheckXML(string xmlContent)
{
bool bResult = true;
if (!string.IsNullOrEmpty(xmlContent))
{
//利用XmlSchemaSet(XSD)检查XML XmlSchemaSet validator = new XmlSchemaSet();
validator.Add("", XmlReader.Create(Server.MapPath(Url.Content("~/Models/xmlTest.xsd")))); //Url.Content必须,否则找不到文件 XDocument doc = null;
try { doc = XDocument.Parse(xmlContent); doc.Validate(validator, (sender, e) => { bResult = false;
});
}
catch { bResult = false;
}
}
else bResult = false;
return bResult;
}
private bool CheckXML(string xmlContent, out string outString)
{
bool bResult = true;
string strError = string.Empty;
if (!string.IsNullOrEmpty(xmlContent))
{
//利用XmlSchemaSet(XSD)检查XML XmlSchemaSet validator = new XmlSchemaSet();
validator.Add("", XmlReader.Create(Server.MapPath(Url.Content("~/Models/xmlTest.xsd")))); //Url.Content必须,否则找不到文件 XDocument doc = null;
try { doc = XDocument.Parse(xmlContent); doc.Validate(validator, (sender, e) => { strError = e.Message; bResult = false;
});
}
catch (XmlException e)
{
strError = e.Message;
bResult = false;
}
}
else bResult = false;
if (!bResult)
outString = strError;
else outString = "OK";
return bResult;
}
#endregion

这里我们返回json数据,来ajax检查

        $(document).ready(function() {
$("form").submit(function() {
if (jQuery.formValidator.pageIsValid())
$.blockUI({ message: '<h1 class="loading">Please Wait...</h1>' });
});
if ($("#xmlContent").val() != "")
$("#xmlContent").val(decodeURI($("#xmlContent").val()));
$.formValidator.initConfig();
$("#xmlContent").formValidator({ onshow: "please input xml", onfocus: "xml required", oncorrect: "OK" })
.inputValidator({ min: 1, empty: { leftempty: true, rightempty: true }, onerror: "xml required" })
.ajaxValidator({
type: "post",
url: "checkXML",
datatype: "json",
success: function(responseData) {
if (responseData.State == "1") {
return true;
}
else {
return false;
}
},
buttons: $("#submit"),
error: function() { alert("server busy,try later..."); },
onerror: "XML Format error or same content",
onwait: "XML checking,please wait..." }); }); function CheckForm() { result = jQuery.formValidator.pageIsValid(); if (result) {
$("#xmlContent").val(encodeURI($("#xmlContent").val()));
}
return result;
}
注意我们利用了encodeURI,decodeURI进行编码,来避免A potentially dangerous Request.QueryString value was detected from the client问题

3.最后编写ShowResult

        [AcceptVerbs(HttpVerbs.Post)]
public ActionResult ShowResult()
{
StringBuilder sbResult = new StringBuilder();
foreach(string key in Request.Form.Keys)
{
sbResult.AppendLine(string.Format("{0}={1}", key, Request.Form[key]));
}
return Json(sbResult.ToString());
}
很简单的直接输出form的内容,你也可以进行你自己的处理,用ajax来避免再次刷新
最后结果
image image 
代码演示和下载 我的个人网站
posted @ 2009-05-18 07:18  柯南  阅读(3669)  评论(10编辑  收藏  举报