1

当我发布包含下拉列表的表单时,我收到了RequestBindingException 。此外,服务器返回带有以下 POST 数据的 HTTP 400 错误请求:

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

我不确定我做错了什么。是否与尝试在 ViewModel 的构造函数中分配 Country / 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)
{
    ...
}
4

1 回答 1

1

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

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

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

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

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

于 2013-08-09T04:53:47.297 回答