任何優秀的架構,都能傳遞參數。在之前的路由章節,我們已經看到了如何在URL中傳遞參數。
能夠傳遞簡單的參數當然好,特别是在設計那些從資料庫讀取記錄的API設計中。但是,很多情況下也是需要傳遞複雜對象。
這個可能是登入子產品的驗證資訊,或者是資料庫表中的多條記錄。不管怎麼樣,隻是傳遞簡單對象已經不能滿足。
這下就該輪到Nancy的模闆綁定功能起作用了。
如果你之前已經熟悉了ASP.NET MVC,你應該已經了解了模型綁定是什麼了: 這是一個根據請求和攜帶的資料去比對對象變量的
一圖賽千言
為了簡單起見,想象我們有一個位址簿,我們需要儲存位址記錄到位址庫資料庫中。首先要做的就是建立一個代表資料庫中記事簿記錄的類。如下:
namespace nancybook.Models
{
public class Address
{
public int RecordId { get; set; }
public string Name { get; set; }
public string BuildingAddress { get; set; }
public string Town { get; set; }
public string County { get; set; }
public string PostalCode { get; set; }
}
}
看下這個類,估計您一眼就能想到,我們采用一個整形數字代表記錄,每條記錄都是由五個屬性構成了位址資訊。
目前台通過AJAX向背景送出表單或傳遞JSON對象時,就能獲得其中的五個屬性:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuQDN2EzM3AzN50SO3kzN1QDM1EDNwIDM3EDMy0COygzN3ATMvwlMwcTMwIzLchjM4czNwEzLcd2bsJ2Lc12bj5ycn9Gbi52YuUTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
正如你在上圖中看到的,你可以在Web表單中發送一個複雜對象,每個表單元素的名字和數值會一起拼接為一個字元串。這也适用于發送JSON或XML格式的資料。
模型綁定的任務就是把傳遞的字元串比對到對象的屬性上。
如果隻是傳遞了部分字段,其他字段仍然是預設值。
一個小例子
讓我們建立一個用于存放視圖的檔案夾address,然後在其中添加一個叫index.html的HTML檔案,代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Nancy Demo | Data Binding Example</title>45
<link href="~/content/bootstrap.min.css" rel="stylesheet"
type="text/css" />
</head>
<body>
<div class="container">
<div class="page-header">
<h1 style="display: inline-block">Nancy Demo <small>Data Binding
Example</small></h1>
<h1 style="display: inline-block" class="pull-right"><small><a
href="~/" title="Click to return to demo home page">home <span
class="glyphicon glyphicon-home"></span></a></small></h1>
</div>
<p class="lead">Please fill in the form below and click 'Send Data'
to perform a data bind to the post action.</p>
<input id="RecordId" name="RecordId" type="hidden" value="1"/>
<div class="form-group">
<label for="Name">Name</label>
<input type="text" class="form-control" id="Name" name="Name"
placeholder="Enter Persons Name here"/>
</div>
<div class="form-group">
<label for="BuildingAddress">Building Address</label>
<input type="text" class="form-control" id="BuildingAddress"
name="BuildingAddress" placeholder="Enter Building Address here" />
</div>
<div class="form-group">
<label for="Town">Town</label>
<input type="text" class="form-control" id="Town" name="Town"
placeholder="Enter Town here" />
</div>
<div class="form-group">
<label for="County">County</label>
<input type="text" class="form-control" id="County" name="County"
placeholder="Enter County here" />
</div>
<div class="form-group">
<label for="PostalCode">Postal Code</label>
<input type="text" class="form-control" id="PostalCode"
name="PostalCode" placeholder="Enter Postal Code here" />
</div>46
<button type="submit" class="btn btn-primary">Send Data</button>
</form>
</div>
<script src="~/scripts/jquery-2.1.3.min.js"></script>
<script src="~/scripts/bootstrap.min.js"></script>
</body>
</html>
在子產品檔案夾中添加一個類檔案 AddressRoutes.cs,代碼如下:
using Nancy;
namespace nancybook.modules
{
public class AddressRoutes : NancyModule
{
public AddressRoutes() : base("/address")
{
Get[@"/"] = _ => View["address/index"];
}
}
}
編譯運作,輸入請求位址/address,能看到下面的樣子:
由三種不同的綁定方式,比較典型的如下:
Address myAddress = this.Bind();
還有采用var ,并輸入泛型的
var myAddress = this.Bind<Address>();
最後,如果已經建立模型的對象,還可以這樣:
var myAddress = this.BindTo(existingModelInstance);
就我個人而言,我更傾向于第二種。
擴充你的子產品類,添加儲存的處理,代碼如下:
using nancybook.Models;
using Nancy;
using Nancy.ModelBinding;
namespace nancybook.modules
{
public class AddressRoutes : NancyModule
{
public AddressRoutes() : base("/address")
{
Get[@"/"] = _ => View["address/index"];
Post[@"/save"] = _ =>
{
var myAddress = this.Bind<Address>();
return View["address/display", myAddress];
};
}
}
}
然後再添加一個視圖檔案 display.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Nancy Demo | Data Binding Example</title>
<link href="~/content/bootstrap.min.css" rel="stylesheet"
type="text/css" />
</head>
<body>
<div class="container">
<div class="page-header">
<h1 style="display: inline-block">Nancy Demo <small>Data Binding
Example</small></h1>
<h1 style="display: inline-block" class="pull-right"><small><a
href="~/" title="Click to return to demo home page">home <span
class="glyphicon glyphicon-home"></span></a></small></h1>
</div>
<p class="lead">The results from your address form are as
follows...</p>
<p>Record ID : <strong class="textsuccess">@Model.RecordId</strong></p>
<p>Name : <strong class="text-success">@Model.Name</strong></p>
<p>Address : <strong class="textsuccess">@Model.BuildingAddress</strong></p>49
<p>Town : <strong class="text-success">@Model.Town</strong></p>
<p>County : <strong class="text-success">@Model.County</strong></p>
<p>Post Code : <strong class="textsuccess">@Model.PostalCode</strong></p>
<a href="~/address" class="btn btn-primary">Go back to the input
form</a>
</div>
<script src="~/scripts/jquery-2.1.3.min.js"></script>
<script src="~/scripts/bootstrap.min.js"></script>
</body>
</html
編譯運作,輸入位址/address,填寫表單,送出發送資料。
綁定清單和數組
驗證
總結