如何从HTTPPOST、字典或?

时间:2021-04-30 13:26:28

I have an MVC controller that has this Action Method:

我有一个MVC控制器有这个动作方法:

[HttpPost]
public ActionResult SubmitAction()
{
     // Get Post Params Here
 ... return something ...
}

The form is a non-trivial form with a simple textbox.

表单是一个具有简单文本框的非平凡形式。

Question

问题

How I access the parameter values?

如何访问参数值?

I am not posting from a View, the post is coming externally. I'm assuming there is a collection of key/value pairs I have access to.

我不是从一个角度发布,而是从外部发布。我假设有一个我可以访问的键/值对集合。

I tried Request.Params.Get("simpleTextBox"); but it returns error "Sorry, an error occurred while processing your request.".

我试着Request.Params.Get(“simpleTextBox”);但它返回错误“对不起,处理请求时发生了错误”。

4 个解决方案

#1


130  

You could have your controller action take an object which would reflect the form input names and the default model binder will automatically create this object for you:

你可以让你的控制器动作选择一个对象,这个对象会反映表单输入名称,默认的模型绑定会自动为你创建这个对象:

[HttpPost]
public ActionResult SubmitAction(SomeModel model)
{
    var value1 = model.SimpleProp1;
    var value2 = model.SimpleProp2;
    var value3 = model.ComplexProp1.SimpleProp1;
    ...

    ... return something ...
}

Another (obviously uglier) way is:

另一种(显然更丑陋的)方式是:

[HttpPost]
public ActionResult SubmitAction()
{
    var value1 = Request["SimpleProp1"];
    var value2 = Request["SimpleProp2"];
    var value3 = Request["ComplexProp1.SimpleProp1"];
    ...

    ... return something ...
}

#2


92  

Simply, you can use FormCollection like:

简单地说,您可以使用FormCollection:

[HttpPost] 
public ActionResult SubmitAction(FormCollection collection)
{
     // Get Post Params Here
 string var1 = collection["var1"];
}

You can also use a class, that is mapped with Form values, and asp.net mvc engine automagically fills it:

你也可以使用一个类,它映射了表单值,asp.net mvc引擎自动填充它:

//Defined in another file
class MyForm
{
  public string var1 { get; set; }
}

[HttpPost]
public ActionResult SubmitAction(MyForm form)
{      
  string var1 = form1.Var1;
}

#3


29  

The answers are very good but there is another way in the latest release of MVC and .NET that I really like to use, instead of the "old school" FormCollection and Request keys.

答案很好,但是在MVC和。net的最新版本中,我有另一种方式,而不是“旧学校”的格式收集和请求键。


Consider a HTML snippet contained within a form tag that either does an AJAX or FORM POST.

考虑一个包含在表单标记中的HTML片段,该标记可以执行AJAX或表单POST。

<input type="hidden"   name="TrackingID" 
<input type="text"     name="FirstName"  id="firstnametext" />
<input type="checkbox" name="IsLegal"  value="Do you accept terms and conditions?" />

Your controller will actually parse the form data and try to deliver it to you as parameters of the defined type. I included checkbox because it is a tricky one. It returns text "on" if checked and null if not checked. The requirement though is that these defined variables MUST exists (unless nullable(remember though that string is nullable)) otherwise the AJAX or POST back will fail.

您的控制器将实际解析表单数据并尝试将其作为定义类型的参数交付给您。我包括了复选框,因为它是一个棘手的问题。如果选中则返回“on”,如果不选中则返回null。但是,要求这些已定义的变量必须存在(除非是可空的(请记住该字符串是可空的)),否则AJAX或POST back将失败。

[HttpPost]
public ActionResult PostBack(int TrackingID, string FirstName, string IsLegal){
    MyData.SaveRequest(TrackingID,FirstName, IsLegal == null ? false : true);
}

You can also post back a model without using any razor helpers. I have come across that this is needed some times.

你也可以不使用任何剃刀助手就回发一个模型。我发现这在某些时候是需要的。

public Class MyModel
{
  public int HouseNumber { get; set; }
  public string StreetAddress { get; set; }
}

