8 Model binding 模型綁定(下)(Nancy 官方文檔翻譯)

原文地址 https://github.com/NancyFx/Nancy/wiki/Model-binding

字段的屬性

模型綁定支持字段或屬性兩種方式,使用模型綁定,可以通過下面的方式實現綁定:

// Properties
public class Model{  
    public int Value { get; set; }
}
// Fields
public class Model{
    public int Value;
}

每個類有自己的參數方式。使用屬性意味着你需要後續的操作中使用數據驗證或者增強的功能,你的代碼已經通過get 訪問器調用一個方法, 並且你可以改變這個方法的實現。 換一種說法, 當屬性沒有明確的使用方式 (就像上面示例中的-- 沒有提供實際的 get 和set 訪問器), C# 編譯器根據名稱通過隱含的操作自動地獲取對應字段的值。 這個字段名需要唯一,以防止和其它成員名衝突。爲了實現這個目的,不可使用的C#特殊標識符。特別地如包含了尖括號。如果數據類型使用了 DataContractSerializer, 將會引發這個結果,因爲 DataContractSerializer 操作針對字段,而不是屬性。它會使用相同的名字獲取字段和嘗試創建XML元素。因爲XML元素不能包括 < 和> 字符,將會引發異常, 在內部的處理會對字段名進行轉義。 (異常可以在運行使用DataContractSerializer的程序時通過調試輸出查看,常見的情況通常是默認WCF綁定配置中。) 異常和轉換並不是必須要執行,你可以通過使用符合的XML標識的字段避免它。

除非你的項目有外部組件引用了它,你使用那種方式無關緊要,因爲大多數.net訪問屬性和字段的語法完全相同的。因此,在大多數情況下, 你可以更改你的模型類型,使用屬性或者字段,編譯時無需做其他修改。

  模型綁定到複選框

對於自動模型綁定到複選框的布爾值,確定設置了value="true" 在複選框中。

<input type="checkbox" name="rememberMe" value="true"/>
public class LoginModel{
    public bool RememberMe;
}

  模型綁定到列表

Nancy支持服務端提交列表形式的東東並且綁定他們,就像之前使用this.Bind<T>()的方式。

Nancy使用兩種方式支持綁定列表項(或者數組及其他可以實現可枚舉的類型),作爲你綁定到的那個對象的列表或通用對象的列表。

 將數組綁定到一個簡單對象

如果你有類似下面的表單:

<form action="/ArrayOnObject" method="post">
  <input type="text" name="Tags" value="Tag1,Tag2,Tag3"/>
  <input type="text" name="Ints" value="1,2,3,4,4,5,6,3,2,21,1"/>
  <input type="submit" value="Submit"/>
</form>

你可以綁定到下面的類:

public class Posts{
  public string[] Tags;
  public int[] Ints;
}

使用這樣的語句:

var listOfPosts = this.Bind<Posts>();

 將列表綁定到包含對象的List中

Imagine you have a system to enter who commits the most to a OSS-framework. You allow the users of the site to post a bunch of users-names and their number of commits at once.

Here's an example form with random dummy data:

<form action="/SimpleListDemo" method="post">
      User 1:<input type="text" name="Name[0]" value="thecodejunkie" /> 
      Commits <input type="text" name="Commits[0]" value="1068"/>
      <br />
      User 2:<input type="text" name="Name[1]" value="grumpydev" />  
      Commits <input type="text" name="Commits[1]" value="1049"/>
      <br />
      User 3:<input type="text" name="Name[2]" value="jchannon" />  
      Commits <input type="text" name="Commits[2]" value="109"/>
      <br />
      User 4:<input type="text" name="Name[3]" value="prabirshrestha" />  
      Commits <input type="text" name="Commits[3]" value="75"/>
      <br />
      User 5:<input type="text" name="Name[4]" value="phillip-haydon" />  
      Commits <input type="text" name="Commits[4]" value="40"/>
      <br />
      <input type="submit" value="Test the binding thingy"/>
