其他分享
首页 > 其他分享> > CodeGo.net>您可以使一个MVC Post操作仅接受表单数据而不接受querystring

CodeGo.net>您可以使一个MVC Post操作仅接受表单数据而不接受querystring

作者:互联网

我正在使用ASP MVC 5,因此对控制器有操作

[HttpPost()]
public ActionResult MyMethod(string param)
{
    // Action code here
}

我需要它仅从表单数据而不是从查询字符串接受它的数据“参数”.

所以这样的事情应该工作

<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中的模型绑定过程考虑了称为“值提供程序”的值.这些是接口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-net-mvc-5,c,asp-net-mvc
来源: https://codeday.me/bug/20191120/2045948.html