简体   繁体   English

从带有Razor页面的Page方法和WebApi控制器中调用共享代码

[英]Calling a shared code from Page method and WebApi Controller with Razor Pages

I'm using the new Razor Pages with core 2.0 and I'm trying to see if I can share the query code by putting the linq and db initialization into a Utility class in App_code folder but I'm having an issue with making this class to work. 我正在将新的Razor Pages与core 2.0一起使用,并且尝试通过将linq和db初始化放入App_code文件夹中的Utility类中来查看是否可以共享查询代码,但是在制作此类时遇到了问题上班。

Basically I'm querying the database with linq but I also have another asp-page-handler that will create a PDF. 基本上,我使用linq查询数据库,但是我还有另一个将创建PDF的asp-page-handler。

Here is my page 这是我的页面

public class IndexModel : PageModel
    {
        private readonly CrewLogContext _context;
        //initialize db
        public IndexModel(CrewLogContext context)
        {
            _context = context;
        }
        public IList<SelectionDailyReport> SelectionDailyReport { get; set; }
        public DateSearchRange DateSearchRange { get; set; }


 public async Task OnPostSelectionAsync(DateSearchRange DateSearchRange)
        {
            var result= await _context.TaskSelection.Where(x => x.WorkDate >= startDate && x.WorkDate <= endDate)
                .Include(t => t.Zone).OrderBy(x => x.AssocId).ToListAsync();

SelectionDailyReport = result;
}

OK. 好。 so this works fine. 所以这很好。 I also have a another button that calls a webApi controller that will basically query the same data and generates a PDF as well. 我还有另一个按钮,调用webApi控制器,该控制器将基本查询相同的数据并生成PDF。

I wanted to create a utility class and call its method from the page or the webapi controller so I don't have to write the linq query twice. 我想创建一个实用程序类并从页面或webapi控制器中调用其方法,因此我不必两次编写linq查询。

I created an App_Folder and add a .cs file 我创建了一个App_Folder并添加了一个.cs文件

in Utility.cS 在Utility.cS中

   namespace WebCrewLog.App_Code
    {
        public class Utility
        {
            private CrewLogContext _context;

            //initiate db connection
            public Utility(CrewLogContext context)
            {
               _context = context;
            }

            public  IList<SelectionDailyReport> GetSelectionData (DateSearchRange DateSearchRange)
            {
                var myList =  _context.TaskSelection.Where(x => x.WorkDate >=DateSearchRange.StartDate && x.WorkDate <= DateSearchRange.EndDate)
                    .Include(t => t.Zone).OrderBy(x => x.AssocId).ToList();
         return  myList ;
       }

Then from my page or my webapi I wanted to call 然后我想从我的页面或Webapi调用

SelectionDailyReport = Utility.GetSelectionData(DateSearchRange);

So the problem is that intellisense does not detect the GetSelectionData method. 因此,问题在于,智能感知无法检测到GetSelectionData方法。 So I thought I should make the GetSelectionData method static. 所以我认为我应该使GetSelectionData方法静态。

so Change Utility Class 因此更改实用程序类

 public IList<SelectionDailyReport> GetSelectionData (DateSearchRange DateSearchRange)
        {
            var myList =  _context.TaskSelection.Where(x => x.WorkDate >=DateSearchRange.StartDate && x.WorkDate <= DateSearchRange.EndDate)
                .Include(t => t.Zone).OrderBy(x => x.AssocId).ToList();
....

 public  static IList<SelectionDailyReport> GetSelectionData (DateSearchRange DateSearchRange)
        {
            var myList =  _context.TaskSelection.Where(x => x.WorkDate >=DateSearchRange.StartDate && x.WorkDate <= DateSearchRange.EndDate)
                .Include(t => t.Zone).OrderBy(x => x.AssocId).ToList();
....

However, when I do that I'm getting a null exception on _context.TaskSelection and not sure why is that. 但是,当我这样做时,我在_context.TaskSelection上得到了一个空异常,并且不确定为什么会这样。

The problem is that when you changed the function to be static , now calling it does not initialize the class and the constructor public Utility(CrewLogContext context) is not called, so the _context field is not assigned to anything and stays null . 问题在于,当您将函数更改为static ,现在调用它不会初始化类,并且不会调用构造函数public Utility(CrewLogContext context) ,因此_context字段未分配任何内容,并保持null

One way to solve this is to remove static and call the function after building the object and passing the context. 解决此问题的一种方法是在构建对象并传递上下文之后删除static变量并调用函数。 So instead of: 所以代替:

SelectionDailyReport = Utility.GetSelectionData(DateSearchRange);

Try something like: 尝试类似:

Utility u = new Utility(myContext); //Change myContext to the name of your context
SelectionDailyReport = u.GetSelectionData(DateSearchRange);

If you want it to be static , then you'll have to pass it the context: 如果希望它是static ,则必须将其传递给上下文:

public  static IList<SelectionDailyReport> GetSelectionData (DateSearchRange DateSearchRange, CrewLogContext context) {
    var myList =  context.TaskSelection.Where(x => x.WorkDate >=DateSearchRange.StartDate && x.WorkDate <= DateSearchRange.EndDate)
            .Include(t => t.Zone).OrderBy(x => x.AssocId).ToList();
     return  myList ;
   }

The above solutions may seem easier, but it's probably better to use the proper injection just like how it works in the controllers. 上面的解决方案似乎更容易,但是使用适当的注入可能更好,就像它在控制器中的工作方式一样。

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

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