</form>

This can then be bound (with this.Bind<List<User>>();) to a list of object of this class:

public class User{
   public string Name; 
   public int Commits;
}

 HTML表單中的列表標記

Nancy supports two kind of list delimiters for the name of the items in the HTML-form;

  • underscores (Name_1Name_2 etc.)

  • brackets (Name[1]Name[2] etc.)


 一個完整的模型綁定的示例

Here's an end-to-end model binding example that shows the full model + view + module.

/// <summary>
/// DTO for creating a new user
/// </summary>
public class NewUser
{
    public string UserName { get; set; }

    public string Email { get; set; }

    public string Password { get; set; }
}

  視圖文件(View)

    ViewBag.Title = "AkkaChat - Register";
}
@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<AkkaChat.ViewModels.NewUser>

<div class="container-fluid">
    <div class="row-fluid">
        <h1>Register an AkkaChat Account</h1>
        @if (ViewBag.ValidationError != null)
        {
            <div class="alert-error">
                <p>Error! @ViewBag.ValidationError</p>
            </div>
        }

        <form class="form-horizontal" method="POST" action="~/register">
            <div class="control-group">
                <label class="control-label" for="UserName">Username</label>
                <div class="controls">
                    <input type="text" name="UserName"  id="UserName" placeholder="Username">
                </div>
            </div>

            <div class="control-group">
                <label class="control-label" for="Email">Email</label>
                <div class="controls">
                    <input type="text" id="Email" name="Email" placeholder="Email">
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="Password">Password</label>
                <div class="controls">
                    <input type="password" name="Password" id="Password" placeholder="Password">
                </div>
            </div>
            <div class="control-group">
                <div class="controls">
                    <button type="submit" class="btn">Register</button>
                </div>
            </div>
        </form>

    </div>
</div>

  模塊文件(Module)

/// <summary>/// Module responsible for handling authentication and account creation/// </summary>public class AuthModule : NancyModule{    private readonly IMembershipService _membership;    public AuthModule(IMembershipService membership)
    {
        _membership = membership;

        Get["/register"] = _ =>
        {            //already logged in
            if (Context.CurrentUser.IsAuthenticated())                return Response.AsRedirect("~/");            return View["register"];
        };

        Post["/register", true] = async (x, ct) =>
        {
            NewUser registerAttempt = this.Bind<NewUser>(); //model binding!
            var validationError = "";            var failedValidation = false;             if (string.IsNullOrEmpty(registerAttempt.UserName))
             {
                 failedValidation = true;
                 validationError += string.Format("Must provide a username!<br>");
             }             else
             {                 //check to see if a username is available
                 var userNameAvailable = await _membership.IsUserNameAvailable(registerAttempt.UserName);                 if (!userNameAvailable)
                 {
                     validationError += string.Format("{0} is already taken. Please pick another username.<br>",
                         registerAttempt.UserName);
                     failedValidation = true;
                 }
             }             if (string.IsNullOrEmpty(registerAttempt.Password))
             {
                 failedValidation = true;
                 validationError += string.Format("Must provide a password!<br>");
             }             if (string.IsNullOrEmpty(registerAttempt.Email))
             {
                 failedValidation = true;
                 validationError += string.Format("Must provide an email!<br>");
             }             if (failedValidation)
             {
                 ViewBag.ValidationError = validationError;                 return View["register"];
             }            var registerResult = await _membership.AddUser(
            registerAttempt.UserName, registerAttempt.Email, registerAttempt.Password);           //success!
            if (!(registerResult is MissingUserIdentity))
            {                return this.LoginAndRedirect(registerResult.CookieId, DateTime.Now.AddDays(30), "~/");
            }            else //failure!
            {
                ViewBag.ValidationError = string.Format("Unable to register as {0} - server error.",
                 registerAttempt.UserName);                return View["register"];
            }

        };

    }
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章