servicestack,Razor,servicestack" /> servicestack,Razor,servicestack" />

Razor 无法从包含dropdownlist的表单绑定POST请求

Razor 无法从包含dropdownlist的表单绑定POST请求,razor,servicestack,Razor,servicestack,当我发布一个包含dropdownlist的表单时,我得到了一个RequestBindingException。此外,服务器返回HTTP 400错误请求,其中包含以下POST数据: Address1:address1 Address2:address2 City:city County:County Countries:GB PostalCode:test123 我不确定我做错了什么。这可能与试图在ViewModel的构造函数中分配Countries/SelectedCountry属性有关吗?如

当我发布一个包含dropdownlist的表单时,我得到了一个RequestBindingException。此外,服务器返回HTTP 400错误请求,其中包含以下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"
                                }
                        };
    }
    ...
}

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

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

  • MVC风格的ViewModel非常适合描述在web页面上显示的内容,但它不一定能很好地表示服务器真正关心的内容
  • 视图模型是单一用途的,是特定类型视图希望显示内容的简单表示
  • 另一方面,表示请求消息的DTO可以而且通常应该更抽象,表示您希望在服务器上执行的操作(或者,如果希望是RESTful的,则表示资源的标识和状态)
  • 您的服务可以而且可能应该能够接受来自各种不同客户端的给定类型的消息。如果将来您希望在服务器上使用Ajax请求而不是表单post执行此类操作,该怎么办?或者如果您希望移动应用程序或第三方客户端与该服务集成?一个单独的MessageDTO类描述服务器上操作的意图,而不是反映UI的状态,在这里会有所帮助
更具体地说,您获得
RequestBindingException
的实际原因可能是由两个因素造成的,例如在
AddressDetailsViewModel
类中如何声明您的
Countries
属性/字段,与HTML表单的声明方式相比,如何为此请求定义路由,等等。在视图模型的构造函数中初始化数据应该与您看到的400错误无关;我发现这是初始化DTO默认值的好方法。如果看不到更多的代码,很难说


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

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

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

  • MVC风格的ViewModel非常适合描述在web页面上显示的内容,但它不一定能很好地表示服务器真正关心的内容
  • 视图模型是单一用途的,是特定类型视图希望显示内容的简单表示
  • 另一方面,表示请求消息的DTO可以而且通常应该更抽象,表示您希望在服务器上执行的操作(或者,如果希望是RESTful的,则表示资源的标识和状态)
  • 您的服务可以而且可能应该能够接受来自各种不同客户端的给定类型的消息。如果将来您希望在服务器上使用Ajax请求而不是表单post执行此类操作,该怎么办?或者如果您希望移动应用程序或第三方客户端与该服务集成?一个单独的MessageDTO类描述服务器上操作的意图,而不是反映UI的状态,在这里会有所帮助
更具体地说,您获得
RequestBindingException
的实际原因可能是由两个因素造成的,例如在
AddressDetailsViewModel
类中如何声明您的
Countries
属性/字段,与HTML表单的声明方式相比,如何为此请求定义路由,等等。在视图模型的构造函数中初始化数据应该与您看到的400错误无关;我发现这是初始化DTO默认值的好方法。如果看不到更多的代码,很难说


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

这也是我最终得出的结论,并最终走上了这条路线。你的观点解释得很好,帮助我理解为什么这是一个更好的方法。很高兴听到。每当我在处理ServiceStack REST API项目时遇到设计复杂性时,解决方案通常是“简化DTO,尊重基于消息的设计”。这就像一个咒语。这也是我最终得出的结论,并最终走上了这条路。你的观点得到了很好的解释和帮助
        <li>
            @Html.LabelFor(x => x.Countries)
            @Html.DropDownListFor(x => x.Countries, Model.SelectedCountry)
        </li>
public object Post(AddressDetailsViewModel data)
{
    ...
}