How to use .cs Class DataFunctions Inside MVC Controller Classes - asp.net-mvc

I have an asp.net web application, now i am trying to convert it to ASP.NET MVC. The problem is my old project has some .cs classes i, Example one class that handle all user data operations , one handle database operations , one will handle some priority properties like... I had included those classes in mvc Project , i had created a new Folder named Project_Class and copy all of my classes to it, my problem is how to access these classes in mvc controller class, how can i call a function of this class in mvc controller class.
I had include a sample .cs class structure below
**class1.cs**
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Text;
using System.Data.SqlClient;
using System.Xml;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace xyz.abc
{
public class AssignValues:SSS
{
Process Objdb;
SqlCommand sqlcom;
SqlConnection sqlcon;
private int _EId;
private int _CId;
XmlDocument PXML, OutputXML;
XmlElement Root, ParameterElement, InputParamIdNode, OperatorIdNode, OutputParamIdNode, OutputParamValueNode, ConditionStatusNode, ModeNode, InputTypeNode, OutputTypeNode, InputRegisterIdNode, InputRegisterHeaderIdNode, OutputRegisterIdNode, OutputRegisterHeaderIdNode, UIdNode, orderNode;
public int iCount = 0;
public int EId
{
set
{
_EId = value;
}
get
{
return _EId;
}
}
public int CId
{
set
{
_CId = value;
}
get
{
return _CId;
}
}
public AssignValues()
{
}
public AssignValues(SqlCommand SqlComm,SqlConnection SqlConn)
{
Objdb = new Process();
sqlcom=SqlComm;
sqlcon = SqlConn;
}
public string check()
{
string x="hai";
return x
}
}
}
my Controller class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using XYZ.ABC.Controllers;
using XYZ.ABC;
namespace XYZ.ABC.Controllers
{
public class XYZ_Controller :Controller
{
public ActionResult XYZ_Checklist()
{
return View();
}
}
}
i want to call "public string check()" method in my controller class,is it possible? ,i am newbie in mvc, please help me to solve this.

You can simply call that in your MVC controller class
Follow the steps
1) Include the namespace of the class in MVC controller class
2) Inherit old class in Your MVC Controller
Public Class MVCCOntrollerclassname: Class1
3) Create object of the .cs class
like
class1 c=new class1();
4) Create a constructor of MVC controller class
like
MVCCOntrollerclassname()
{
c.methodname();
}
Note : You say you are migrating asp.net to MVC , so if you have any asp.net dll then must change it as MVC Compitable dll

The MVC Framework just instantiates your Controller class and invokes an action method using some defined configuration or convention. So with that in mind ask yourself the question how would I invoke this method if you instantiated the controller yourself and called XYZ_Checklist().
The answer may look something like this:
public ActionResult XYZ_Checklist()
{
var assignValues = new AssignValues();
var result = assignValues.check();
// Do something here with the result ...
return View();
}
That's the short and simple answer. Once you start to understand that the framework isn't magic and is simply calling your code, you can start to delve into better ways to arrange your code (IoC/DI, etc.).
Hope this helps!

Related

Object reference not set to an instance of an object MVC 5

I'm new to MVC working on 3-tier MVC project and i am using a ready database.
now i need to write a query using linq in Business Layer to bring list of doctors like this :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DoctorsSheet.DataAccess;
namespace DoctorsSheet.Business
{
class Doctor : IDoctor
{
DoctorsSheetDBEntities db = new DoctorsSheetDBEntities();
public IQueryable<Doctors> GetDoctors()
{
var doctors = from d in db.Doctors
select d;
return doctors.AsQueryable<Doctors>();
}
}
}
and when i call GetDoctors() from DoctorsController
it tell me Object reference not set to an instance of an object
this is the Controller :
public ActionResult Index()
{
var doctors = obj.GetDoctors().AsQueryable<Doctors>();
return View(doctors);
}
please help me how to fix it.
Make your class public -
public class Doctor : IDoctor
And then initiate obj variable as shown below and then use obj.
IDoctor obj = new Doctor();
NOTE: As #Sippy explained there is no need for you to use GetDoctors().AsQueryable<Doctors>();.

Is it possible to select an Action with AttributeRouting in .NET MVC based on the Media Type of the Accept header?

