2016-11-25 46 views
0

我目前正在重构我编写的一些代码,当时我的经验不足,并且已经将逻辑从我的控制器移动到某些模型以尝试使我的控制器更具可读性。C#清洁视图控制器

有一个功能,我不是100%确定的,一旦它被提交,它就会通过电子邮件从视图中发送一个表单。该问题的代码写成:

[HttpPost] 
     [ValidateAntiForgeryToken] 
     public async Task<ActionResult> NewUser(Request model) 
     { 
      if (!ModelState.IsValid) 
      { 
       return View(model); 
      } 

      Offer_Request req1 = new Offer_Request(); 
      Offer_Request req2 = new Offer_Request(); 
      req1.Request = req2.Request= model; 
      req1.offerID = 1; 
      req2.offerID = 2; 

      using (var ctx = new UserDBEntities()) 
      { 
       ctx.Request.Add(model); 
       ctx.Offer_Request.Add(req1); 
       ctx.Offer_Request.Add(req2); 
       ctx.SaveChanges(); 
      } 

      string link1 = Url.Action("EmailHandler", "Home", routeValues: null, protocol: Request.Url.Scheme); 
      string link2 = Url.Action("EmailHandler", "Home", routeValues: null, protocol: Request.Url.Scheme); 
      link1 = link1 + "?id=" + req1.ID.ToString(); 
      link2 = link2 + "?id=" + req2.ID.ToString(); 
      var body = "<p>New request from {0} at {1}</p><p>Please choose from the following</p><br><p>One day access token:</p><p>{2}</p><br><p>5 day access token</p><p>{3}</p>"; 
      var subject = "{0} wants to connect!"; 
      var message = new MailMessage(); 
      message.To.Add(new MailAddress(model.SponsorEmail)); 
      message.From = new MailAddress(##########); 
      message.Subject = string.Format(subject, model.FirstName); 
      message.Body = string.Format(body, model.FirstName, model.Email, link1, link2); 
      message.IsBodyHtml = true; 

      using (var smtp = new SmtpClient()) 
      { 
       var credential = new NetworkCredential("########", "##########"); 
       smtp.Credentials = credential; 
       smtp.Host = "smtp.office365.com"; 
       smtp.Port = 587; 
       smtp.EnableSsl = true; 
       await smtp.SendMailAsync(message); 
      } 

      return RedirectToAction("Sent"); 
     } 

我想知道如果我应该电子邮件逻辑移动到一个模型,如果我可以通过我的请求模型;到所述模型进行处理。还有一些数据库操作发生的时间很短,这让我想知道是否值得把它放在移动控制器中。这里最好的代码练习是什么? (由于显而易见的原因删除证书)

+1

它不应该在你的模型中。将代码重构为控制器中的私有方法,或者更好地,创建一个由控制器方法调用的单独服务。 –

+0

@StephenMuecke嘿谢谢你的回应!我目前正在由我的控制器调用的“模型”文件夹中创建类以运行各种方法。我不完全确定将这些模型放入单独的服务意味着什么意味着在我的解决方案中创建一个新文件(即将模型中的类从模型移动到我的解决方案目录中)? –

+1

没有,模型没有一个单独的服务去 - 以发送电子邮件的方法做 - 包含一个方法的类,说,'SendEmail(...)'(和类将实现一个接口,这样你就可以使用DI将其注入到控制器中 –

回答

1

当发布的应用程序被封装在一个DLL中时,抽取出凭证总是会变得更安全。 DLL可以被解构和逆向工程,所以它不是一种防止代码的简单方法,但确实有帮助。

我往往有三层到我的安全和整洁的应用。首先,我在一个项目中拥有DataAccess Layer,另一个项目中的业务逻辑以及所有控制器所做的就是将它们集中到一起。所以它也分开了用户界面。我认为这是大多数英国软件开发公司的标准做法。如果你愿意,你可以进一步抽象出来,像保险公司和金融机构这样的地方可以有20或30层,这取决于数据需要如何操纵,但对于个人项目,我发现三层工作正常。

希望一些散漫的帮助!

+0

嘿,尽管设计进行得很合理 - 但是,当涉及到dataAccess和businessLogic时,我不确定将哪一个归类为其中一个。 使用此格式的程序是否具有一个结构使视图和视图控制器在一个项目中;数据库读写,数据模型和所需的配置在另一个项目中;业务逻辑(我假设)将包括撰写和发送电子邮件,创建API调用和管理所需的信息是根据需要在项目之间发送的? –

+0

通常情况下,数据访问除了管理数据外什么也不做(因此从数据库服务器等等获取数据)。),然后业务层将其操作到适合您需要交付给您的视图的方式 - 因此,如果您需要更改它,将其设置为新类,那么所有凭证存储和处理都将位于数据层上,添加到它等等,将在业务层完成 - 然后你的UI控制器(视图)将抓住所有操纵的数据,并把它放到你的模型中,用户友好的方式:) –

1

通常,控制器内部保存的内容仅仅是从interface实现中触发command让我们假设(SendEmail方法),它使得控制器不依赖于邮件的发送方式。

这意味着控制器只负责与模型连接图。所以逻辑应该理想地坐在模型或服务的某个地方。

然后该服务由DI注入控制器。