The HTML markup will simply be ...

HTML标记将简单地……

<input type="text" name="MyHome.HouseNumber" id="whateverid" >

and your controller(Razor Engine) will intercept the Form Variable "MyHome" and try to build it up and cast it to MyModel.

而您的控制器(Razor Engine)将拦截表单变量“MyHome”并尝试构建它并将其转换为MyModel。

[HttpPost]
public ActionResult PostBack(MyModel MyHome){
    postBack.HouseNumber; //The value user entered
    postBack.StreetAddress; //the default value of NULL.
}

When a controller is expecting a Model you do not have to define ALL the fields as the parser will just leave them at default, usually NULL. The nice thing is you can mix and match various models on the Mark-up and the post back parse will populate as much as possible. You do not need to define a model on the page or use any helpers.

当一个控制器期望一个模型时,您不必定义所有的字段,因为解析器会默认地保留这些字段,通常为空。好处是您可以混合和匹配标记上的各种模型,并且post back parse将尽可能多地填充。您不需要在页面上定义模型或使用任何助手。

TIP: The name of the parameter in the controller is the name defined in the HTML mark-up "name=" not the name of the Model!

提示:控制器中参数的名称是在HTML标记中定义的名称“name=”,而不是模型的名称!


Using List<> is bit more complex in its mark-up.

使用List<>在其标记上要复杂一些。

<input type="text" name="MyHomes[0].HouseNumber" id="id"           value="0">
<input type="text" name="MyHomes[1].HouseNumber" id="whateverid-x" value="1">
<input type="text" name="MyHomes[2].HouseNumber"                   value="2">
<input type="text" name="MyHomes[3].HouseNumber" id="whateverid22" value="3">

Index on List<> MUST always be zero based and sequential. 0,1,2,3.

List<>的索引必须始终为零,并按顺序排列。0、1、2、3。

[HttpPost]
public ActionResult PostBack(List<MyModel> MyHomes){
     int counter = MyHomes.Count()
     foreach(var home in MyHomes)
     { ... }
}

Using IEnumerable<> for non zero based and non sequential indices post back. We need to add an extra hidden input to help the binder.

使用IEnumerable<>,用于非零基和非顺序索引反向。我们需要添加一个额外的隐藏输入来帮助绑定器。

<input type="hidden" name="MyHomes.Index" value="278">
<input type="text" name="MyHomes[278].HouseNumber" id="id"      value="3">

<input type="hidden" name="MyHomes.Index" value="99976">
<input type="text" name="MyHomes[99976].HouseNumber" id="id3"   value="4">

<input type="hidden" name="MyHomes.Index" value="777">
<input type="text" name="MyHomes[777].HouseNumber" id="id23"    value="5">

And the code just needs to use IEnumerable and call ToList()

代码只需要使用IEnumerable并调用ToList()

[HttpPost]
public ActionResult PostBack(IEnumerable<MyModel> MyHomes){
     int counter = MyHomes.ToList().Count()
     foreach(var home in MyHomes)
     { ... }
}

It is recommended to use a single Model or a ViewModel (Model contianing other models to create a complex 'View' Model) per page. Mixing and matching as proposed could be considered bad practice, but as long as it works and is readable its not BAD. It does however, demonstrate the power and flexiblity of the Razor engine.

建议每一页使用一个模型或一个视图模型(模型结合其他模型来创建一个复杂的“视图”模型)。混合和匹配被认为是不好的做法,但是只要它能工作并且可以读它的不坏。不过,它确实展示了剃须刀引擎的力量和灵活性。

So if you need to drop in something arbitrary or override another value from a Razor helper, or just do not feel like making your own helpers, for a single form that uses some unusual combination of data, you can quickly use these methods to accept extra data.

因此,如果您需要插入任意的内容或覆盖来自Razor助手的另一个值,或者只是不想为使用一些不同寻常的数据组合的单个表单创建自己的helper,您可以快速地使用这些方法来接受额外的数据。

#4


8  

If you want to get the form data directly from Http request, without any model bindings or FormCollection you can use this:

如果您想直接从Http请求获取表单数据,而不需要任何模型绑定或FormCollection,您可以使用以下方法:

