question

RobertKing-4059 avatar image
0 Votes"
RobertKing-4059 asked RobertKing-4059 answered

Object variable empty but RawView contains data in Core MVC project.

Taking my first crack at DI in a MVC project using Core 3.1, and I'm stumped on a fairly basic question. I know I'm biting off several new things in one gulp, but I've done a lot of reading and sample projects so I feel like I understand what SHOULD be happening.

I'm creating an instance of a Service Layer in Startup.cs, and it appears to initialize properly.

The first time my HomeController Index method calls the ServiceLayer, everything seems to work correctly, as I can set and read some Instance vars in the ServiceLayer and it returns data to the Controller as expected.

But the next time a controller method makes a call to the ServiceLayer, the simple instance variables (strings) are still set as expected, but objects that I expected to be persisted in the ServiceLayer are null.

Here's a few snips that I think show my entire setup. I hope I'm missing something easy, but it behaves as if object variables simply don't persist, which really makes no sense.

Startup.cs

         public Startup(IConfiguration configuration)
         {
             Configuration = configuration;
         }
         public Startup(IConfiguration configuration, IWebHostEnvironment env)
         {
             Configuration = configuration;
             Env = env;
         }
    
         public IWebHostEnvironment Env { get; set; }
         public IConfiguration Configuration { get; }
    
         // This method gets called by the runtime. Use this method to add services to the container.
         public void ConfigureServices(IServiceCollection services)
         {
             services.AddRazorPages();
             services.AddSingleton<ServiceMgr>();
             services.AddAutoMapper(typeof(Startup));
    
             //if (Env.IsDevelopment()
             //{
    
             //}
         }
    
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
         public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
         {
             loggerFactory.AddLog4Net();
                
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
             }
             else
             {
                 app.UseExceptionHandler("/Home/Error");
                 // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                 app.UseHsts();
             }
             app.UseHttpsRedirection();
             app.UseStaticFiles();
    
             app.UseRouting();
    
             app.UseAuthorization();
    
             app.UseEndpoints(endpoints =>
             {
                 endpoints.MapControllers();
                 endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
             });
         }
     }

HomeController:

     public IActionResult Index()
     {
         _svcMgr.Test();

         _svcMgr._testStr = "Updated";
         mvm = _svcMgr.GetMainViewModel();
         mvm.JobBatch.StatusMsg = "Test Not started";


         return View(mvm);
     }
    public IActionResult DisplayJobs(string BatchID)
     {
         log.Info("HomeController.DisplayJobs - In Display Jobs");
         mvm = _svcMgr.GetMainViewModel(BatchID);
         //mvm.JobBatch = new JobBatchViewModel(BatchID); //** Fix this ASAP to do Read from Repo
           
         return PartialView("Jobs", mvm.JobBatch);
     }

ServiceMgr:

 public class ServiceMgr
 {
     Guid currentRequest = new Guid();

     ILog log = LogManager.GetLogger("Perf");

     private IMapper _mapper;

     public string _testStr = "";
     private ViewModels.JobMainViewModel _jmvm;


     public JobMainViewModel Jmvm { get => _jmvm; set => _jmvm = value; }

     public ServiceMgr(IMapper mapper)
     {
         _mapper = mapper;
         _jmvm = new ViewModels.JobMainViewModel();

     }

     public JobMainViewModel GetMainViewModel()
     {
         _jmvm.JobBatchList.BatchListItems = MapJobBatchList(GetJobBatchList());
         if (_jmvm.JobBatchList.SelectedID != -1)
         {
             string batchID = _jmvm.JobBatchList.SelectedID.ToString();

             _jmvm.JobBatch = _jmvm.JobBatchList.Find(t => t.ID == batchID);
             List<JobItem> jbi = GetJobBatchItems(batchID);

         }
         return _jmvm;

     }
     public JobMainViewModel GetMainViewModel(string BatchID)
     {
         //HERE is where the trouble shows up ****
         _jmvm.JobBatch = _jmvm.JobBatchList.Find(t => t.ID == BatchID);
         List<JobItem> jbi = GetJobBatchItems(BatchID);

         _jmvm.JobBatch.JobItems = MapJobBatchItems(jbi);

         return _jmvm;

     }

The first call to GetMainViewModel() seems to work great. I can see that _testStr gets and stays set to "Updated" by the Index() call. But once I do something on the Index page (selecting something from a dropdown and returning 'BatchID' via jQuery) and reach the DisplayJobs() controller method, things go wrong. If I set a breakpoint on the line starting with "//HERE" in ServiceMgr, I see that _testStr is still set to 'Updated', so I THINK I have the same instance of ServiceMgr, but the objects look like a new instance. If I look at _jmvm.JobBatchList, it is empty, but RawView is correctly populated with the object contents from the first call into ServiceMgr, which is what I want to access.

I have no idea what's going on there, but since I can't see that contents in the object itself I don't know how to proceed.











dotnet-csharpdotnet-aspnet-core-mvcvs-debugging
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

A singleton is accessible to every user in the application. I don't think a singleton is a good approach but then again the intent is not real clear.

What is JobBatchList. It seems to have a property SelectedID and at the same time it's a collection?

Can you describe the programming problem you are trying to solve?

0 Votes 0 ·

JobBatchList is a list of possible job batches to be run. Each job batch has multiple jobs, which is why it's called a Job Batch. The Selected ID is the index of the selected item from the dropdownList, but that's not material to the issue I'm having. It's just a common way to tell if something has been selected yet.

The reason for the Singleton is that the app is single user app. It could easily be a desktop app, but that doesn't fit the use case. I onl;y need/want a single instance of the ServiceMgr to manage all the job threads that make up the Batch. The jobs themselves can & will be long running, so those will be separate threads. All that is coded and working, but the ServiceMgr is being rewritten to better handle the GUI updates and some persistence & tracking.

Any thoughts on why the "Raw View" shows the intended contents of the List while the List variable itself shows a empty?

0 Votes 0 ·

Thought of a couple more details:

The flow you can see from the Index Method to the DisplayJobs Method in the Controller is this. Index displays the form with Dropdown for selecting a JobBatch to run. On the Dropdown change, javascript code does it's thing and then sends the selected item back to the DisplayJobs Method, which populates the Collection containing the list of JobItems to be run, which are then displayed as a table. It's the logic to populate the ViewModel with the rows to be displayed that is failing.

0 Votes 0 ·

1 Answer

RobertKing-4059 avatar image
0 Votes"
RobertKing-4059 answered

Sorry, found the problem - a combo of bad object naming and a nesting issue.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.