繁体   English   中英

如何检查一个条目是否存在于单独的 SQL Server 表中,并根据它是否存在来更改链接的函数

[英]How to check if an entry exists in a separate SQL Server table, and change which function is linked depending on whether it exists or not

在我开始之前,我对编码还比较陌生,并且将在不久的将来开始我的第一个初级角色,所以我目前的技能水平非常基础。

我正在创建一个个人 C# ASP.NET MVC Web 应用程序来跟踪用户参加的音乐活动、在这些活动中播放的艺术家以及用户看到的艺术家。 这一切都是由用户从数据库 (SQL Server) 中所有事件的索引视图中手动添加事件完成的,如下图所示。

https://i.stack.imgur.com/HOUGG.png

控制器动作:

        public ActionResult GetEvents()
        {
            return View(_trackerService.GetEvents());
        }

视图的标记:

@model IEnumerable<Tracker.Data.tbl_events>

@{
    ViewBag.Title = "GetEvents";
}

<h2>GetEvents</h2>

<p>
    @Html.ActionLink("Create New", "CreateEvent")
</p>
<table class="table">

    <tr><h2>Upcoming Events</h2>
        <th>
            @Html.DisplayNameFor(model => model.Event_ID)
        </th><th>
            @Html.DisplayNameFor(model => model.Event_Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Event_Date)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Event_Location)
        </th>
    </tr>

    @foreach (var item in Model.Where( x => x.Event_Date >= System.DateTime.Now).OrderBy(x => x.Event_Date))
    {

<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Event_ID)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Event_Name)
    </td>
    <td>
        @Convert.ToString(string.Format("{0:dd/MM/yyyy}", item.Event_Date)) @*Converts the DateTime data type that ASP.NET uses by default into a string with the format of Date Only (https://stackoverflow.com/a/34990313/12764653)*@
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Event_Location)
    </td>
    <td>
        @*@Html.ActionLink("Edit", "Edit", new { id = item.Event_ID }) | *@
        @Html.ActionLink("Details", "GetEventDetails", new { Event_ID = item.Event_ID }) |
        @Html.ActionLink("Lineup", "../Event/GetLineup", new { Event_ID = item.Event_ID, Event_Name = item.Event_Name }) |
        @if ((System.Web.HttpContext.Current.User != null) && System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
        {@*Checks to see if there is a current user*@
        @Html.ActionLink("Add to my Events", "../Event/AddToUser", new { User_ID = Convert.ToString(System.Web.HttpContext.Current.User.Identity.GetUserId()).GetHashCode(), Event_ID = item.Event_ID })}
    @*@Html.ActionLink("Delete", "Delete", new { id = item.Event_ID })*@
    </td>
</tr>
    }
</table>

用户将事件添加到他们的个人资料后,它会在数据库中创建一个条目,其中包含以下字段(链接如下):

https://i.stack.imgur.com/YQqHT.png

“添加到我的事件”功能的控制器方法:

[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] 
public ActionResult AddToUser(tbl_eventhistory _event)
{
        try
        {
            _trackerService.AddToUser(_event);
            return RedirectToAction("GetEvents");
        }
        catch
        {
            return View();
        }
}

我知道按照目前的方式,这很可能必须在控制器或视图中完成,并且可以检查“tbl_eventhistory”以查看当前用户的 User_ID 和特定的 Event_ID 是否存在条目,但是我不确定如何实际执行此操作,因此将不胜感激任何帮助。

编辑:显示的表是“tbl_events”的索引视图。 当用户从此视图向其配置文件添加事件时,它会使用该特定事件的参数在名为“tbl_eventhistory”的不同表中创建一个条目,该事件通过 Event_ID(tbl_event 的 PK)上的外键关联。 当用户将事件添加到 tbl_eventhistory 时,我只想从该特定事件的视图中删除“添加到用户”链接。

您的 Razor 视图中已经有一个Delete链接 - 这似乎已经足够了:

@Html.ActionLink("Delete", "../Event/DeleteEvent", new { id = item.Event_ID })