[HttpPost] 
public ActionResult SubmitAction() {

    // This will return an string array of all keys in the form.
    // NOTE: you specify the keys in form by the name attributes e.g:
    // <input name="this is the key" value="some value" type="test" />
    var keys = Request.Form.AllKeys;

    // This will return the value for the keys.
    var value1 = Request.Form.Get(keys[0]);
    var value2 = Request.Form.Get(keys[1]);
}

#1


130  

You could have your controller action take an object which would reflect the form input names and the default model binder will automatically create this object for you:

你可以让你的控制器动作选择一个对象,这个对象会反映表单输入名称,默认的模型绑定会自动为你创建这个对象:

[HttpPost]
public ActionResult SubmitAction(SomeModel model)
{
    var value1 = model.SimpleProp1;
    var value2 = model.SimpleProp2;
    var value3 = model.ComplexProp1.SimpleProp1;
    ...

    ... return something ...
}

Another (obviously uglier) way is:

另一种(显然更丑陋的)方式是:

[HttpPost]
public ActionResult SubmitAction()
{
    var value1 = Request["SimpleProp1"];
    var value2 = Request["SimpleProp2"];
    var value3 = Request["ComplexProp1.SimpleProp1"];
    ...

    ... return something ...
}

#2


92  

Simply, you can use FormCollection like:

简单地说,您可以使用FormCollection:

[HttpPost] 
public ActionResult SubmitAction(FormCollection collection)
{
     // Get Post Params Here
 string var1 = collection["var1"];
}

You can also use a class, that is mapped with Form values, and asp.net mvc engine automagically fills it:

你也可以使用一个类,它映射了表单值,asp.net mvc引擎自动填充它:

//Defined in another file
class MyForm
{
  public string var1 { get; set; }
}

[HttpPost]
public ActionResult SubmitAction(MyForm form)
{      
  string var1 = form1.Var1;
}

#3


29  

The answers are very good but there is another way in the latest release of MVC and .NET that I really like to use, instead of the "old school" FormCollection and Request keys.

答案很好,但是在MVC和。net的最新版本中,我有另一种方式,而不是“旧学校”的格式收集和请求键。


Consider a HTML snippet contained within a form tag that either does an AJAX or FORM POST.

考虑一个包含在表单标记中的HTML片段,该标记可以执行AJAX或表单POST。

<input type="hidden"   name="TrackingID" 
<input type="text"     name="FirstName"  id="firstnametext" />
<input type="checkbox" name="IsLegal"  value="Do you accept terms and conditions?" />

Your controller will actually parse the form data and try to deliver it to you as parameters of the defined type. I included checkbox because it is a tricky one. It returns text "on" if checked and null if not checked. The requirement though is that these defined variables MUST exists (unless nullable(remember though that string is nullable)) otherwise the AJAX or POST back will fail.

您的控制器将实际解析表单数据并尝试将其作为定义类型的参数交付给您。我包括了复选框,因为它是一个棘手的问题。如果选中则返回“on”,如果不选中则返回null。但是,要求这些已定义的变量必须存在(除非是可空的(请记住该字符串是可空的)),否则AJAX或POST back将失败。

[HttpPost]
public ActionResult PostBack(int TrackingID, string FirstName, string IsLegal){
    MyData.SaveRequest(TrackingID,FirstName, IsLegal == null ? false : true);
}

You can also post back a model without using any razor helpers. I have come across that this is needed some times.

你也可以不使用任何剃刀助手就回发一个模型。我发现这在某些时候是需要的。

public Class MyModel
{
  public int HouseNumber { get; set; }
  public string StreetAddress { get; set; }
}

The HTML markup will simply be ...

HTML标记将简单地……

<input type="text" name="MyHome.HouseNumber" id="whateverid" >

and your controller(Razor Engine) will intercept the Form Variable "MyHome" and try to build it up and cast it to MyModel.

而您的控制器(Razor Engine)将拦截表单变量“MyHome”并尝试构建它并将其转换为MyModel。

[HttpPost]
public ActionResult PostBack(MyModel MyHome){
    postBack.HouseNumber; //The value user entered
    postBack.StreetAddress; //the default value of NULL.
}

