I have an application using ASP.NET Core, Angular 5 And ADO.NET
It worked fine until I decided to change the code to set a session variable with a database connection string gotten from my appssettings.json file.
I am using this as a reference: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-2.2
However, when I try to set the session variable, I get a Null object reference in my SetSessionVariable() method.
Error is:
An error occurred while starting the application.
NullReferenceException: Object reference not set to an instance of an
object. Angular5NetcoreAdo.Startup.SetSessionVariable() in Startup.cs,
line 82
My code is:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Angular5NetcoreAdo.Models;
// Added these.
using Microsoft.AspNetCore.Http;
using System;
namespace Angular5NetcoreAdo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// Added this.
public HttpContext HttpContext { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// In production, the Angular files will be served from this directory.
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddScoped<EmployeeDataAccessLayer>();
// Added this.
services.AddSession(options =>
{
options.Cookie.Name = ".ConnectionString";
});
// Added this.
SetSessionVariable();
}
// Added this.
public void SetSessionVariable()
{
HttpContext.Session.SetString("ConnectionString", Convert.ToString(Configuration.GetConnectionString("DBAngular5NetcoreAdoDatabase")));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseSpaStaticFiles();
// Added this.
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
}
---- Per a suggestion below, I am including that code here:
// Middleware extension method.
using Microsoft.AspNetCore.Builder;
namespace Angular5NetcoreAdo
{
public static class RequestConnectionMiddlewareExtensions
{
public static IApplicationBuilder UseRequestConnection(this
IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestConnectionMiddleware>();
}
}
}
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using System;
using Microsoft.Extensions.Configuration;
namespace Angular5NetcoreAdo
{
public class RequestConnectionMiddleware
{
public IConfiguration Configuration { get; }
public HttpContext HttpContext { get; }
private readonly RequestDelegate _next;
public RequestConnectionMiddleware(RequestDelegate next,
IConfiguration configuration)
{
_next = next;
Configuration = configuration;
}
public async Task InvokeAsync(HttpContext context)
{
// Set the session variable with the database connection string from appsettings.json.
HttpContext.Session.SetString("ConnectionString", Convert.ToString(Configuration.GetConnectionString("DBAngular5NetcoreAdoDatabase")));
await _next(context);
}
}
}
Now in the Startup.cs, I call the new middleware message method after the app.UseSession();
app.UseSession();
// Call the middlware now to set the session variable with the database
// connection string from appsettings.json.
app.UseRequestConnection();
------------------ Added now as a new error refers to this class.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Http;
namespace Angular5NetcoreAdo.Models
{
public class EmployeeDataAccessLayer
{
public HttpContext HttpContext { get; }
public string connectionString;
public EmployeeDataAccessLayer(HttpContext httpContext)
{
// Set the property.
HttpContext = httpContext;
// Get the connection string session variable.
connectionString = HttpContext.Session.GetString("ConnectionString");
}
public IEnumerable<Employee> GetAllEmployees()
{
try
{
List<Employee> lstemployee = new List<Employee>();
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("SelectEmployees", con);
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Employee employee = new Employee();
employee.ID = Convert.ToInt32(rdr["EmployeeID"]);
employee.Name = rdr["Name"].ToString();
employee.Gender = rdr["Gender"].ToString();
employee.Department = rdr["Department"].ToString();
employee.City = rdr["City"].ToString();
lstemployee.Add(employee);
}
rdr.Close();
con.Close();
}
return lstemployee;
}
catch
{
throw;
}
}
public Employee GetEmployeeData(int id)
{
try
{
Employee employee = new Employee();
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("SelectEmployeeById", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#EmpId", id);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
employee.ID = Convert.ToInt32(rdr["EmployeeID"]);
employee.Name = rdr["Name"].ToString();
employee.Gender = rdr["Gender"].ToString();
employee.Department = rdr["Department"].ToString();
employee.City = rdr["City"].ToString();
}
rdr.Close();
con.Close();
}
return employee;
}
catch
{
throw;
}
}
public int AddEmployee(Employee employee)
{
try
{
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("InsertEmployee", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Name", employee.Name);
cmd.Parameters.AddWithValue("#City", employee.City);
cmd.Parameters.AddWithValue("#Department", employee.Department);
cmd.Parameters.AddWithValue("#Gender", employee.Gender);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
return 1;
}
catch
{
throw;
}
}
public int UpdateEmployee(Employee employee)
{
try
{
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("UpdateEmployee", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#EmpId", employee.ID);
cmd.Parameters.AddWithValue("#Name", employee.Name);
cmd.Parameters.AddWithValue("#City", employee.City);
cmd.Parameters.AddWithValue("#Department", employee.Department);
cmd.Parameters.AddWithValue("#Gender", employee.Gender);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
return 1;
}
catch
{
throw;
}
}
public int DeleteEmployee(int id)
{
try
{
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("DeleteEmployee", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#EmpId", id);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
return 1;
}
catch
{
throw;
}
}
}
}
Its because documentation says
HttpContext.Session can't be accessed before UseSession has been
called.
and you call it in ConfigurationServices method where HttpContext.Session does not exist yet.
So you will need create your own middleware and call it after UseSession() method in Configure method.
Related
In ASP.NET Core-6 Web API, this Basic Auth code to be used as an header for my POST, PUT and Get Requests:
--header 'Authorization: Basic GGATEIIIFFFF12234JJKKKKKFFFFFFFFFFFFFF'
In my appsettings.Json, I have the credential as shown below:
"BasicCredentials": {
"username": "Akwetey",
"password": "#12345677**87" //Basic Auth
},
Then I have this Get Request:
public IEnumerable<Employee> GetEmployees()
{
List<Employee> employeelist = new List<Employee>();
using (con = new SqlConnection(connection))
{
con.Open();
command = new SqlCommand("sp_employees", con);
command.CommandType = CommandType.StoredProcedure;
dataReader = command.ExecuteReader();
while (dataReader.Read())
{
Employee employee = new Employee();
employee.EmployeeId = Convert.ToInt32(dataReader["EmployeeId"]);
employee.Firstname = dataReader["Firstname"].ToString();
employee.Lastname = dataReader["Lastname"].ToString();
employee.Email = dataReader["Email"].ToString();
employee.EmploymentDate = Convert.ToDateTime(dataReader["EmploymentDate"].ToString());
employeelist.Add(employee);
}
con.Close();
}
return employeelist;
}
How do I authorise the Get Get Request code above using the Basic Auth Credentials as the header?
Thanks
You would need to add something along these lines
builder.Services.AddAuthentication()
.AddScheme<MyAuthenticationOptions, MyAuthenticationHandler>(MyAuthenticationSchemeName, options => {});
Where:
public class MyAuthenticationOptions : AuthenticationSchemeOptions
{}
and
public class MyAuthenticationHandler : AuthenticationHandler<MyAuthenticationOptions>
{
private IConfiguration Configuration;
public MyAuthenticationHandler(
IOptionsMonitor<MyAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock,
IConfiguration configuration
) : base(options, logger, encoder, clock)
{
Configuration = configuration;
}
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
{
// Get the header
string authHeader = Request.Headers[HeaderNames.Authorization];
// Parse config this way
var pwd = Configuration.GetValue<string>("BasicCredentials:password")
// Check if the header is valid comparing to your config
// Create here your claims principal
ClaimsPrincipal principal;
//...//
var ticket = new AuthenticationTicket(principal, Scheme.Name);
return AuthenticateResult.Success(ticket);
// Or otherwise
return AuthenticateResult.Fail("Invalid secret.");
}
}
Then finally, you can have an authed controller like this
[Authorize]
[HttpGet("employees")]
public IEnumerable<Employee> GetEmployees()
{
List<Employee> employeelist = new List<Employee>();
using (con = new SqlConnection(connection))
{
con.Open();
command = new SqlCommand("sp_employees", con);
command.CommandType = CommandType.StoredProcedure;
dataReader = command.ExecuteReader();
while (dataReader.Read())
{
Employee employee = new Employee();
employee.EmployeeId = Convert.ToInt32(dataReader["EmployeeId"]);
employee.Firstname = dataReader["Firstname"].ToString();
employee.Lastname = dataReader["Lastname"].ToString();
employee.Email = dataReader["Email"].ToString();
employee.EmploymentDate = Convert.ToDateTime(dataReader["EmploymentDate"].ToString());
employeelist.Add(employee);
}
con.Close();
}
return employeelist;
}
This is the BasicAuthenticationHandler implementation from dotnetthoughts modified to read the credentials from appsettings.json using IConfiguration:
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
private readonly IConfiguration _configuration;
public BasicAuthenticationHandler(
IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock,
IConfiguration configuration) : base(options, logger, encoder, clock)
{
_configuration = configuration;
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var authHeader = Request.Headers["Authorization"].ToString();
if (authHeader != null && authHeader.StartsWith("basic", StringComparison.OrdinalIgnoreCase))
{
var token = authHeader.Substring("Basic ".Length).Trim();
Console.WriteLine(token);
var credentialstring = Encoding.UTF8.GetString(Convert.FromBase64String(token));
var credentials = credentialstring.Split(':');
var username = _configuration["BasicCredentials:username"];
var password = _configuration["BasicCredentials:password"];
if (credentials[0] == username && credentials[1] == password)
{
var claims = new[] { new Claim("name", credentials[0]), new Claim(ClaimTypes.Role, "Admin") };
var identity = new ClaimsIdentity(claims, "Basic");
var claimsPrincipal = new ClaimsPrincipal(identity);
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, Scheme.Name)));
}
Response.StatusCode = 401;
Response.Headers.Add("WWW-Authenticate", "Basic realm=\"dotnetthoughts.net\"");
return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header"));
}
else
{
Response.StatusCode = 401;
Response.Headers.Add("WWW-Authenticate", "Basic realm=\"dotnetthoughts.net\"");
return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header"));
}
}
}
I have used Entity Framework for a long time, but have an edge case where I need to use SQL. I was wondering if I could use my existing Entity Framework Core context for this or not. Here is what I have currently, but the queryResults variable contains a "-1" value, instead of a list of Students, after running it:
string tableName = "Students";
var queryResults = db.Database.ExecuteSqlRaw(#"SELECT * FROM {0}", tableName);
Any ideas?
Entity Framework Core 3.1
.NET Core 3.1
Linq-to-SQL
It is possible; I just had to do this for a pet project.
You need to reference the Microsoft.EntityFrameworkCore.Relational NuGet.
ConsoleApp Example:
Program.cs
using System.Collections.Generic;
namespace EfDirectSql
{
class Program
{
/*
* written: VS2019 .Net Core 3.1 Console App
*
* used nugets:
*
* Microsoft.EntityFrameworkCore.SqlServer 3.1.0
* Microsoft.EntityFrameworkCore.Relational 3.1.0
*
*/
static void Main(string[] args)
{
// attention: supply your database server name
ApplicationContext context = new ApplicationContext("?YOURSERVER?", "Master");
// note: leveraging included extension methods for the dbContext class.
object scalarResult = context.ExecuteScalar("SELECT COUNT(1) FROM Master.dbo.SysObjects");
object nonQueryResult = context.ExecuteNonQuery("SELECT * FROM Master.dbo.SysObjects"); // likely your -1
IEnumerable<SysObject> readerResult = context.ExecuteReader<SysObject>("SELECT * FROM Master.dbo.SysObjects");
}
}
}
ApplicationContext.cs
using Microsoft.EntityFrameworkCore;
namespace EfDirectSql
{
public class ApplicationContext
: DbContext
{
public ApplicationContext(string serverName, string catalogName)
{
this.ServerName = serverName;
this.CatalogName = catalogName;
}
public readonly string ServerName;
public readonly string CatalogName;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer($"Data Source={this.ServerName};Initial Catalog={this.CatalogName};Integrated Security=true;");
base.OnConfiguring(optionsBuilder);
}
}
}
DbContextExtensions.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
namespace EfDirectSql
{
public static class DbContextExtensions
{
public static object ExecuteScalar
(
this DbContext context,
string sql
)
{
IDbConnection connection = context.Database.GetDbConnection();
IDbCommand command = connection.CreateCommand();
object result = null;
try
{
connection.Open();
command.CommandText = sql;
command.CommandType = CommandType.Text;
result = command.ExecuteScalar();
}
finally
{
connection.Close();
}
return result;
}
public static int ExecuteNonQuery
(
this DbContext context,
string sql
)
{
IDbConnection connection = context.Database.GetDbConnection();
IDbCommand command = connection.CreateCommand();
int result;
try
{
connection.Open();
command.CommandText = sql;
command.CommandType = CommandType.Text;
result = command.ExecuteNonQuery();
// likely the -1
}
finally
{
connection.Close();
}
return result;
}
public static IEnumerable<TType> ExecuteReader<TType>
(
this DbContext context,
string sql
)
where TType : class, new()
{
IDbConnection connection = context.Database.GetDbConnection();
IDbCommand command = connection.CreateCommand();
IEnumerable<TType> result = new List<TType>();
try
{
connection.Open();
command.CommandText = sql;
command.CommandType = CommandType.Text;
IDataReader reader = command.ExecuteReader(CommandBehavior.Default);
result = Convert<TType>(reader);
}
finally
{
connection.Close();
}
return result;
}
private static IEnumerable<TType> Convert<TType>(IDataReader reader)
where TType : class, new()
{
List<PropertyInfo> properties = typeof(TType)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanWrite)
.ToList();
IList<TType> instances = new List<TType>();
while (reader.Read())
{
TType instance = new TType();
properties
.ForEach
(p =>
// for the purposes of the example, this works - could be outliers.
p.SetValue(instance, reader[p.Name] == DBNull.Value ? null : reader[p.Name])
);
instances.Add(instance);
}
return instances;
}
}
}
SysObject.cs
namespace EfDirectSql
{
// shortened represenation of the MS-SQL sysobject table
public class SysObject
{
public string name { get; set; }
public int id { get; set; }
public string xtype { get; set; }
public int uid { get; set; }
public int info { get; set; }
public int status { get; set; }
// the rest are not needed for a demo.
}
}
"I was wondering if I could use my existing Entity Framework Core context for this or not":
Yes you can use your existing databaseContext but you have to execute that query on your dbContext Entity see the example below:
var sqlCommand = $"SELECT * FROM Students";
var executeSQL = await _context.Students.FromSqlRaw(sqlCommand).ToListAsync();
return Ok(executeSQL);
Output:
Note: As you can see I am executing sqlCommand on Students dbContext this is valid. But using DbContext you cannot pass the
table name dynamically. You must need to define it explicitly.
Hope above steps guided you accordingly, You can have a look on official document for more details here
Update Using Ado.Net Connection:
using (var connection = _context.Database.GetDbConnection())
{
connection.Open();
var tableName = "Students";
List<Student> _listStudent = new List<Student>();
var command = connection.CreateCommand();
command.CommandType = CommandType.Text;
command.CommandText = string.Format("SELECT * FROM [{0}];", tableName);
SqlDataReader reader = (SqlDataReader)command.ExecuteReader();
while (reader.Read())
{
var student = new Student(); // You have to bind dynamic property here based on your table entities
student.FirstName = reader["FirstName"].ToString(); // Remember Type Casting is required here it has to be according to database column data type
student.LastName = reader["LastName"].ToString();
_listStudent.Add(student);
}
reader.Close();
command.Dispose();
connection.Close();
}
I want write autorization system in asp.net - user of Postgres (which created throws CREATE ROLE...) entering login and password and working with own tables. Problem is i working in ASP.NET core and connecting throws Dapper.
appsettings.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"DBInfo": {
"Name": "coresample",
"ConnectionString": "User ID=username;Password=userpassword;Host=localhost;Port=5432;Database=Documents;Pooling=true;"
}
}
DocumentsRepository
public class DocumentsRepository : IRepository<Documents>
{
private string connectionString;
public DocumentsRepository(IConfiguration configuration, string login, string password)
{
connectionString = configuration.GetValue<string>("DBInfo:ConnectionString");
connectionString = connectionString.Replace("username", login);
connectionString = connectionString.Replace("userpassword", password);
}
internal IDbConnection Connection
{
get
{
return new NpgsqlConnection(connectionString);
}
}
public void Add(Documents item)
{
using (IDbConnection dbConnection = Connection)
{
dbConnection.Open();
dbConnection.Execute("SELECT addrecuserdocuments(#DocumentName,#Contents,#DocumentIntroNumber)", item);
}
}
public IEnumerable<Documents> FindAll()
{
using (IDbConnection dbConnection = Connection)
{
dbConnection.Open();
return dbConnection.Query<Documents>("SELECT * FROM selectdata()");
}
}
DocumentController
public class DocumentsController : Controller
{
private readonly DocumentsRepository dRepository;
public DocumentsController(IConfiguration configuration)
{
dRepository = new DocumentsRepository(configuration);
}
public IActionResult Index()
{
return View(dRepository.FindAll());
}
public IActionResult Create()
{
return View();
}
// POST: Documents/Create
[HttpPost]
public IActionResult Create(DocumentViewModel dvm)
{
Documents docs = new Documents { DocumentName = dvm.DocumentName, DocumentIntroNumber = dvm.DocumentIntroNumber };
if (ModelState.IsValid)
{
if (dvm.Contents != null)
{
byte[] imageData = null;
using (var binaryReader = new BinaryReader(dvm.Contents.OpenReadStream()))
{
imageData = binaryReader.ReadBytes((int)dvm.Contents.Length);
}
docs.Contents = imageData;
}
dRepository.Add(docs);
return RedirectToAction("Index");
}
return View(docs);
}
In Startup.cs i connection throws
services.AddSingleton(Configuration);
Please, help me understand, how i can call connection string and transfering login and password of user? And where? And is it possible?
Please, i realy need help with this!
Error 1
'UserWcfService.userService' does not implement interface member
'UserWcfService.IuserService.Getuserdetails()'.
'UserWcfService.userService.Getuserdetails()' cannot implement an
interface member because it is not
public. C:\Users\ravi\Documents\Visual Studio
2013\Projects\wcfservices\UserWcfService\UserWcfService\userService.svc.cs 16 18 UserWcfService
userservice.svc.cs code:
namespace UserWcfService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "userService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select userService.svc or userService.svc.cs at the Solution Explorer and start debugging.
public class userService : IuserService
{
public string str = ConfigurationManager.ConnectionStrings["connstring"].ToString();
List<usertype> Getuserdetails()
{
List<usertype> userdetails=new List<usertype>();
SqlConnection conn = new SqlConnection(str);
{
conn.Open();
SqlCommand cmd = new SqlCommand("spgetdata", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
for(int i=0; i<dt.Rows.Count; i++)
{
usertype objinfo = new usertype();
objinfo.name = Convert.ToString(dt.Rows[i]["name"]);
objinfo.gender = Convert.ToString(dt.Rows[i]["gender"]);
objinfo.dateofbirth = Convert.ToDateTime(dt.Rows[i]["dateofbirth"]);
objinfo.address = Convert.ToString(dt.Rows[i]["address"]);
objinfo.contactno = Convert.ToInt32(dt.Rows[i]["contactno"]);
objinfo.mailid = Convert.ToString(dt.Rows[i]["mailid"]);
userdetails.Add(objinfo);
}
}
conn.Close();
}
return userdetails;
}
public string newuser(usertype user)
{
string strmessage;
SqlConnection conn = new SqlConnection(str);
{
conn.Open();
SqlCommand cmd = new SqlCommand("spinsert", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#C_Users_Name", user.name);
cmd.Parameters.AddWithValue("#C_Users_Gender", user.gender);
cmd.Parameters.AddWithValue("#lC_Users_DOB", user.dateofbirth);
cmd.Parameters.AddWithValue("#C_Users_Address", user.address);
cmd.Parameters.AddWithValue("#C_Users_ContactNo", user.contactno);
cmd.Parameters.AddWithValue("#C_Users_MailID", user.mailid);
//cmd.Parameters.AddWithValue("#C_Users_RegisteredDate", userinfo.date);
int result = cmd.ExecuteNonQuery();
if(result==1)
{
strmessage = user.name + "details inserted succesfully";
}
else
{
strmessage = user.name + "Details not inserted";
}
conn.Close();
}
return strmessage;
}
}
}
and IUserService code:
namespace UserWcfService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IuserService" in both code and config file together.
[ServiceContract]
public interface IuserService
{
[OperationContract]
List<usertype> Getuserdetails();
[OperationContract]
string newuser(usertype user);
}
[DataContract]
public class usertype
{
[DataMember]
public string name { get; set; }
[DataMember]
public string gender { get; set; }
[DataMember]
public DateTime dateofbirth { get; set; }
[DataMember]
public string address { get; set; }
[DataMember]
public int contactno { get; set; }
[DataMember]
public string mailid { get; set; }
[DataMember]
public DateTime date { get; set; }
}
}
All interface methods are by default public therefore your class which dervies interface needs to be public as well.
A good way to see what you are doing wrong here is to right click on the IuserService in
public class userService : IuserService
go to implement interface -> implement interface explicitly
this will create the stub methods that are implementing your interface. you can either drop your code into those or you could adjust the methods that you have appropriately
Here is an example which built I derived using the method I described above
public class userService : IuserService
{
public string str = ConfigurationManager.ConnectionStrings["connstring"].ToString();
List<usertype> IuserService.Getuserdetails()
{
List<usertype> userdetails = new List<usertype>();
SqlConnection conn = new SqlConnection(str);
{
conn.Open();
SqlCommand cmd = new SqlCommand("spgetdata", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
usertype objinfo = new usertype();
objinfo.name = Convert.ToString(dt.Rows[i]["name"]);
objinfo.gender = Convert.ToString(dt.Rows[i]["gender"]);
objinfo.dateofbirth = Convert.ToDateTime(dt.Rows[i]["dateofbirth"]);
objinfo.address = Convert.ToString(dt.Rows[i]["address"]);
objinfo.contactno = Convert.ToInt32(dt.Rows[i]["contactno"]);
objinfo.mailid = Convert.ToString(dt.Rows[i]["mailid"]);
userdetails.Add(objinfo);
}
}
conn.Close();
}
return userdetails;
}
public string newuser(usertype user)
{
string strmessage;
SqlConnection conn = new SqlConnection(str);
{
conn.Open();
SqlCommand cmd = new SqlCommand("spinsert", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#C_Users_Name", user.name);
cmd.Parameters.AddWithValue("#C_Users_Gender", user.gender);
cmd.Parameters.AddWithValue("#lC_Users_DOB", user.dateofbirth);
cmd.Parameters.AddWithValue("#C_Users_Address", user.address);
cmd.Parameters.AddWithValue("#C_Users_ContactNo", user.contactno);
cmd.Parameters.AddWithValue("#C_Users_MailID", user.mailid);
//cmd.Parameters.AddWithValue("#C_Users_RegisteredDate", userinfo.date);
int result = cmd.ExecuteNonQuery();
if (result == 1)
{
strmessage = user.name + "details inserted succesfully";
}
else
{
strmessage = user.name + "Details not inserted";
}
conn.Close();
}
return strmessage;
}
I am retrieving records from store procedure, but it does not bind data into view.
Here is ModelContext class:
namespace MyTesting.Models
{
public class TvSerialDB
{
public static string constr = ConfigurationManager.ConnectionStrings["TvSerialContext"].ConnectionString;
SqlConnection con;
SqlCommand cmd;
public IEnumerable<TVSerialByGroup> tvserialgroupby(string serialname)
{
List<TVSerialByGroup> tvserials = new List<TVSerialByGroup>();
using (con = new SqlConnection(constr))
{
cmd = new SqlCommand("pSerialListGroupBySerialName", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#SerialName", SqlDbType.VarChar, 100).Value = serialname;
con.Open();
SqlDataReader sdr = cmd.ExecuteReader();
while (sdr.Read())
{
TVSerialByGroup tvs = new TVSerialByGroup();
tvs.Series_Name = sdr["Series_Name"].ToString();
tvs.Image_Url_Big = sdr["Image_Url_Big"].ToString();
tvs.Season_No = sdr["Season_No"].ToString();
tvs.TotalEpisode = sdr["TotalEpisode"].ToString();
}
}
return tvserials;
}
}
}
Here is ModelClass:
namespace MyTesting.Models
{
public class TVSerialByGroup
{
public string Series_Name { get; set; }
public string Season_No { get; set; }
public string Image_Url_Big { get; set; }
public string TotalEpisode { get; set; }
}
}
Here is controller class:
public ActionResult ListAllSeason(string serial)
{
try
{
TvSerialDB tvcon = new TvSerialDB();
List<TVSerialByGroup> tv = tvcon.tvserialgroupby(serial).ToList();
return View(tv);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
When i run this application it does not display any record nor it gives error.
When i debug this code through breakpoint it returns rows into store procedure but in views it does not bind data.
You not adding your model instances to the collection.
while (sdr.Read())
{
TVSerialByGroup tvs = new TVSerialByGroup();
tvs.Series_Name = sdr["Series_Name"].ToString();
tvs.Image_Url_Big = sdr["Image_Url_Big"].ToString();
tvs.Season_No = sdr["Season_No"].ToString();
tvs.TotalEpisode = sdr["TotalEpisode"].ToString();
tvserials.Add(tvs); // add this
}
Side note: Since your initializing List<TVSerialByGroup>, you can make your method public List<TVSerialByGroup> tvserialgroupby(string serialname) and then you do not need .ToList(); in the ActionResult method.