我在尝试使用WebClient对MVC 2控制器进行HTTP PUT(或POST)时遇到了一些问题。例外是:
The parameters dictionary contains a null entry for parameter 'total'
of non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult Company(System.Guid, Int32, Int32, System.String)'
控制器操作是:
[HttpPut]
public ActionResult Company(Guid uid, int id, int total, string url)
路线是:
routes.MapRoute(
"CompanySet",
"job/active/{uid}/company/{id}",
new { controller = "Job", action = "Company" }
);
客户端代码是:
var putData = Encoding.ASCII.GetBytes("total=919&url=test");
var client = new WebClient();
client.UploadData("http://localhost/job/active/1/company/2", "PUT", putData);
正如您所看到的,我想要的是发送' uid '和' id '参数通过网址,和'总计'和'网址'参数作为 PUT 或 POST <的一部分强>体
我还尝试将后面的参数合并到一个类(即CompanySetMessage)中,不再引发异常,但我没有收到服务器端的值。
有什么想法吗?谢谢!
答案 0 :(得分:3)
首先,您需要设置PUT或POST ActionMethodSelectorAttribute
:
[HttpPut] // <- ActionMethodSelectorAttribute
public ActionResult Company(Guid uid, int id, int total, string url)
{ // TODO: Bananas }
示例:
使用视图中的表单和每个请求的单独方法解决问题(ASP.NET MVC架构中首选):
修改公司方法
public ActionResult Company(int id)
{
return View(companyData.Single(x => x.Id == id)); // The filter can be anything
}
POST操作方法
[HttpPost]
[ActionName("Company")] // <- Allows to create multiple Actions with the same parameters which also refer to the same ActionName
public ActionResult Company_Post(Guid uid, int id, int total, string url)
{
return Content(
String.Format("POST Values:<br />Guid: {0}<br /> Id: {1}<br /> Total: {2}<br /> Url: {3}", uid, id, total, url)
);
}
POST查看代码(这是“公司”类型的强类型视图)
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.Uid) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Uid)%>
<%: Html.ValidationMessageFor(model => model.Uid)%>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Id) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Id) %>
<%: Html.ValidationMessageFor(model => model.Id) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Total) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Total) %>
<%: Html.ValidationMessageFor(model => model.Total) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Url) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Url) %>
<%: Html.ValidationMessageFor(model => model.Url) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
POST输出
POST Values:
Guid: 12345678-1234-1234-1234-123456789012
Id: 1
Total: 10
Url: #1
如您所见,所有值都会发送回控制器。 (无需先收集/初始化它们)
PUT行动方法
[HttpPut]
[ActionName("Company")] // <- Allows to create multiple Actions with the same parameters which also refer to the same ActionName
public ActionResult Company_Put(Guid uid, int id, int total, string url)
{
return Content(
String.Format("PUT: Values:<br />Guid: {0}<br /> Id: {1}<br /> Total: {2}<br /> Url: {3}", uid, id, total, url)
);
}
PUT查看代码(与上面相同,只是略有改变
<% using (Html.BeginForm()) {%>
<%: Html.HttpMethodOverride(HttpVerbs.Put) %> // <- Only this one is new, it renders a different form
<%: Html.ValidationSummary(true) %>
...
PUT查看呈现的HTML代码
<form action="/dataentry/Company/1" method="post"><input name="X-HTTP-Method-Override" type="hidden" value="PUT" />
PUT输出
PUT: Values:
Guid: 12345678-1234-1234-1234-123456789012
Id: 1
Total: 10
Url: #1
这将是从控制器和视图来回发送数据的强类型和更安全的方式。 发布/放置值的映射由MVC框架自动完成。因此,如果您需要更改域模型中的某些内容,则只需将新字段添加到视图中并调整方法参数。
即使它不是你想要的,我仍然认为把它写在某处并不是那么糟糕: - )。
答案 1 :(得分:0)
没关系,显然这是客户端的问题,而不是服务器端。
我刚刚改变了
client.UploadData
的
client.UploadValues
使用NameValueCollection,现在它正常工作。