asp.net mvc相关,主要是一个重构问题

时间:2008-12-08 07:46:19

标签: asp.net-mvc refactoring

任何人都可以想到更好的方法吗?

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult SaveAction()
    {
        NameValueDeserializer value = new NameValueDeserializer();

        // selected messages
        MemberMessageSaveAction[] messages = (MemberMessageSaveAction[])value.Deserialize(Request.Form, "value", typeof(MemberMessageSaveAction[]));

        // selected action
        MemberMessageAction action = (MemberMessageAction)Enum.Parse(typeof(MemberMessageAction), Request.Form["action"]);

        // determine action
        if (action != MemberMessageAction.MarkRead &&
            action != MemberMessageAction.MarkUnRead &&
            action != MemberMessageAction.Delete)
        {
            // selected action requires special processing
            IList<MemberMessage> items = new List<MemberMessage>();

            // add selected messages to list
            for (int i = 0; i < messages.Length; i++)
            {
                foreach (int id in messages[i].Selected)
                {
                    items.Add(MessageRepository.FetchByID(id));
                }
            }

            // determine action further
            if (action == MemberMessageAction.MoveToFolder)
            {
                // folders
                IList<MemberMessageFolder> folders = FolderRepository.FetchAll(new MemberMessageFolderCriteria
                {
                    MemberID = Identity.ID,
                    ExcludedFolder = Request.Form["folder"]
                });

                if (folders.Total > 0)
                {
                    ViewData["messages"] = items;
                    ViewData["folders"] = folders;

                    return View("move");
                }

                return Url<MessageController>(c => c.Index("inbox", 1)).Redirect();
            }
            else if (action == MemberMessageAction.ExportXml)
            {
                return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Xml);
            }
            else if (action == MemberMessageAction.ExportCsv)
            {
                return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Csv);
            }
            else
            {
                return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Text);
            }
        }
        else if (action == MemberMessageAction.Delete)
        {
            for (int i = 0; i < messages.Length; i++)
            {
                foreach (int id in messages[i].Selected)
                {
                    MemberMessage message = MessageRepository.FetchByID(id);

                    if (message.Sender.ID == Identity.ID || message.Receiver.ID == Identity.ID)
                    {
                        if (message.Sender.ID == Identity.ID)
                        {
                            message.SenderActive = false;
                        }
                        else
                        {
                            message.ReceiverActive = false;
                        }

                        message.Updated = DateTime.Now;

                        MessageRepository.Update(message);

                        if (message.SenderActive == false && message.ReceiverActive == false)
                        {
                            MessageRepository.Delete(message);
                        }
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i < messages.Length; i++)
            {
                foreach (int id in messages[i].Selected)
                {
                    MemberMessage message = MessageRepository.FetchByID(id);

                    if (message.Receiver.ID == Identity.ID)
                    {
                        if (action == MemberMessageAction.MarkRead)
                        {
                            message.ReceiverRead = true;
                        }
                        else
                        {
                            message.ReceiverRead = false;
                        }

                        message.Updated = DateTime.Now;

                        MessageRepository.Update(message);
                    }
                }
            }
        }

        return Url<MessageController>(c => c.Index("inbox", 1)).Redirect();
    }

5 个答案:

答案 0 :(得分:3)

我认为您也可以在大多数代码中使用mvc框架。如果我错了,请纠正我,因为我会对你的课程做一些假设,因为我不能从你的帖子中扣除它。
我的假设:

  • Request.Form [“action”]是单值选择框
  • Request.Form [“value”]是一个多值选择框
  • action是您希望对所有邮件采取的操作
  • message是应该与操作一起使用的值列表

我会尝试尽可能利用框架的功能

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveMemberAction(SelectList selectedMessages, MemberMessageAction actionType){
     //Refactors mentioned by others        
}

如果您在Html中输入正确的名称(在我的示例中将是selectedMessages和actionType),则前几条规则将成为不合规定的。

如果默认的modelBinder无法帮助您,您可能需要考虑将解析逻辑放在自定义模型绑定器中。您可以搜索SO以查找有关它的帖子。

作为旁注:您可能想重新考虑变量命名。 “action”可能与MVC的操作混淆(如在ActionResult中),而MemberMessageSaveAction可能看起来像是MemberMessageAction枚举的值。只是一个想法。

答案 1 :(得分:2)

第一步是为每个动作制定不同的方法。

接下来是删除否定逻辑。

这导致如下:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction() {
  // SNIP   
  if (action == MemberMessageAction.Delete) {
    return DoDeleteAction(...);
  }
  else if (action == MemberMessageAction.MoveToFolder) {
    return DoMoveToFolderAction(...);
  }
  else if (action == MemberMessageAction.ExportXml) {
    return DoExportXmlAction(...);
  }
  else if (action == MemberMessageAction.ExportCsv) {
    return DoExportCsvAction(...);
  }
  else {
    return HandleUnknownAction(...);
  }
}

答案 2 :(得分:2)

将MemberMessageAction转换为具有Perform虚拟功能的类。

对于您的特殊操作,请将常用的执行代码分组:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction()
{
    NameValueDeserializer value = new NameValueDeserializer();
    MemberMessageSaveAction[] messages = (MemberMessageSaveAction[])value.Deserialize(Request.Form, "value", typeof(MemberMessageSaveAction[]));
    MemberMessageAction action = MemberMessageAction.FromName(
        messages,
        Request.Form["action"]));
    return action.Perform();
}