I want to select an Action of my Controller based on the Media Type requested in the Accept header.
For example, I have a resource called a subject. Its assigned route is:
GET /subjects/{subjectId:int}
Normally, the browser is requesting text/html, which is fine. The default Media Formatter handles this great.
Now, I have custom logic I want to perform when this same route is accessed with an accept header specifying application/pdf as the accepted Media Type.
I could create a custom Media Formatter, but, to my understanding, this would mean that any route that is requested with the Accept header set to application/pdf would also run through this Media Formatter. This is unacceptable.
In Java, there is an annotation called #Produces:
The #Produces annotation is used to specify the MIME media types or
representations a resource can produce and send back to the client. If
#Produces is applied at the class level, all the methods in a resource
can produce the specified MIME types by default. If applied at the
method level, the annotation overrides any #Produces annotations
applied at the class level.
This would allow me to do the following:
namespace MyNamespace
{
[RoutePrefix("subjects")]
public class SubjectsController : Controller
{
[Route("{subjectId:int}")]
[HttpGet]
public ActionResult GetSubject(int subjectId)
{
}
[Route("{subjectId:int}")]
[HttpGet]
[Produces("application/pdf")]
public ActionResult GetSubjectAsPdf(int subjectId)
{
//Run my custom logic here to generate a PDF.
}
}
}
There is no Produces Attribute in .NET that I can find, of course, so this doesn't work. I haven't been able to find a similar attribute, either.
I could of course manually check the header within the body of the action, and redirect it to another action, but that seems hackish at best.
Is there a mechanism in .NET 4.5 that I may use to pull this off that I'm overlooking or missing?
(I'm using MVC 5.2.2 from NuGet repository)
After searching around the Internet for awhile, I came up with the idea that this would be best accomplished by creating an ActionMethodSelectorAttribute.
The following is a very naive, first-pass implementation of a ProducesAttribute that I wrote with the eventual intent of mimicking Java's Produces annotation:
namespace YourNamespace
{
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Mime;
using System.Web.Mvc;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class ProducesAttribute : ActionMethodSelectorAttribute
{
private readonly ISet<ContentType> acceptableMimeTypes;
public ProducesAttribute(params string[] acceptableMimeTypes)
{
this.acceptableMimeTypes = new HashSet<ContentType>();
foreach (string acceptableMimeType in acceptableMimeTypes)
this.acceptableMimeTypes.Add(new ContentType(acceptableMimeType));
}
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
string acceptHeader = controllerContext.RequestContext.HttpContext.Request.Headers[HttpRequestHeader.Accept.ToString()];
string[] headerMimeTypes = acceptHeader.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
foreach (var headerMimeType in headerMimeTypes)
{
if (this.acceptableMimeTypes.Contains(new ContentType(headerMimeType)))
return true;
}
return false;
}
}
}
It is meant to be used with Attribute Routing, and can be applied as follows:
public sealed class MyController : Controller
{
[Route("subjects/{subjectId:int}")] //My route
[Produces("application/pdf")]
public ActionResult GetSubjectAsPdf(int subjectId)
{
//Here you would return the PDF representation.
}
[Route("subjects/{subjectId:int}")]
public ActionResult GetSubject(int subjectId)
{
//Would handle all other routes.
}
}

LINQ and MVC controller query

Hi this should be a really simple problem with actual LINQ knowledge unlike me! I want to return only the last 20 records and normally .Take(20) when ordered by descending works but because I'm returning an instance of the model.CPU I don't know where to put the statement.
Help would be greatly appreciated, have been Googling for the past hour or so.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
namespace hello_services.Controllers
{
public class cpuController : ApiController
{
private Data.ResourceDataModelDataContext _context = new Data.ResourceDataModelDataContext();
//WebAPI will respond to an HTTP GET with this method
public List<Models.CPU> Get()
{
//get all of the records from the Counter_CPU table
var cpuRecords = from e in _context.Counter_CPUs
select new Models.CPU
{
Counter_CPU_ID = e.Counter_CPU_ID,
//Counter_CPU_Time = e.Counter_CPU_Time,
Counter_CPU_Percentage = e.Counter_CPU_Percentage
};
return cpuRecords.ToList();
}
}
}
You can
Order the query (desc) and then select your Models.CPU class with take(20) as last statement
Order your result before using the .ToList() (before executing the query on the db)
e.g.
return cpuRecords.OrderByDesc(o => o.Counter_CPU_ID).Take(20).ToList();

Get nesting level of view in ASP.NET MVC 4

