asp.net mvc связанный, в основном вопрос рефакторинга - PullRequest
0 голосов
/ 08 декабря 2008

Кто-нибудь может придумать лучший способ сделать это?

    [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 ]

3 голосов
/ 08 декабря 2008

Я думаю, вы также можете использовать инфраструктуру mvc для большей части своего кода. Поправьте меня, если я ошибаюсь, потому что я сделаю несколько предположений о ваших занятиях, потому что я не могу вычесть это из вашего поста.
Мои предположения:

  • Request.Form ["action"] - это поле выбора с одним значением
  • Request.Form ["value"] - это поле выбора с несколькими значениями
  • действие - это действие, которое вы хотите предпринять для всех сообщений
  • message - список значений, которые должны идти с действием

Я бы попытался использовать функциональность фреймворка, где это возможно

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

Если затем вы дадите своим входным данным в своем HTML правильное имя (в моем примере это будет выбранные сообщения и actionType), первые несколько правил станут не обязательными.

Если модель ModelBinder по умолчанию не может вам помочь, вы можете подумать о том, чтобы поместить логику синтаксического анализа в пользовательский моделиндер. Вы можете искать сообщения об этом в SO.

В качестве примечания: вы, возможно, захотите пересмотреть названия переменных. «action» может путать с действием MVC (как в ActionResult), а MemberMessageSaveAction может выглядеть так, как будто это значение перечисления MemberMessageAction. Просто мысль.

2 голосов
/ 08 декабря 2008

Превратите 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
    }
}

Теперь вы можете легко разложить код.

2 голосов
/ 08 декабря 2008

Первым шагом будет создание разных методов для каждого действия.

Далее следует убрать негативную логику.

В результате получается что-то вроде этого:

[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(...);
  }
}
1 голос
/ 08 декабря 2008

Мне не нравится

MessageRepository.FetchByID(messages[i].ID)

это сделает сообщения. Длинные (выбранные) запросы к базе данных. Я думаю, вам нужно хранить ваши сообщения в ViewData, выполнять фильтрацию и передавать их в Update () без необходимости запрашивать вашу базу данных.

0 голосов
/ 08 декабря 2008

Я придумал это.

    [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();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...