原文地址 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_1,Name_2etc.)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"];
}
};
}
}
转载于:https://blog.51cto.com/soaop/1703741
本文详细阐述了Nancy框架下模型绑定的概念,包括属性与字段的区别及使用场景,模型绑定到复选框、列表的具体实现,并通过一个完整的实例展示了从视图、模块到绑定过程的实现细节。
38

被折叠的 条评论
为什么被折叠?



