重工电子论坛

标题: 【MVC】学习笔记 [打印本页]

作者: 李维强-15级    时间: 2016-9-13 14:17
标题: 【MVC】学习笔记
本帖最后由 李维强-15级 于 2019-8-18 02:01 编辑

基本概念教程:
http://www.cnblogs.com/duanshuiliu/tag/MVC/
或者百度搜索:“全网 MVC”

路由控制:
http://www.cnblogs.com/firstcsharp/p/3741600.html

理解控制器工作原理:里面讲了ActionResult的6种返回形式(ContentResult,ViewResult)等
http://www.tracefact.net/Asp-Net/AspNetMvc-Controller.aspx
下面是ActionResult(12种)的简单应用
http://www.cnblogs.com/xielong/p/5940535.html


MVC参数传递,从控制器中传参数到VIEW,里面讲了M层处理参数配置,VIEW只管显示,C层才是逻辑处理然后返回给VIEW显示,最终都是传一个model给VIEW,MVC框架结构体现
http://www.cnblogs.com/powertoolsteam/p/MVC_two.html

MVC 控制器与控制器之间传递参数
http://www.cqutlab.cn/forum.php?mod=redirect&goto=findpost&ptid=177&pid=989&fromuid=8

HTMLHelper总结
HTMLHelper总结

Session设置和cookies的关系 讲得很详细了

MVC 多级控制器子目录,多级Views的子目录建立

扩展XMLResult的例子,注意看其整个result的原理

使用区域,路由多级控制的王道

控制器上添加自定义过滤
asp.net MVC 应用程序的生命周期
MVC后台接收数组对象
后台是List数据,传递到前台,用@Html.Raw(Json.Encode(ViewBag.FuncList)); 其中FuncList是后台的List
作者: 李维强-15级    时间: 2017-3-26 21:22
本帖最后由 李维强-15级 于 2017-6-10 16:06 编辑

Razor的基本概念
http://www.cnblogs.com/dengxinglin/p/3352078.html

控制器向VIEW传参数的几个方法 razor的
http://blog.csdn.net/chao88552828/article/details/9051117

MVC Razor模板引擎 @RenderBody、@RenderPage、@RenderSection及Html.RenderPartial、Html.RenderAction
http://www.cnblogs.com/xlhblogs/archive/2013/06/09/3129449.html
作者: 李维强-15级    时间: 2017-3-31 22:25
本帖最后由 李维强-15级 于 2017-3-31 22:40 编辑

上传文件相关的东西,

合并路径用Path.Combine
Path.Combine(Request.MapPath("~/Upload"), Path.GetFileName(file.FileName));
Razor相关示例: http://www.cnblogs.com/zhouhb/p/3906714.html

JS前端获取文件大小
http://www.cnblogs.com/ningvsban/archive/2013/06/04/3117906.html
然后到后端,razor直接用HttpPostedFileBase 这个类接收,或者继承model也可以,在后端再验证大小。

设置config文件限制连接时间以及上传文件大小
http://m.blog.csdn.net/article/details?id=5654883

多图片上传并浏览例程
http://www.jq22.com/jquery-info833
作者: 李维强-15级    时间: 2017-4-1 21:56
本帖最后由 李维强-15级 于 2017-4-1 22:13 编辑

上传图片到服务器,手写JS练习。研究了我好一段时间,主要还是对razor和jQuery不熟
这里给出例子主要是前端的,就是说文件在用户本地的时候,上传了立马展现出来,只要他不点上传以前,都不管服务器的事情。
主要实现功能是动态新增图片预览,每个图片右上角配删除字样,可以点击删除。另附后台MVC代码。
由于另外的包括文件大小验证,后缀名验证等,前后台都要做,后面再加上。