When a controller is expecting a Model you do not have to define ALL the fields as the parser will just leave them at default, usually NULL. The nice thing is you can mix and match various models on the Mark-up and the post back parse will populate as much as possible. You do not need to define a model on the page or use any helpers.

当一个控制器期望一个模型时,您不必定义所有的字段,因为解析器会默认地保留这些字段,通常为空。好处是您可以混合和匹配标记上的各种模型,并且post back parse将尽可能多地填充。您不需要在页面上定义模型或使用任何助手。

TIP: The name of the parameter in the controller is the name defined in the HTML mark-up "name=" not the name of the Model!

提示:控制器中参数的名称是在HTML标记中定义的名称“name=”,而不是模型的名称!


Using List<> is bit more complex in its mark-up.

使用List<>在其标记上要复杂一些。

<input type="text" name="MyHomes[0].HouseNumber" id="id"           value="0">
<input type="text" name="MyHomes[1].HouseNumber" id="whateverid-x" value="1">
<input type="text" name="MyHomes[2].HouseNumber"                   value="2">
<input type="text" name="MyHomes[3].HouseNumber" id="whateverid22" value="3">

Index on List<> MUST always be zero based and sequential. 0,1,2,3.

List<>的索引必须始终为零,并按顺序排列。0、1、2、3。

[HttpPost]
public ActionResult PostBack(List<MyModel> MyHomes){
     int counter = MyHomes.Count()
     foreach(var home in MyHomes)
     { ... }
}

Using IEnumerable<> for non zero based and non sequential indices post back. We need to add an extra hidden input to help the binder.

使用IEnumerable<>,用于非零基和非顺序索引反向。我们需要添加一个额外的隐藏输入来帮助绑定器。

<input type="hidden" name="MyHomes.Index" value="278">
<input type="text" name="MyHomes[278].HouseNumber" id="id"      value="3">

<input type="hidden" name="MyHomes.Index" value="99976">
<input type="text" name="MyHomes[99976].HouseNumber" id="id3"   value="4">

<input type="hidden" name="MyHomes.Index" value="777">
<input type="text" name="MyHomes[777].HouseNumber" id="id23"    value="5">

And the code just needs to use IEnumerable and call ToList()

代码只需要使用IEnumerable并调用ToList()

[HttpPost]
public ActionResult PostBack(IEnumerable<MyModel> MyHomes){
     int counter = MyHomes.ToList().Count()
     foreach(var home in MyHomes)
     { ... }
}

It is recommended to use a single Model or a ViewModel (Model contianing other models to create a complex 'View' Model) per page. Mixing and matching as proposed could be considered bad practice, but as long as it works and is readable its not BAD. It does however, demonstrate the power and flexiblity of the Razor engine.

建议每一页使用一个模型或一个视图模型(模型结合其他模型来创建一个复杂的“视图”模型)。混合和匹配被认为是不好的做法,但是只要它能工作并且可以读它的不坏。不过,它确实展示了剃须刀引擎的力量和灵活性。

So if you need to drop in something arbitrary or override another value from a Razor helper, or just do not feel like making your own helpers, for a single form that uses some unusual combination of data, you can quickly use these methods to accept extra data.

因此,如果您需要插入任意的内容或覆盖来自Razor助手的另一个值,或者只是不想为使用一些不同寻常的数据组合的单个表单创建自己的helper,您可以快速地使用这些方法来接受额外的数据。

#4


8  

If you want to get the form data directly from Http request, without any model bindings or FormCollection you can use this:

如果您想直接从Http请求获取表单数据,而不需要任何模型绑定或FormCollection,您可以使用以下方法:

[HttpPost] 
public ActionResult SubmitAction() {

    // This will return an string array of all keys in the form.
    // NOTE: you specify the keys in form by the name attributes e.g:
    // <input name="this is the key" value="some value" type="test" />
    var keys = Request.Form.AllKeys;

    // This will return the value for the keys.
    var value1 = Request.Form.Get(keys[0]);
    var value2 = Request.Form.Get(keys[1]);
}