然后你的EventController会看起来像下面这些行:

[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] 
public ActionResult DeleteEvent(int id)
{
        try
        {
            _trackerService.DeleteForUser(HttpContext.Current.User.Identity.GetUserId(), _event); // this is where you verify whether currently logged in user has access and delete their associated event. 
            //depending on your data access framework of choice you should aim to fire a query like so: 
            //DELETE FROM table WHERE User_Id = :user_id AND Event_Id = :id 
            //that would cover you for users deleing only items belonging to them
            return RedirectToAction("GetEvents");
        }
        catch
        {
            return View();
        }
}

现在指出您的 AddEvent 代码的两个安全问题:

@Html.ActionLink("Add to my Events", "../Event/AddToUser", new { User_ID = Convert.ToString(System.Web.HttpContext.Current.User.Identity.GetUserId()).GetHashCode(), Event_ID = item.Event_ID })}
  1. GetHashCode()不是您认为的那样:将其用作标识符是不安全的,因为很可能会在默认实现上发生冲突
  2. 甚至不需要从客户端传回用户 ID:您的控制器可以访问HttpContext对象,因此您应该能够在服务器端获取该User_ID

并尝试在标题中回答您的问题:

如何检查一个条目是否存在于单独的 SQL Server 表中,

我认为您不需要它来删除事件 - 请参阅上面代码中的注释

并根据是否存在更改链接的功能

我不确定我是否得到了这部分。 我觉得在查看SQL JOIN上的其他 SO 问题后,您可能可以自己回答这两个问题。 否则,我(以及这​​里的社区)将需要有关您的实际用例和目标的更多详细信息

设法终于找到了解决方案。 如果术语不正确,请原谅我。

我已经有一个函数来返回特定用户事件的索引视图(下面的 DAO 类代码)

        public IList<tbl_eventhistory> GetUserEvents(string User_ID)
        {
            IQueryable<tbl_eventhistory> _eventHistory;
            _eventHistory = from tbl_eventhistory in _context.tbl_eventhistory where tbl_eventhistory.User_ID == User_ID select tbl_eventhistory;
            return _eventHistory.ToList<tbl_eventhistory>();
        }

考虑如何在具有不同绑定模型的视图中使用此数据,我考虑使用 ViewBag 并遇到了这个: “如何检查 ViewBag 中的列表是否包含字符串” 从这个答案中,我将我的“GetEvents”函数修改为以下内容:

public ActionResult GetEvents()
        {
            List<string> UsersEvents = new List<string>();
            foreach (var item in _trackerService.GetUserEvents(User_ID))
            {
                UsersEvents.Add(item.Event_ID.ToString());
            }
            ViewBag.MyEvents = _trackerService.GetUserEvents(User_ID);
            ViewBag.MyEvents = UsersEvents;
            return View(_trackerService.GetEvents());
        }

如果我的理解是正确的,这将创建一个 List,它通过调用 'GetUserEvents' 操作填充并循环遍历结果中的每个条目。 将此列表移动到 ViewBag 然后允许我修改“GetEvents”ActionLinks 以在现有语句中包含一个额外的 IF 语句,以检查用户是否已登录:

@if ((System.Web.HttpContext.Current.User != null) && System.Web.HttpContext.Current.User.Identity.IsAuthenticated)

if (((IList<string>)ViewBag.MyEvents).Contains(item.Event_ID.ToString())){ 
       <p>TEST</p> }
else{
       @Html.ActionLink("Add to my Events", "../Event/AddToUser", new { User_ID = Convert.ToString(System.Web.HttpContext.Current.User.Identity.GetUserId()).GetHashCode(), Event_ID = item.Event_ID })}
            }

这导致在适当的情况下显示“测试”而不是“添加到用户”的链接(如下所示,最终事件不存在于“tbl_eventhistory”中):

http://icecream.me/b459c9d17854b081a0804692f67c3aa3

我知道这可能是最有效的方法,但我很高兴它在经过很长时间试图弄清楚之后现在可以工作了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM