MVC强类型视图,并在发送到较低层之前设置服务器端属性



我有一个分层应用程序,它向业务层发送命令(实际上,该应用程序基于ncqrs框架,但我认为它在这里不重要)。

命令看起来像这样:

public class RegisterUserCommand : CommandBase
{
    public string UserName { get; set; }
    public string Email{ get; set; }
    public DateTime RegistrationDate { get; set; }
    public string ApiKey {get; set;} // edit
}

这个类没有逻辑,只有数据。

我想让用户输入他们的用户名,电子邮件,我想让系统使用当前日期来构建命令。

  1. 创建一个基于RegisterUserCommand的强类型视图,然后在将其发送到业务层之前注入日期和APi Key ?

  2. 创建一个RegisterUserViewModel类,用这个类创建视图,并根据视图输入创建命令对象

我写了以下代码(对于解决方案n°2):

public class RegisterController : Controller
{
    //
    // GET: /Register/
    public ActionResult Index()
    {
        return View();
    }
    [HttpPost]
    public ActionResult Index(RegisterUserViewModel registrationData)
    {
        var service = NcqrsEnvironment.Get<ICommandService>();
        service.Execute(
            new RegisterUserCommand
            {
                RegistrationDate = DateTime.UtcNow,
                Email= registrationData.Email,
                UserName= registrationData.Name,
                ApiKey = "KeyFromConfigSpecificToCaller" // edit
            }
            );
        return View();
    }

    public class RegisterUserViewModel
    {
        [Required]
        [StringLength(16)]
        public string Name { get; set; }
        [Required]
        [StringLength(64)]
        public string Email{ get; set; }
    }
}

这个代码正在工作…但我想知道我是否选择了正确的方式…

thanks for advice

[Edit]由于日期时间似乎引起误解,我添加了另一个属性"ApiKey",这也应该设置服务器端,从web层(而不是从命令层)

[Edit 2]尝试Erik的建议并实现我想象的第一个解决方案:

[HttpPost]
public ActionResult Index(RegisterUserCommand registrationCommand)
{
    var service = NcqrsEnvironment.Get<ICommandService>();
    registrationCommand.RegistrationDate = DateTime.UtcNow;
    registrationCommand.ApiKey = "KeyFromConfigSpecificToCaller";
    service.Execute(
        registrationCommand
        );
    return View();
}

我认为你最好选择#2,在那里你会有一个单独的ViewModel和一个命令。虽然它可能看起来是多余的(在某种程度上),你的命令实际上是从你的web服务器到你的命令处理程序的消息。这些消息的格式可能与ViewModel不同,也不应该如此。如果你按原样使用NCQRS,那么你就必须将你的命令映射到你的AR方法和构造函数。

虽然它可能会节省你一点时间,我认为你把自己归类为在你的ViewModels之后建模你的领域,这不应该是这样的。你的ViewModels应该反映你的用户体验和看到的东西;您的领域应该是您的业务规则和知识的反映,而不是总是反映在您的视图中。

现在看起来似乎要做更多的工作,但请帮自己一个忙,将命令与视图模型分开。你以后会感谢自己的。

我希望这对你有帮助。好运!

我建议将其放入RegisterUserCommand类的构造函数中。这样,默认行为总是将其设置为DateTime。UtcNow,如果你需要显式地设置它你可以把它添加到对象初始化器。当你在项目的其他部分使用这个类,而你忘记显式地设置RegistrationDate时,这也会有帮助。

public class RegisterUserCommand : CommandBase
{
    public string UserName { get; set; }
    public string Email{ get; set; }
    public DateTime RegistrationDate { get; set; }
    public RegisterUserCommand()
    {
        RegistrationDate = DateTime.UtcNow;
    }
}

和Controller

public class RegisterController : Controller
{
    //
    // GET: /Register/
    public ActionResult Index()
    {
        return View();
    }
    [HttpPost]
    public ActionResult Index(RegisterUserViewModel registrationData)
    {
        var service = NcqrsEnvironment.Get<ICommandService>();
        service.Execute(
            new RegisterUserCommand
            {
                Email= registrationData.Email,
                OpenIdIdentifier = registrationData.OpenIdIdentifier
            }
            );
        return View();
    }

    public class RegisterUserViewModel
    {
        [Required]
        [StringLength(16)]
        public string Name { get; set; }
        [Required]
        [StringLength(64)]
        public string Email{ get; set; }
    }
}

我将使用第1条,并使用system.componentmodel.dataannotations.metadatatype进行验证。

我为另一个SO问题创建了一个示例(答案)。

这允许您将模型保存在另一个库中,验证字段并显示字段,就像您使用DataAnnotations处理内部/私有类一样。我不太喜欢为一个视图创建一个完全独立的类,因为它没有额外的价值,同时必须将数据ORM返回到另一个类。(如果你有额外的值,如下拉列表值,或默认值,那么我认为这是有意义的)。

不是

[HttpPost]
public ActionResult Index(RegisterUserViewModel registrationData)
{
    var service = NcqrsEnvironment.Get<ICommandService>();
    service.Execute(
        new RegisterUserCommand
        {
            RegistrationDate = DateTime.UtcNow,
            Email= registrationData.Email,
            UserName= registrationData.Name,
            ApiKey = "KeyFromConfigSpecificToCaller" // edit
        }
        );
    return View();
}

你可以有

[HttpPost]
public ActionResult Index(RegisterUserCommand registrationData)
{
    var service = NcqrsEnvironment.Get<ICommandService>();
    registrationData.ApiKey = "KeyFromConfigSpecificToCaller";
    service.Execute(registrationData);
    return View();
}

相关内容

  • 没有找到相关文章

最新更新