天天看點

NancyFX 第七章 模型綁定和驗證

   任何優秀的架構,都能傳遞參數。在之前的路由章節,我們已經看到了如何在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對象時,就能獲得其中的五個屬性:

NancyFX 第七章 模型綁定和驗證

   正如你在上圖中看到的,你可以在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,能看到下面的樣子:

NancyFX 第七章 模型綁定和驗證

由三種不同的綁定方式,比較典型的如下:

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,填寫表單,送出發送資料。

NancyFX 第七章 模型綁定和驗證

    綁定清單和數組

    驗證

    總結