博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nancy简单实战之NancyMusicStore(三):完善商品信息与管理
阅读量:7029 次
发布时间:2019-06-28

本文共 6756 字,大约阅读时间需要 22 分钟。

前言

上一篇,我们做了不少准备,并且还把我们NancyFx音乐商城的首页打造好了。这一篇主要是完善我们在首页的商品浏览问题和添加对商品的管理。

下面开始正题:

商品详情

首先是查看单个商品的详情:

先回顾一下我们在Home/Index.cshtml中写的热销商品列表

我们在上一篇是没有给这个列表项加具体的链接,为了和MVC MusicStore保持一致,我们也用了同样的请求链接

给Home/Index.cshtml列表的a标签加上链接,具体如下:

  • @album.Title @album.Title
  • 所以我们要访问单个商品的详情,是要通过 http://domain.com/store/details/id 的形式来访问。

    下面我们就在StoreModule中,添加这一块相应的内容,在StoreModule的构造函数中添加下面的代码:

    Get["details/{id:int}"] = _ =>{    int id = 0;    if (int.TryParse(_.id, out id))    {        string cmd = "public.get_album_details_by_aid";        var album = DBHelper.QueryFirstOrDefault
    (cmd, new { aid = id }, null, null, CommandType.StoredProcedure); if (album != null) { return View["Details", album]; } } return View["Shared/Error"];};

    在路由中details/{id:int},参数id后面加了一个限制,让其只能是整数。

    然后通过_.id来取到这个id的具体值,后面的内容就是根据这个id去拿到第一条数据。

    最后就是详情页的页面内容了

    @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase
    @{ ViewBag.Title = "Album - " + Model.Title; }

    @Model.Title

    @Model.Title

    Genre: @Model.GenreName

    Artist: @Model.ArtistName

    Price: @String.Format("{0:F}", Model.Price)

    Add to cart

    此时单个商品的详情已经可看到了,效果如下:

    details

    商品分类列表

    下面要查看的是某个分类的所有商品。

    我们在通过ajax填充分类信息时,填充的内容是:

    $("#categories").append('
  • ' + res[i].name + '
  • ');

    现在把具体的链接地址加上,修改成如下代码:

  • ' + res[i].name + '
  • 可以看到,我们要访问某个分类有那些商品,是要通过 http://domain.com/store/browse/name 的形式来访问。

    同样在StoreModule的构造函数添加一个相应的处理:

    Get["browse/{genre}"] = _ =>{    string genre = _.genre;    ViewBag.Genre = genre;    string cmd = "public.get_album_list_by_gname";    var albumList = DBHelper.Query
    (cmd, new { gname = genre }, null, true, null, CommandType.StoredProcedure).ToList(); return View["Browse", albumList];};

    其对应的页面内容是和首页的热销商品一个形式的,只是数量比较多而已。

    在这里点击某个商品也是能跳到对应的详情页的,具体如下:

    @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase
    >@{ ViewBag.Title = "Browse Albums"; }

    @ViewBag.Genre Albums

    示例为Disco分类下面的列表页:

    disco

    到这里,我们已经完成了商品信息浏览的相关处理。

    下面就添加对这些商品的管理,这里的管理实则是对专辑(Albums)信息的CURD操作。

    商品管理

    这些操作的具体内容就不详细展开了。在Modules文件夹下面新建一个StoreManagerModule.cs

    具体内容如下(省略了部分代码,占的篇幅有点多) :

    using Nancy;using Nancy.ModelBinding;using Nancy.Security;using NancyMusicStore.Common;using NancyMusicStore.Models;using NancyMusicStore.ViewModels;using System;using System.Data;namespace NancyMusicStore.Modules{    public class StoreManagerModule : NancyModule    {        public StoreManagerModule() : base("/storemanager")        {            Get["/"] = _ =>            {                string cmd = "get_all_albums";                var list = DBHelper.Query
    (cmd, null, null, true, null, CommandType.StoredProcedure); return View["Index", list]; }; Get["/create"] = _ =>{}; Post["/create"] = _ =>{}; Get["/details/{id:int}"] = _ =>{}; Get["/edit/{id:int}"] = _ =>{}; Post["/edit"] = _ =>{}; Get["/delete/{id:int}"] = _ =>{}; Post["/delete/{id:int}"] = _ =>{}; Get["/getallgenres"] = _ =>{}; Get["/getallartists"] = _ =>{}; } }}

    视图代码就不放出来了,可以在最后的文章中去下载。

    商品管理的效果如下:

    manager

    我们在_Layout.cshtml中指定了商品管理的入口在导航菜单的【Admin】中

    enter

    但是现在这种情况下,是任何人都可以对商品信息修改,这显然是不合理的。

    在MVC MusicStore中是通过Membership来处理这个问题的。对于这一块我是通过Nancy本身的Forms认证来处理。

    Forms认证,有几个重要的地方需要说明一下:

    • 在启动器中要添加Forms认证的支持

    • 实现一个继承IUserMapper接口的UserMapper类

    • 通过IoC去注册这个UserMapper类

    • 在要认证的地方添加this.RequiresAuthentication()即可

    我们先在web.config的appSettings中添加一个配置项,用来指定没授权用户的登录url

    在启动器(CustomerBootstrapper.cs)中,是这样进行处理的

    protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context){    base.RequestStartup(container, pipelines, context);    //form authentication    var formsAuthConfiguration = new FormsAuthenticationConfiguration    {        RedirectUrl = ConfigHelper.GetAppSettingByKey("logonUrl"),        UserMapper = container.Resolve
    (), }; FormsAuthentication.Enable(pipelines, formsAuthConfiguration);}protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context){ base.ConfigureRequestContainer(container, context); container.Register
    ();}

    在这里,用的IoC容器也是Nancy本身就支持的TinyIoc,没有用业界流行的AutoFac。

    UserMapper的实现如下 :

    internal class UserMapper : IUserMapper{    public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context)    {        string cmd = "public.get_user_by_userid";        var user = DBHelper.QueryFirstOrDefault
    (cmd, new { uid = identifier.ToString() }, null, null, CommandType.StoredProcedure); return user == null ? null : new UserIdentity { UserName = user.SysUserName, Claims = new[] { "SystemUser" } }; }}

    到这一步,Forms的配置已经OK了。

    有关Nancy中Forms认证的内容,可以参考之前的博客

    下面就只要在StoreManagerModule的构造函数中添加 this.RequiresAuthentication();

    这时,我们想直接通过入口来打开管理界面,就会跳转到登录界面,要求我们先进行登录才可以。

    效果图如下:

    logon

    可以看到,我们的效果已经达到了。

    下面仔细观察一下url,发现参数中还附带了returnUrl,可以让我们登录后跳转到指定的页面。

    登录注册相关的操作放在在AccountModule中

    下面来看看这个returnUrl的处理

    Get["/logon"] = _ =>{    var returnUrl = this.Request.Query["returnUrl"];    ViewBag.returnUrl = returnUrl;    return View["LogOn"];};Post["/logon"] = _ =>{    var logonModel = this.Bind
    (); string cmd = "public.get_user_by_name_and_password"; var user = DBHelper.QueryFirstOrDefault
    (cmd, new { uname = logonModel.SysUserName, upwd = logonModel.SysUserPassword }, null, null, CommandType.StoredProcedure); if (user == null) { return View["LogOn"]; } else { MigrateShoppingCart(user.SysUserName); var redirectUrl = string.IsNullOrWhiteSpace(logonModel.ReturnUrl) ? "/" : logonModel.ReturnUrl; return this.LoginAndRedirect(Guid.Parse(user.SysUserId), fallbackRedirectUrl: redirectUrl); }};

    returnUrl是以QueryString的形式存在,所以在打开登录界面的时候,用一个viewbag把它存起来

    登录的时候再POST到后台。登录的POST操作用到了Nancy的ModelBinding,与MVC的模型绑定是类似的,可以参考 。

    所以在LogOnModel中,添加了一个属性用于绑定这个returnUrl。

    public class LogOnModel{    public string SysUserName { get; set; }    public string SysUserPassword { get; set; }    public string ReturnUrl { get; set; }        }

    到这里,商品信息和管理已经完成了。实战的第二篇文章也就结束了。

    下面一篇的内容就是要完成购物车的内容。

    本文也已经同步到

    转载于:https://www.cnblogs.com/catcher1994/p/6308666.html

    你可能感兴趣的文章
    BZOJ 1084 最大子矩阵
    查看>>
    2018杭电多校第三场1007(凸包,极角排序)
    查看>>
    django中orm的简单操作
    查看>>
    Mybatis知识(1)
    查看>>
    php处理网站url编码及乱码问题
    查看>>
    快速入门:selenium自动化测试+ubuntu系统+php语言+firefox/chrome浏览器
    查看>>
    docx 转 doc
    查看>>
    DD DT DL标签
    查看>>
    用window.open函数页面传值
    查看>>
    SPOJ 10707 COT2 - Count on a tree II
    查看>>
    数据绑定——Vue.js
    查看>>
    Max Mex
    查看>>
    [CentOS] 7 不执行文件 /etc/rc.d/rc.local
    查看>>
    模态窗口的各个属性
    查看>>
    10.28 (上午) 开课一个月零二十四天 (数据访问)
    查看>>
    为什么你应该(从现在开始就)写博客
    查看>>
    小技巧积累
    查看>>
    Java JDBC链接Oracle数据库
    查看>>
    Moss2010 部署命令
    查看>>
    Git 操作分支
    查看>>