下面直接上前端代码:
[HTML] syntaxhighlighter_viewsource syntaxhighlighter_copycode
@using (Html.BeginForm("Upload", "Test", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div id="DIV_picField">
        <div onclick='btnAction(this)' class='UploadPicPlus' style='position:relative;display:inline-block;height:100px;width:100px;background-image:url(../../Content/upImg/IMGEmpty.png);'>
            <input type="file" name="ImgUpload" style='position:absolute;bottom:2px;display:none;' onchange="FileSelected(this)" />
        </div>
    </div>
    <input type="submit" value="picUp" name="myPicUp" />
}
<script type="text/javascript">
    var PicCount = 1;
    function btnAction(obj) {
        $(obj).children("input")[0].click(this);
        PicCount++;
    }
    function btnDel(obj) {
        $(obj).parent().remove();
    }
    function FileSelected(obj) {       //文件选择后的相应函数
        //先获取一个文件
        var UpIMG = obj.files[0];
        //把删除字样加到DIV右上角
        $(obj).parent("div.UploadPicPlus").append("<span style='position:absolute; right:2px;font-size:20px;cursor:pointer;' onclick='btnDel(this)'>删除</span>");
        //改变DIV的背景,使得看起来是一张图片
        $(obj).parent("div.UploadPicPlus").css("background-image", "url(" + window.URL.createObjectURL(UpIMG) + ")");
        //去除DIV的onclick事件
        $(obj).parent("div.UploadPicPlus").removeAttr("onclick");
        //再加一个 图片输入框到刚才那个旁边
        $("#DIV_picField").append("<div onclick='btnAction(this)' class='UploadPicPlus' style='position:relative;display:inline-block;height:100px;width:100px;background-image:url(../../Content/upImg/IMGEmpty.png);'>"
            + "<input name='ImgUpload' style='position:absolute;bottom:2px;display:none;'  type='file' onchange='FileSelected(this)' /></div>");
    }
</script>


然后是后端 这里用razor
[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
//先要到model里面定义个类,由于是接受多个文件,所以用了个list,网上他们用的IEnumerable,暂时还不明白区别,
    public class FileUploadViewModel
    {
        public List<HttpPostedFileBase> ImgUpload {get;set;}
        public string upValue { get; set; }
    }


然后在controller里面直接这样写即可

[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
        [HttpPost]
        public ActionResult Upload(FileUploadViewModel file)
        {
          //这里文件直接到file里面来了用file.XXX.XXX来取然后操作
            return RedirectToAction("Test", "Test");
        }



本文关键点,过了太多坑才有如上代码
1)model里面的变量名ImgUpload 要和input里面的name一样,不然razor收不到数据。
2)form表单里面 一定要有enctype = "multipart/form-data"属性
3)$(obj).children("input")[0] 我通过调试,在浏览器里面看到实际上那些parent或者children方法实际上是得到一个obj 这个obj里面有各个元素,所以我用[0]来索引到指定元素,实际上通过页面代码看到也只有一个元素。。
4)特别是parent("div.UploadPicPlus")的时候,如果夫级是div,则要把选择器加个div.XXXX这样才可以append,CSS等操作。我看人家都没这么做,但是我只有这么做了才可以成功。。。。
5)relative和absolute的定位使用区别 夫级用relative 子级用absolute定位
最终效果


作者: 李维强-15级    时间: 2017-4-5 00:55
安全问题 注入是无处不在的,我们需要防止攻击者来注入,来防止恶意提交写脚本。。。。
下面两篇文章给我讲了原理以及防范方法,特别是第一篇,在我们设计网站的时候,是需要用户提交带HTML标签的文本进来的,所以,需要对敏感信息进行过滤,
http://www.cnblogs.com/onepiece_wang/p/3669728.html
http://blog.sina.com.cn/s/blog_700185a60100q86h.html
作者: 李维强-15级    时间: 2017-4-9 23:11
mvc razor 验证总结
http://blog.csdn.net/wybshyy/article/details/52064253

作者: 李维强-15级    时间: 2017-4-9 23:11
防止跨站攻击 用@Html.AntiForgeryToken()
http://blog.csdn.net/cpytiger/article/details/8781457
作者: 李维强-15级    时间: 2017-4-11 21:53
本帖最后由 李维强-15级 于 2017-4-11 21:56 编辑

WEB API
让其默认返回JSON或者XML格式
http://blog.csdn.net/xxj_jing/article/details/48808099

简单使用示例
http://blog.csdn.net/sam1012/article/details/46957173

