无法从包含下拉列表的表单绑定POST请求

时间:2013-08-08 15:36:54

标签: razor servicestack

当我发布包含下拉列表的表单时,我收到 RequestBindingException 。此外,服务器返回HTTP 400 Bad Request以及以下POST数据:

Address1:address1
Address2:address2
City:city
County:County
Countries:GB
PostalCode:test123

我不确定我做错了什么。是否可以尝试在ViewModel的构造函数中分配Countries / SelectedCountry属性?如果是这样,我应该如何为这些属性分配初始值/默认值?

或者使用我的ViewModel作为端点参数是不是一个坏主意(它应该是一个单独的dto吗?)

我的ViewModel如下所示:

public class AddressDetailsViewModel
{
    public AddressDetailsViewModel()
    {
        Countries = new List<SelectListItem>
                        {
                            new SelectListItem
                                {
                                    Selected = true,
                                    Text = "United Kingdom",
                                    Value = "GB"
                                }
                        };

        SelectedCountry = new List<SelectListItem>
                        {
                            new SelectListItem
                                {
                                    Selected = true,
                                    Text = "United Kingdom",
                                    Value = "GB"
                                }
                        };
    }
    ...
}

我正在使用Html Helper创建下拉列表:

        <li>
            @Html.LabelFor(x => x.Countries)
            @Html.DropDownListFor(x => x.Countries, Model.SelectedCountry)
        </li>

我的服务端点(不会被点击)看起来像:

public object Post(AddressDetailsViewModel data)
{
    ...
}

1 个答案:

答案 0 :(得分:1)

简短的回答是建议不要将ViewModel用作端点参数,而是设计一个单独的DTO来表示要发送到服务器的message。如果您创建一个干净的消息DTO,它代表您在请求中需要的确切字段,并且请求中的每个字段都具有简单的get / set属性,那么应该更容易将其连接起来并使路由在ServiceStack中工作。 / p>

将视图模型重用为请求消息有一些缺陷:

  • MVC风格的ViewModel非常适合描述在您的网页上显示的内容,但它不一定能很好地代表服务器实际关注的内容
  • 视图模型旨在用于单一目的,简单表示特定类型的视图要显示的内容
  • 另一方面,表示请求消息的DTO可以且通常应该更抽象,表示要在服务器上执行的操作(或者如果您想要RESTful,则表示资源的标识和状态)< / LI>
  • 您的服务可以并且可能应该能够接受来自各种不同客户的特定类型的消息。如果您希望将来使用Ajax请求而不是表单发布在服务器上执行此类操作,该怎么办?或者,如果您希望移动应用程序或第三方客户端与服务集成?单独的消息DTO类描述了服务器上的操作意图而不是反映UI的状态将有助于此处

更具体地说,您获得RequestBindingException的实际原因可能是由于几个因素造成的,例如Countries类中AddressDetailsViewModel属性/字段的声明方式,与声明HTML表单的方式相比,如何为此请求定义路由,等等。在视图模型的构造函数中初始化数据与您看到的400错误无关;我发现这是初始化DTO默认值的好方法。没有看到更多代码就很难分辨。

我建议为POST请求设计一个更简单的DTO类,它只具有服务器真正需要的数据所需的属性。并使用更简单的数据类型 - 字符串和整数而不是SelectListItems或SelectListItems列表。这只会使请求复杂化,并可能涉及您所看到的400错误。