你能让 MVC Post 动作只接受表单数据而不接受查询字符串吗
Can you make an MVC Post action only accept form data and not querystring
我正在使用 ASP MVC 5 并且我在我的控制器上有一个动作
[HttpPost()]
public ActionResult MyMethod(string param)
{
// Action code here
}
我需要它来接受它的数据 "param" 仅来自表单数据,而不是来自查询字符串。
所以像这样的东西应该可以工作
<form method="post" action="http://localhost/Home/MyMethod">
<input type="hidden" name="param" value="MyValue" />
<input type="submit" value="Post with token" />
</form>
虽然这不应该(很高兴找不到动作,或者通过提供空模型找到动作)。
<form method="post" action="http://localhost/Home/MyMethod?param=MyValue">
<input type="submit" value="submit" />
</form>
我看过一些自定义模型活页夹
public class FormOnlyModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
/*
* http://blogs.msdn.com/b/jmstall/archive/2012/04/20/how-to-bind-to-custom-objects-in-action-signatures-in-mvc-webapi.aspx
* Add [ModelBinder(typeof(FormOnlyModelBinder))] to parameter
* e.g. public ActionResult RetreiveBill([ModelBinder(typeof(CModelBinder))] string token)
* In controllerContext.RequestContext.HttpContext.Request you can see the type, and if the data is in q query string or forms data.
* Just not sure if this is reliable
*/
throw new NotImplementedException();
}
}
但真的不知道从这里到哪里去,或者这是否是做这类事情的可靠方法。
MVC 中的模型绑定过程考虑了称为 Value Providers 的东西。这些是接口 IValueProvider
的实现,其中有一些实现了不同的数据源:FormValueProvider
、RouteDataValueProvider
、QueryStringValueProvider
、HttpFileCollectionValueProvider
。
默认情况下,模型绑定过程会将它们全部考虑在内,但有一些方法可以限制使用哪些。
手动调用模型绑定过程指定应使用哪个值提供程序
public ActionResult MyMethod()
{
var model = new MyModel();
if (TryUpdateModel(model, new FormValueProvider(this.ControllerContext)))
{
//proceed with post action
}
//validation errors, display same form
return View(model);
}
将类型为 FormCollection
的参数添加到您的控制器操作,并使用该参数作为值提供程序手动调用模型绑定。 FormCollection
通过仅查看表单参数来实现 IValueProvider
,因此它与上面的选项相同(但使您不必创建值提供程序实例)
public ActionResult MyMethod(FormCollection formData)
{
var model = new MyModel();
if (TryUpdateModel(model, formData))
{
//proceed with post action
}
//validation errors, display same form
return View(model);
}
创建一个仅使用 FormValueProvider
作为其值提供者的模型绑定器。这允许您像往常一样编写控制器操作方法(无需手动调用模型绑定)
public class FormOnlyModelBinder: DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ModelBindingContext newBindingContext = new ModelBindingContext()
{
ModelMetadata = bindingContext.ModelMetadata,
ModelName = bindingContext.ModelName,
ModelState = bindingContext.ModelState,
PropertyFilter = bindingContext.PropertyFilter,
FallbackToEmptyPrefix = bindingContext.FallbackToEmptyPrefix,
ValueProvider = new FormValueProvider(controllerContext),
};
return base.BindModel(controllerContext, newBindingContext);
}
}
所有这些选项都具有相同的效果。仅当我对非常特殊的操作有此要求时,我才会使用第二个选项,在任何其他情况下,我可能会使用自定义模型活页夹。
我正在使用 ASP MVC 5 并且我在我的控制器上有一个动作
[HttpPost()]
public ActionResult MyMethod(string param)
{
// Action code here
}
我需要它来接受它的数据 "param" 仅来自表单数据,而不是来自查询字符串。
所以像这样的东西应该可以工作
<form method="post" action="http://localhost/Home/MyMethod">
<input type="hidden" name="param" value="MyValue" />
<input type="submit" value="Post with token" />
</form>
虽然这不应该(很高兴找不到动作,或者通过提供空模型找到动作)。
<form method="post" action="http://localhost/Home/MyMethod?param=MyValue">
<input type="submit" value="submit" />
</form>
我看过一些自定义模型活页夹
public class FormOnlyModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
/*
* http://blogs.msdn.com/b/jmstall/archive/2012/04/20/how-to-bind-to-custom-objects-in-action-signatures-in-mvc-webapi.aspx
* Add [ModelBinder(typeof(FormOnlyModelBinder))] to parameter
* e.g. public ActionResult RetreiveBill([ModelBinder(typeof(CModelBinder))] string token)
* In controllerContext.RequestContext.HttpContext.Request you can see the type, and if the data is in q query string or forms data.
* Just not sure if this is reliable
*/
throw new NotImplementedException();
}
}
但真的不知道从这里到哪里去,或者这是否是做这类事情的可靠方法。
MVC 中的模型绑定过程考虑了称为 Value Providers 的东西。这些是接口 IValueProvider
的实现,其中有一些实现了不同的数据源:FormValueProvider
、RouteDataValueProvider
、QueryStringValueProvider
、HttpFileCollectionValueProvider
。
默认情况下,模型绑定过程会将它们全部考虑在内,但有一些方法可以限制使用哪些。
手动调用模型绑定过程指定应使用哪个值提供程序
public ActionResult MyMethod() { var model = new MyModel(); if (TryUpdateModel(model, new FormValueProvider(this.ControllerContext))) { //proceed with post action } //validation errors, display same form return View(model); }
将类型为
FormCollection
的参数添加到您的控制器操作,并使用该参数作为值提供程序手动调用模型绑定。FormCollection
通过仅查看表单参数来实现IValueProvider
,因此它与上面的选项相同(但使您不必创建值提供程序实例)public ActionResult MyMethod(FormCollection formData) { var model = new MyModel(); if (TryUpdateModel(model, formData)) { //proceed with post action } //validation errors, display same form return View(model); }
创建一个仅使用
FormValueProvider
作为其值提供者的模型绑定器。这允许您像往常一样编写控制器操作方法(无需手动调用模型绑定)public class FormOnlyModelBinder: DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ModelBindingContext newBindingContext = new ModelBindingContext() { ModelMetadata = bindingContext.ModelMetadata, ModelName = bindingContext.ModelName, ModelState = bindingContext.ModelState, PropertyFilter = bindingContext.PropertyFilter, FallbackToEmptyPrefix = bindingContext.FallbackToEmptyPrefix, ValueProvider = new FormValueProvider(controllerContext), }; return base.BindModel(controllerContext, newBindingContext); } }
所有这些选项都具有相同的效果。仅当我对非常特殊的操作有此要求时,我才会使用第二个选项,在任何其他情况下,我可能会使用自定义模型活页夹。