这里有个WEB API系列  讲了怎么做认证  
http://www.cnblogs.com/parry/arc ... ET_MVC_Web_API.html
http://www.cnblogs.com/parry/arc ... asic_Authorize.html
http://www.cnblogs.com/parry/p/A ... authentication.html

作者: 李维强-15级    时间: 2017-4-13 14:27
本帖最后由 李维强-15级 于 2017-5-4 13:17 编辑

使用cookie
http://www.cnblogs.com/firstcsha ... /06/08/3127209.html

用filter验证cookie的方法  自定义filter
http://blog.csdn.net/u010096526/article/details/46700581
作者: 李维强-15级    时间: 2017-5-4 02:09
本帖最后由 李维强-15级 于 2017-5-4 23:27 编辑

Session 设置 和cookies的关系 讲得很全面了
http://www.cnblogs.com/panchunti ... T_Session_Mode.html

直接跳转session会变的解决办法
http://www.cnblogs.com/net-saiya/p/4980960.html
作者: 李维强-15级    时间: 2017-5-4 15:11
       一般情况下,在我们做访问权限管理的时候,会把用户的正确登录后的基本信息保存在Session中,以后用户每次请求页面或接口数据的时候,拿到

Session中存储的用户基本信息,查看比较他有没有登录和能否访问当前页面。

       Session的原理,也就是在服务器端生成一个SessionID对应了存储的用户数据,而SessionID存储在Cookie中,客户端以后每次请求都会带上这个

Cookie,服务器端根据Cookie中的SessionID找到存储在服务器端的对应当前用户的数据。
示例用http://blog.csdn.net/u010096526/article/details/46700581

       FormsAuthentication是微软提供给我们开发人员使用,做身份认证使用的。通过该认证,我们可以把用户Name 和部分用户数据存储在Cookie中,

通过基本的条件设置可以,很简单的实现基本的身份角色认证。

forms身份认证
http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.html
作者: 李维强-15级    时间: 2017-6-10 22:42
本帖最后由 李维强-15级 于 2018-3-28 01:05 编辑

htmlhelper 总结
http://www.cnblogs.com/hunji-fight/p/3821140.html
http://www.cnblogs.com/fishtreeyu/archive/2011/03/23/1992498.html

另外 如果需要输出带标签的HTML相关东西,如字符串,需要使用@Html.Raw()这样才行。
作者: 李维强-15级    时间: 2017-10-18 22:36
[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
当多个action需要调用并且传递参数时:  

  public ActionResult getAllMenu(int i) {
            ManagerMenu managerMenu = new ManagerMenu();
            string str_json = string.Empty;
            List<ManagerMenu> listManagerMenu = GetMenu.getMenu(i);//得到菜单的list集合
            if (listManagerMenu.Count > 0)
            {
                List<TreeNode> listTreeNode = managerMenu.rerurnTreeNode(listManagerMenu);    //把菜单的list集合转化为换成符合easyUI的带有递归关系的集合
                str_json = ObjToJson.objToJson(listTreeNode);                                     //把对象转换为json格式的字符串
            }
            return Content(str_json);
        }



        public ActionResult getPersonMenu() {
            return RedirectToAction("getAllMenu", new { i=1});
        }

作者: 李维强-15级    时间: 2017-11-20 18:53
本帖最后由 李维强-15级 于 2019-6-23 13:36 编辑

可以参考https://www.cnblogs.com/genesis/p/5220879.html

实现控制器里面有子目录,view里面也有子目录。如下图所示

控制器代码

--------------------------------------------------------
正常情况下,如果单独建立这种目录然后直接去访问的话,肯定有问题,那么需要按照如下方式设置

首先需要重新配置路由,
[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            
            //路由规则匹配是从上到下的,优先匹配的路由一定要写在最上面。因为路由匹配成功以后,他不会继续匹配下去。
            routes.MapRoute(
                name: "LayUI",
                url: "LayUI/{controller}/{action}/{id}",
                defaults: new { Controller = "Admin", action = "Index", id = UrlParameter.Optional }
            );


            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "WxPage", action = "Index", id = UrlParameter.Optional }
            );

        }
    }

