c# - 这是 MVC 反模式吗?

标签 c# asp.net-mvc-3 design-patterns response dto

我对任何类型的 .NET Web 开发都很陌生(到目前为止,我主要使用 Winforms 和服务。)我已经开始与另外两个开发人员一起处理现有的 MVC3 项目。我在概念上熟悉 MVC,并且正在努力了解它在这个项目中的使用方式。

我们有一个 AccountDto 类来表示帐户。每个实体都有一个由另一个类继承的 Response 类,即 AccountResponse:

public class Response
{
    [DataMember]
    public bool IsSuccess{get;set;}

    [DataMember]
    public string DisplayMessage { get; set; }

    [DataMember]
    public string DetailedMessage { get; set; }

    [DataMember]
    public ErrorType ErrorType { get; set; }

    public Response(){
        this.IsSuccess=true;
        this.ErrorType = ErrorType.None;
    }
}

public partial class AccountResponse : Response
{
    [DataMember]
    public IList<AccountDto> AccountList { get; set; }
}

有一个 AccountService 会返回一个 AccountResponse 给 Controller,其中包含一个 AccountDto 对象的列表:

public AccountResponse GetAccountByAccountId(Int64 accountId)
{
    _logger.Info("Executing GetAccountByAccountId()");
    AccountResponse response = new AccountResponse();

    try
    {
        Account item = AccountPersistence.GetAccountByAccountId(accountId);
        AccountDto dto = Mapper.Map<AccountDto>(item);

        response.AccountList = new List<AccountDto>() { dto };
        response.IsSuccess = true;
    }
    catch (Exception ex)
    {
        response.IsSuccess = false;
        response.ErrorType = ErrorType.GeneralFault;
        response.DetailedMessage = ex.ExceptionMessageBuilder();
        response.DisplayMessage = "System Failure: Failed to get Account by AccountId";
        _logger.Error(ex);
    }
    return response;
}

有人告诉我 Response 的实现是为了能够处理成功/失败消息。所以在 Controller 中,有如下代码(如果失败也不会碰巧做任何特殊的事情):

public ActionResult ToBeCalled(int id)
{
    AccountDto dto = null;
    var response = _accountService.GetAccountByAccountId(Convert.ToInt64(id));
    if (response.IsSuccess)
    {
        dto = response.AccountList[0];
        return View(dto);
    }
    return View(dto);
}

这对我来说很有意义,尽管我不确定成功/错误消息将在哪里使用。但是,他们现在想从在 View 中使用 DTO 切换到使用响应,因此必须在 View 中处理成功/失败:

public ActionResult ToBeCalled(int id)
{
    var response = _accountService.GetAccountByAccountId(Convert.ToInt64(id));
    return View(response);
}

这对我来说似乎不太对劲——我不必针对 DTO 作为模型进行编码,我必须为每个页面执行如下操作:

@{
    if (Model.IsSuccess)
    {
        var account = Model.AccountList.FirstOrDefault();

        if (account != null)
        {
            @Html.HiddenFor(x => account.AccountNumber)
        }
}

然后, Controller 的 ActionResult/HttpPost 方法还必须从这些 Response 对象中解析 DTO。这对我来说似乎是一种反模式;这样的做法正常吗?

抱歉,如果这太长,如果它属于 Code Review 或其他网站,请迁移。

最佳答案

我同意你的看法,这将是一种反模式。 View 应该是非常无知的,尤其是像这样的逻辑。

如果成功和失败之间的区别只是 UI 的一小部分,我明白为什么这会很诱人,但想象一下如果这种情况发生变化。一个 View 几乎没有能力(没有不必要的部分嵌套)切换到一个完全不同的 View 。它没有发出重定向或其他错误代码的能力。如果您决定更改 UI,您可能需要返回并再次重写您的 Controller 。

如果将逻辑移动到 View 背后的原因是从 Controller 中删除 response.IsSuccess 逻辑(老实说,这对我来说很好;它与classic Model.IsValid),您可以考虑另一种方法:重构您的 Response 类以继承自 ActionResult。然后您可以将该逻辑移动到 ExecuteResult() 方法中,它将与您的 Controller 分开。

关于c# - 这是 MVC 反模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11725269/

相关文章:

C# XML 序列化列表,元素名称取决于类

c# - csproj 根据操作系统复制文件

c# - 如何使用 ASP.NET MVC 3 将 "expensive"数据从一个页面传递到另一个页面?

design-patterns - 域类中的 HTML 格式化

c# - 如何从带有 MethodCallExpression/lambda 的树中的 ConditionalExpression.IfThen 返回?

c# - Xamarin.Android SQLite.NET 重复列名称 : ID

c# - 在 MVC 3 Razor 中获取事件页面链接的更好方法

asp.net-mvc - 将 MVC 中的 Jquery 表转换为 JSON

java - 为什么不在一个类中编码呢?

java - 无法编译列表的模式匹配程序