如何从HTTPPOST,字典或?中检索表单值

Ric*_*ard 111 asp.net http-post asp.net-mvc-3

我有一个MVC控制器,具有此操作方法:

[HttpPost]
public ActionResult SubmitAction()
{
     // Get Post Params Here
 ... return something ...
}
Run Code Online (Sandbox Code Playgroud)

表单是一个非常简单的表单,带有一个简单的文本框.

我如何访问参数值?

我不是从View发帖,帖子是外部的.我假设有一组我可以访问的键/值对.

我试过Request.Params.Get("simpleTextBox");但它返回错误"抱歉,处理您的请求时出错".

Dar*_*rov 151

您可以让控制器操作采用反映表单输入名称的对象,默认模型绑定器将自动为您创建此对象:

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

    ... return something ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

    ... return something ...
}
Run Code Online (Sandbox Code Playgroud)

  • 我只想指出您在选项2中丢失了编译器的备份.如果模型更改,编译器将无法捕获相关控制器中的更改.备选方案2有很好的案例,但我不鼓励广泛使用. (5认同)
  • @Goose,因为它是魔法字符串.您没有任何编译时安全性.如果您在变量名称中输入错误,则代码将在运行时失败,而如果您使用强类型,则编译器将成为您的朋友. (3认同)
  • 有时你需要丑陋的东西,当你已经知道什么是最佳实践时有一个选择是件好事 (2认同)

Ade*_*eel 102

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

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

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

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

[HttpPost]
public ActionResult SubmitAction(MyForm form)
{      
  string var1 = form1.Var1;
}
Run Code Online (Sandbox Code Playgroud)


Pio*_*ula 36

答案是非常好的,但在我最喜欢使用的MVC和.NET的最新版本中有另一种方式,而不是"旧学校"FormCollection和Request键.


考虑包含在表单标记中的HTML片段,该标记可以执行AJAX或FORM 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?" />
Run Code Online (Sandbox Code Playgroud)

您的控制器将实际解析表单数据并尝试将其作为已定义类型的参数传递给您.我包括复选框,因为它是一个棘手的.如果选中则返回文本"on",如果未选中则返回null.但要求是这些定义的变量必须存在(除非可以为空(记住它string是可空的))否则AJAX或POST将失败.

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

您也可以在不使用任何剃刀助手的情况下回发模型.我发现有些时候需要这样做.

public Class HomeModel
{
  public int HouseNumber { get; set; }
  public string StreetAddress { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

HTML标记将简单地......

<input type="text" name="variableName.HouseNumber" id="whateverid" >
Run Code Online (Sandbox Code Playgroud)

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

[HttpPost]
public ActionResult PostBack(HomeModel variableName){
    postBack.HouseNumber; //The value user entered
    postBack.StreetAddress; //the default value of NULL.
}
Run Code Online (Sandbox Code Playgroud)

当控制器期望模型时,您不必定义所有字段,因为解析器将它们保留为默认值,通常为NULL.好处是你可以在标记上混合和匹配各种模型,并且后期解析将尽可能地填充.您无需在页面上定义模型或使用任何帮助程序.

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


使用List<>在标记中有点复杂.

<input type="text" name="variableNameHere[0].HouseNumber" id="id"           value="0">
<input type="text" name="variableNameHere[1].HouseNumber" id="whateverid-x" value="1">
<input type="text" name="variableNameHere[2].HouseNumber"                   value="2">
<input type="text" name="variableNameHere[3].HouseNumber" id="whateverid22" value="3">
Run Code Online (Sandbox Code Playgroud)

List <>上的索引必须始终为零和顺序.0,1,2,3.

[HttpPost]
public ActionResult PostBack(List<HomeModel> variableNameHere){
     int counter = MyHomes.Count()
     foreach(var home in MyHomes)
     { ... }
}
Run Code Online (Sandbox Code Playgroud)

使用IEnumerable<>非零基和非循序索引后回来.我们需要添加一个额外的隐藏输入来帮助绑定器.

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

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

<input type="hidden" name="variableNameHere.Index" value="777">
<input type="text" name="variableNameHere[777].HouseNumber" id="id23"    value="5">
Run Code Online (Sandbox Code Playgroud)

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

[HttpPost]
public ActionResult PostBack(IEnumerable<MyModel> variableNameHere){
     int counter = variableNameHere.ToList().Count()
     foreach(var home in variableNameHere)
     { ... }
}
Run Code Online (Sandbox Code Playgroud)

建议每页使用单个模型或ViewModel(模型包含其他模型来创建复杂的"视图"模型).建议的混合和匹配可能被认为是不好的做法,但只要它有效并且可读,它就不是坏事.然而,它确实展示了Razor引擎的强大功能和灵活性.

因此,如果您需要从Razor助手中删除任意内容或覆盖其他值,或者只是不想制作自己的助手,对于使用某些不寻常的数据组合的单个表单,您可以快速使用这些方法来接受额外的数据.

  • 最后有人清楚地解释了它 (3认同)

A-S*_*ani 15

如果你想直接从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]);
}
Run Code Online (Sandbox Code Playgroud)

  • 警告这可能是错误的形式(无双关语),但有时您只需要表单值,而不能彻底更改函数签名。这是这里唯一适合我特定情况的解决方案。 (2认同)