然后配置了路由过后,发现也不能访问,
因为,默认视图也是有自己的调用路径的,如下:
        Views/{1}/{0}.cshtml
        Views/Shared/{0}.cshtml
其中{1}表示Controller的名称,{0}表示视图名称,Shared是存放模板页的文件夹。一看就很清楚了。这个就是寻找视图的规则,所以我们存放在"Views/LayUI/Admin/Index.cshtml的存放规则就不满足。
那么下面就需要修改这个默认的view路径,也就是重写它,并且保留原来的那些东西
那么我建立一个自己的类,继承RazorViewEngine方法
[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WuYuHotel.Tools
{
    public sealed class LayUIViewEngine:RazorViewEngine
    {
        public  LayUIViewEngine()
        {
            ViewLocationFormats = new[]
            {
                "~/Views/{1}/{0}.cshtml",
                "~/Views/Shared/{0}.cshtml",
                //以上两个是默认视图引擎路径
                "~/Views/LayUI/{1}/{0}.cshtml"//我们的规则
            };

        }
        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            return base.FindView(controllerContext, viewName, masterName, useCache);
        }
    }
}

然后需要再global里面去注册一下


[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using WuYuHotel.WX_AccToken;
using System.Threading;
using WuYuHotel.Tools;

namespace WuYuHotel
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            RegisterView();
        }

        protected void RegisterView()
        {
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new LayUIViewEngine());
        }
    }
}


然后就可以访问到了~~~


作者: 李维强-15级    时间: 2018-3-5 19:47
使用区域
http://blog.csdn.net/hanjun0612/article/details/61918960

--------------------------------------
在14楼提到的东西,实际上有问题,例如添加了那个layui的目录,但是不要那个目录,任然可以访问到例如,localhost:60748//admin/index,也可以,还有一个localhost:60748//layui/home/index也可以访问到,这个实际上就存在问题因为他都匹配到了那条路由。。。如果硬要采取14楼的方法,那么就需要添加路由限制,在我帖子http://bbs.csdn.net/topics/392327883里面2楼的地方写得很清楚了。。
不过最后王道的方法还是使用Areas,因为把控制器文件放在主目录的controllers下面,始终都会被匹配到。。所以还是用这个不错。。
作者: 李维强-15级    时间: 2018-9-19 12:29
控制器上的自定义过滤
https://blog.csdn.net/dxb601/article/details/78021716

里面涉及到个调用base.OnActionExecuting(filterContext)
一句话,就是调用base.OnActionExecuting(filterContext)这个后,才会执行后续的ActionFilter,如果你确定只有一个,或是不想执行后续的话,那么可以不用调用该语句。

并且,filterContext.Result = xxx;会导致转向其它视图,后续的ActionFilter也是执行不了的。

作者: 李维强-15级    时间: 2019-7-18 23:15
MVC 后台接收数组对象
前台:
[HTML] syntaxhighlighter_viewsource syntaxhighlighter_copycode
        $("#BatchDel").on("click", function () {
            var checkStatus = table.checkStatus('EquipFeeMainlyTable');
            var data = checkStatus.data;
            if (data.length < 1) {
                layer.msg('至少选择一行数据', { icon: 3, time: 1500 });
                return;
            }
            var arr = new Array();
            for (var i = 0; i < data.length; i++) {
                arr = data.PEEquipPriceId;
            }

            $.ajax({
                type: "POST",
                url: "/Estimate/PEEquipFeeBatchDel",
                //contentType: "application/json",
                //dataType: "json",
                async: false,
                data: { "PEEquipPriceId": arr },
                success: function (msg) {
                    if (msg.result == "OK") {
                        layer.msg('复制成功"', { icon: 6, time: 1000 });
                        table.reload("demo", {
                            //where: { SortName: "SSlistId", Order: "Desc", Condition: " and 1=1" }
                        });
                        layer.close(layerCopyIndex);
                    } else {
                        alert(msg.result);
                    }
                }
            });
        });



后台
Request.Form.GetValues("PEEquipPriceId[]")




欢迎光临 重工电子论坛 (http://www.cqutlab.cn/) Powered by Discuz! X3.1