将url params和POST body发送到MVC 2 Controller

时间:2010-05-25 03:35:08

标签: http url post asp.net-mvc-2 parameters

我在尝试使用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)中,不再引发异常,但我没有收到服务器端的值。

有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:3)

首先,您需要设置PUTPOST 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,现在它正常工作。