Model binding(模型绑定)
方法:
Foo foo = this.Bind();
var foo = this.Bind<Foo>();
var foo = this.BindTo(instance);
下面直接来看一个Nancy模型绑定的例子吧:
Module:
using CoreNancy.Models;
using Nancy;
using Nancy.ModelBinding;
using Nancy.Security;
namespace CoreNancy.Module
{
public class NancyModelModule : NancyModule
{
public NancyModelModule()
{
Get("/Register", p =>
{
//already logged in
if (Context.CurrentUser.IsAuthenticated())
return Response.AsRedirect("~/");
return View["Register.html"];
});
Post("/Register", async (x, ct) =>
{
ModelUser user = this.Bind<ModelUser>(); //model binding!
if (string.IsNullOrEmpty(user.UserName) || string.IsNullOrEmpty(user.Email) || string.IsNullOrEmpty(user.Password))
{
return "Parameter is null";
}
else
{
bool ret = this.DoRegister(user);
if (ret)
{
return string.Format("Register Success : {0}", user.UserName);
}
else
{
return string.Format("Unable to register as {0} - server error.", user.UserName);
}
}
});
}
private bool DoRegister(ModelUser user)
{
//todo:调用业务层执行用户注册
bool registerResult = true;
return registerResult;
}
}
}
Model:
namespace CoreNancy.Models
{
public class ModelUser
{
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
}
View:
<div class="container-fluid">
<div class="row-fluid">
<h1>Nancy Model Test</h1>
<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>
运行结果:
黑名单:
如果只想要绑定部分有用的属性,需要忽略某些属性时,可以将要忽略的属性加入黑名单来调用模型绑定器:
var foo = this.Bind<Foo>(f => f.Email, f => f.Password);
or
var foo = this.Bind<Foo>("Email", "Password");
我们来实际操作一下:
ModelUser user = this.Bind<ModelUser>(p => p.Password, p => p.Email); //model binding!
属性或字段
Nancy的模型绑定支持字段或属性,也就是说我们封装模型的时候可以选择定义属性,也可以定义字段:
// Properties
public class Model
{
public int Value { get; set; }
}
// Fields
public class Model
{
public int Value;
}
绑定复选框
对于自动模型绑定复选框到布尔值,需要确保在复选框中设置value=“true”。
<input type="checkbox" name="rememberMe" value="true"/>
public class LoginModel
{
public bool RememberMe;
}
绑定数组
<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>();
绑定多个对象
<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 />
<input type="submit" value="Test the binding thingy"/>
</form>
this.Bind<List<ModelUser>>();
绑定配置(Binding configuration):
使用模型绑定时,可以传入BindingConfig实例以修改模型绑定器的行为。
BindingConfig bindingConfig = new BindingConfig()
{
BodyOnly = false,
IgnoreErrors = true,
Overwrite = true
};
ModelUser user = this.Bind<ModelUser>(bindingConfig); //model binding!
//ModelUser user = this.Bind<ModelUser>(bindingConfig, p => p.Password, p => p.Email); //model binding!
BindingConfig属性说明:
属性 | 说明 | 默认值 |
---|---|---|
BodyOnly | 一旦绑定到请求主体,绑定器是否应该是幸福的。 在这种情况下,请求和上下文参数将不受约束。 如果没有正文并且启用了此选项,则根本不会发生任何绑定。 | false |
IgnoreErrors | 是否应忽略绑定错误,并且绑定程序应继续使用下一个属性或字段。 | false |
Overwrite | 是否允许绑定器覆盖没有默认值的属性和字段。 | true |
反序列化(Deserializing rich request body payloads)
Nancy附带了两个主体反序列化器,一个用于JSON,另一个用于XML。模型绑定器将使用Content-Type HTTP标头来确定应该为附加的请求主体使用哪个解串器。
与其他模型绑定器一样,我们可以创建自己的主体反序列化器,Nancy将自动检测它们,并且任何用户定义的绑定器优先于内置的绑定器。
注意:如果由于有效负载过高而遇到Nancy.Json.JsonSettings.MaxJsonLength Exceeded错误,请将ApplicationStartup中的Bootstrapper中的限制更改为Nancy.Json.JsonSettings.MaxJsonLength = int.MaxValue。