I've been searching for a way to determine the "nesting level" of a view. I've found: Determine view 'nesting level' here on stackoverflow.com. But that only works with RenderAction and only says if it is a child view or not.
What I would like is that layout has level 0, views rendered in layout (e.g. with #RenderBody()) has level 1, views rendered in that view (e.g. with #Html.Partial(...)) has level 2.
For example:
_Layout.cshtml (0)
_LoginPartial.cshtml (1)
Index.cshtml (1)
DataTable.cshtml (2)
DataHeader.cshtml (3)
DataRow.cshtml (3)
Do anyone have a solution for this?
After some investigation I found a static class System.Web.WebPages.TemplateStack that is used when executing views, pushing template on to stack before execution and popping after execution so the size of the stack can be used to determine the level. There is no count variable or any public property/method to get the actual stack. However there is a private method GetStack(HttpContextBase).
I solved it by using reflection and a extension method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
using System.Reflection;
using System.Collections;
namespace Mollwe.Helpers
{
public static class TemplateStackLevelAccessor
{
private static MethodInfo _getStackMethod;
public static int GetTemplateLevel(this HtmlHelper htmlHelper)
{
return GetTemplateLevel(htmlHelper.ViewContext);
}
public static int GetTemplateLevel(this ViewContext viewContext)
{
return GetTemplateLevel(viewContext.HttpContext);
}
public static int GetTemplateLevel(this HttpContextBase httpContext)
{
if (_getStackMethod == null)
{
_getStackMethod = typeof(TemplateStack).GetMethod("GetStack", BindingFlags.NonPublic | BindingFlags.Static);
}
var stack = _getStackMethod.Invoke(null, new object[] { httpContext }) as Stack<ITemplateFile>;
return stack.Count - 1;
}
}
}
Maybe not the best way but it works. As the stack is used within execution of view it will only work in views or in code called from views.
Dependant on System.Web.WebPages.WebPageBase's implementation of ExecutePageHierarchy() that is called in derived type System.Web.Mvc.WebViewPage which is used in RazorView.RenderView(...).
For anyone looking to do this in ASP.Net Core, you need to implement your own ViewResultExecutor. You can intercept all 'ExecuteAsync()' calls, which get nested, allowing one to build their own nesting level.
See here for more details: Hooking into razor page execution for ASP.Net Core

Does it make sense to have Business Logic within a ViewModel in MVC?

At the moment I'm working on Asp.Net MVC using: Repository, Unit-Of-Work patterns, Service Layer and ViewModels.
In this project every View is linked to a ViewModel Class, the Controllers are thin-one, so the Business Layer reside on a Service Layer.
I create instances of ViewModel class in the Controller and pass it to the view like this
public ActionResult Create()
{
EventCreateViewModel eventViewModel = new EventCreateViewModel();
return View(eventViewModel);
}
In some ViewModel I use to call the Service Layer.
The system works, but I would like to know if it is a good idea adding call to a Service Layer in the ViewModel or better would be leave this operation only to the Controller.
public class EventCreateViewModel
{
public CandidateListViewModel CandidateList = new CandidateListViewModel();
public EventCreateViewModel()
{
DateTimeStart = DateTime.UtcNow; // Add a default value when a Date is not selected
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using XXX.Models;
using XXX.Service;
namespace XXX.ViewModels
{
public class CandidateListViewModel
{
// We are using the Service Layer
private ICandidateBL serviceCandidate;
// Property
public IDictionary<string, string> Candidates = new Dictionary<string, string>();
// An utility method that convert a list of Canddates from Enumerable to SortedDictionary
// and save the result to an inner SortedDictionary for store
public void ConvertSave(IEnumerable<Candidate> candidates)
{
Candidates.Add("None", "0"); // Add option for no candidate
foreach (var candidate in candidates)
Candidates.Add(candidate.Nominative, candidate.CandidateId.ToString());
}
#region Costructors
public CandidateListViewModel()
{
serviceCandidate = new CandidateBL();
ConvertSave(serviceCandidate.GetCandidates());
}
// Dependency Injection enabled constructors
public CandidateListViewModel(ICandidateBL serviceCandidate)
{
this.serviceCandidate = serviceCandidate;
}
public CandidateListViewModel(IEnumerable<Candidate> candidates)
{
serviceCandidate = new CandidateBL();
ConvertSave(candidates);
}
#endregion
}
}
The controller is the component that should be in control, so to say. The ViewModel should just be a data container, nothing more.
Remember the Single Responsibility Principle. Once you start distributing logic it will become increasingly difficult to remember and understand all the moving parts.

Resources