class MoveToFolder : SpecialAction { /*...*/ }
class ExportXml : SpecialAction { /*...*/ }
class ExportCsv : SpecialAction { /*...*/ }

class Delete : MemberMessageAction { /*...*/ }
class MarkRead : MemberMessageAction { /*...*/ }
class MarkUnRead : MemberMessageAction { /*...*/ }

abstract class MemberMessageAction {
    protected MemberMessageSaveAction[] messages;
    public MemberMessageAction(MemberMessageSaveAction[] ms) { messages = ms; }
    public abstract ActionResult Perform();
    public static MemberMessageAction FromName(MemberMessageSaveAction[] ms, string action) {
        // stupid code
        // return new Delete(ms);
    }
}

abstract class SpecialAction : MemberMessageAction {
    protected IList<MemberMessage> items;
    public SpecialAction(MemberMessageSaveAction[] ms) : base(ms) {
        // Build items
    }
}

现在您可以轻松地对代码进行分析。

答案 3 :(得分:1)

我不喜欢

MessageRepository.FetchByID(messages[i].ID)

这将使messages.Length(选中)查询到数据库。我认为您需要将消息存储在ViewData中,执行过滤并将它们传递给Update(),而无需重新查询数据库。

答案 4 :(得分:0)

我想出了这个。

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Update(MemberMessageUpdate[] messages, MemberMessage.Action action)
    {
        var actions = new List<MemberMessage.Action>
        {
            MemberMessage.Action.MoveToFolder,
            MemberMessage.Action.ExportCsv,
            MemberMessage.Action.ExportText,
            MemberMessage.Action.ExportText
        };

        if (actions.Contains(action))
        {
            IList<MemberMessage> items = new List<MemberMessage>();

            for (var i = 0; i < messages.Length; i++)
            {
                if (messages[i].Selected == false)
                {
                    continue;
                }

                items.Add(MessageRepository.FetchByID(messages[i].ID));
            }

            if (action == MemberMessage.Action.MoveToFolder)
            {
                var data = new MessageMoveViewData
                {
                    Messages = items
                };

                return View("move", data);
            }

            return new MessageDownloadResult(Identity.ID, items, action);
        }

        MessageRepository.Update(messages, action);

        return Url<MessageController>(c => c.Index(null, null, null, null)).Redirect();
    }
相关问题