C#cleaner视图控制器

C#cleaner视图控制器,c#,asp.net-mvc-4,model-view-controller,C#,Asp.net Mvc 4,Model View Controller,我目前正在重构我在经验不足时编写的一些代码,并将逻辑从控制器转移到一些模型,以使控制器更具可读性 有一个功能我不能百分之百确定,一旦表单提交,它将通过电子邮件从视图发送表单。问题代码编写为: [HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> NewUser(Request model) { if (!ModelState.I

我目前正在重构我在经验不足时编写的一些代码,并将逻辑从控制器转移到一些模型,以使控制器更具可读性

有一个功能我不能百分之百确定,一旦表单提交,它将通过电子邮件从视图发送表单。问题代码编写为:

[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");
        }
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务NewUser(请求模型)
{
如果(!ModelState.IsValid)
{
返回视图(模型);
}
Offer_Request req1=新的Offer_Request();
Offer_Request req2=新的Offer_Request();
req1.请求=req2.请求=模型;
需求1.offerID=1;
需求2.offerID=2;
使用(var ctx=new UserDBEntities())
{
ctx.Request.Add(型号);
ctx.报价和请求添加(需求1);
ctx.报价和请求添加(需求2);
ctx.SaveChanges();
}
字符串link1=Url.Action(“EmailHandler”,“Home”,routeValue:null,协议:Request.Url.Scheme);
字符串link2=Url.Action(“EmailHandler”,“Home”,RouteValue:null,协议:Request.Url.Scheme);
link1=link1+“?id=“+req1.id.ToString();
link2=link2+“?id=“+req2.id.ToString();
var body=“来自{1}{0}的新请求

请从以下


一天访问令牌中选择:

{2}


五天访问令牌

{3}

”; var subject=“{0}要连接!”; var message=new MailMessage(); message.To.Add(新邮件地址(model.SponsorEmail)); message.From=新邮件地址; message.Subject=string.Format(Subject,model.FirstName); message.Body=string.Format(Body,model.FirstName,model.Email,link1,link2); message.IsBodyHtml=true; 使用(var smtp=new SmtpClient()) { var凭证=新的网络凭证(“网络凭证”); smtp.Credentials=凭证; smtp.Host=“smtp.office365.com”; smtp.Port=587; smtp.EnableSsl=true; 等待smtp.SendMailAsync(消息); } 返回重定向操作(“已发送”); }

我想知道我是否应该将电子邮件逻辑移动到一个模型,以及我是否可以传递我的请求模型;对所述模型进行处理。此外,还有一些数据库操作正在进行,这是相当短的,让我想知道是否值得把它留在控制器的移动也。这里的最佳代码实践是什么?(由于明显的原因删除了凭据)

当应用程序发布时,提取凭据总是一个更安全的选择,因为它们随后被包装在DLL中。DLL可以解构和反向工程,所以它不是保护代码的简单方法,但确实有帮助

为了安全和整洁,我的应用程序通常有三个层次。首先,我在一个项目中有数据访问层,在另一个项目中有业务逻辑,控制器所做的一切就是将它们集中在一个地方。因此,它也分离出用户界面。我认为这是大多数英国软件开发公司的标准做法。如果您愿意,您可以进一步抽象出来,而像保险公司和金融机构这样的地方可以有20或30层,这取决于数据在整个过程中的处理方式,但对于个人项目,我发现这三层可以很好地工作


希望这些漫无边际的话能有所帮助

当应用程序发布时,提取凭据总是一个更安全的选择,因为它们被包装在DLL中。DLL可以解构和反向工程,所以它不是保护代码的简单方法,但确实有帮助

为了安全和整洁,我的应用程序通常有三个层次。首先,我在一个项目中有数据访问层,在另一个项目中有业务逻辑,控制器所做的一切就是将它们集中在一个地方。因此,它也分离出用户界面。我认为这是大多数英国软件开发公司的标准做法。如果您愿意,您可以进一步抽象出来,而像保险公司和金融机构这样的地方可以有20或30层,这取决于数据在整个过程中的处理方式,但对于个人项目,我发现这三层可以很好地工作


希望这些漫无边际的话能有所帮助

通常保存在控制器内的只是从
接口
实现(比如SendEmail方法)触发一个
命令
,这使得控制器不依赖于邮件的发送方式

这意味着控制器只负责连接视图和模型。因此,理想情况下,逻辑应该位于模型或服务中的某个位置


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

通常,控制器中保存的内容只是从
接口
实现(比如SendEmail方法)触发一个
命令,这使得控制器不依赖于邮件的发送方式

这意味着控制器只负责连接视图和模型。因此,理想情况下,逻辑应该位于模型或服务中的某个位置


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

它不应该在您的模型中。将代码重构为控制器中的私有方法,或者更好,创建一个由控制器方法调用的单独服务。@StephenMuecke嘿,感谢您的响应!我目前正在“models”文件夹中创建类,我的控制器调用这些类来运行它们的各种方法。我不完全确定将这些模型放到一个单独的服务中意味着什么,这是否意味着在我的解决方案中创建一个新文件(即从