How do I store emails into my SQL server database? - c#

I am trying to store emails into my SQL server database. These emails I got from Exchange Webservices.
I am using entity Framework and made a ADO .Net Data Model.
My Question is how do I make a method(StoreEmail) that stores these emails into my database.
This is my StoreEmail method that I got so far:
It should store my PhishingMails...
public object StoreMail(Model.PhishingMail PhishingMail)
{
using (var phishingMailStorage = new PhishFinderModel())
{
PhishingMail = MailMapper.Map(Model.PhishingMail);
phishingMailStorage.PhishingMails.Add();
phishingMailStorage.SaveChanges();
return PhishingMail;
}
}
In Mailmapper class I set the properties that I want to store, which are Sender, Subject and Body:
public static PhishingMail Map(EmailMessage OutlookMail)
{
PhishingMail readMail = new PhishingMail();
readMail.Sender = OutlookMail.Sender.Address;
readMail.Body = OutlookMail.Body;
return readMail;
}
This is my DB schema
To clarify my question, I already get the list of emails from the exchange server. Now, all I need to do is insert them into the SQL server.
How do I make my StoreEmail method work to do this?
Please don't be harsh I am really new to this. It feels like I am swimming in an ocean of information and I don't know where to look or start. So any suggested tutorials are very welcome.
Thanks!

You're storing PhishingMail, and you're receiving a PhishingMail, so you don't need your mapping step.
Does this not work?
public void StoreMail(Model.PhishingMail PhishingMail)
{
using (var phishingMailStorage = new PhishFinderModel())
{
phishingMailStorage.PhishingMails.Add(PhishingMail);
phishingMailStorage.SaveChanges();
}
}
You don't need to return the mail, either, since the caller already has it (and it's a lot tidier to have a void return if you're not returning a new/different object.
If you actually need to store an EmailMessage, your method should be:
public void StoreMail(EmailMessage emailMessage)
{
var phishingMail = MailMapper.Map(emailMessage);
using (var phishingMailStorage = new PhishFinderModel())
{
phishingMailStorage.PhishingMails.Add(phishingMail);
phishingMailStorage.SaveChanges();
}
}

Related

Proper API calls and server-side data storage - Blazor

I'm trying to learn Blazor while bringing some of my ideas to live as I think that the best way to learn is by practice. I want to build a card viewer for CCG (collectible card game) and I've stumbled upon a roadblock which I hope someone can help me with :)
As I don't want to store the card database myself, I'm using a 3rd party source to download the required information - and I have a problem with it's storage afterwards.
I made a server-side controller that fetches the mentioned DB (after some sorting with my own class to filter some unnecesarry data). What I wanted to achieve is a list of all the cards and onClick to fetch the info about the specific one by ID.
My controller looks like this:
[Route("[controller]")]
[ApiController]
public class CardController : ControllerBase
{
private List<Card> Cards = new();
[HttpGet("{id}")]
public ActionResult Get(int id)
{
var card = Cards.Find(o => o.Id == id);
if (card != null)
{
return Ok(card);
}
return NotFound("Card not found");
}
[HttpGet("List")]
public ActionResult List()
{
return Ok(Cards);
}
[HttpGet("GetAllCards")]
public async Task<List<Card>> GetAllCards()
{
if (Cards.Count() == 0)
{
Cards = await GetAllCardsPro();
}
return Cards;
}
public async Task<List<Card>> GetAllCardsPro()
{
var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://db.ygoprodeck.com/api/v7/cardinfo.php");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
YgoProMap.Rootobject obj = JsonConvert.DeserializeObject<YgoProMap.Rootobject>(responseBody);
if (obj != null)
{
foreach (var card in obj.data)
{
Cards.Add(new Card
{
Id = card.id,
Name = card.name,
Type = card.type,
Desc = card.desc,
Atk = card.atk,
Def = card.def,
Level = card.level,
Race = card.race,
Attribute = card.attribute,
Archetype = card.archetype,
Linkval = card.linkval,
Scale = card.scale,
Images = new string[] { card.card_images.First().image_url, card.card_images.First().image_url_small }
});
}
}
return Cards;
}
}
The problem occurs when I try to call Get(ID) to get info of that specific card and it always return 404. If I manualy populate the Cards list with a new Card(some data) I'm able to get that one specific card's information. So I would assume that after the call to that 3rd party API Cards it just passes the value to client once remaining null on the server.
So my 1st question here is how should I store that data that is fetched from the 3rd party API to make it accessable afterwards? Should it be somewhere in the server startup with a daily refresh? Is it even possible to store it like a JSON file for example?
My 2nd question is about best practices performance wise as at the moment I'm passing the whole List of Cards to the client (~10 thousand objects). Would it be better to pass a separate array that only stores card.Name and card.Id for it to be bound to a UI list/table and afterwards onClick fetch that specific card's full data? Or 10 thousand objects isn't a huge deal and I should just pass the whole List and do all the specific card operation client side?
Sorry for making it so long but I've tried to be as specific as I can :D

Edit and delete from SQL database through Azure

I have been building a Windows Phone 8 app and Windows Azure cloud service that will allow people to store schedules in the cloud. I have implemented a single sign on system and a cloud service used to store the schedule items.
I have however run into yet another problem, as I am using a cloud service to communicate with the database, the commands are slightly different, for example, this is the code to add a record to the database:
public bool addMedication(string userid, string medname, DateTime medtime)
{
using (var meds = new TMP_Meds_Entities())
{
meds.med_schedule.Add(new med_schedule()
{
userid = userid,
medname = medname,
medtime = medtime
});
meds.SaveChanges();
return true;
}
}
I now need to implement methods to allow a user to edit or delete a particular record in the database, does anybody know how I might go about editing or deleting a record? As a note, I am using EntityFramework.
Thanks
This is more or less from scratch, so you'll need to adapt it to your scenario, but this should get you started...
Update:
public void UpdateMed(meds med)
{
if (ModelState.IsValid)
{
db.meds.Attach(med);
db.Entry(med).State = EntityState.Modified;
db.SaveChanges();
}
}
Delete:
public void DeleteMed(int medid)
{
meds med = db.meds.Find(medid);
db.meds.Remove(med);
db.SaveChanges();
}
Here are a couple good resources for more detail
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application
http://www.dotnetcurry.com/showarticle.aspx?ID=619

A database that easy for a developer to use and deploy?

I have created this interface for storing data in a file:
interface IFileStore {
bool Import(string);
string Export();
}
...and a generic class that implements that interface:
class DBTextFile<T> where T : IFileStore, new ()
{
public List<T> db = new List<T>();
public void SaveFile(string filename)
{
foreach(T d in db) File.WriteToFile(d.Export(), filename);
}
public void RestoreFile(string filename)
{
db = new List<T>();
string buffer;
while(buffer = File.Read(filename) != null)
{
T temp = new T();
if(temp.Import(buffer)) db.Add(temp);
}
}
}
This approach has been working for me for a while. However, I'm finding that I'm having to manage too many files. I think it might be more appropriate to use a database where each of my files would become a table in that database.
I would like to use a database that does not require the user to install any software on the user's system. (I want to keep things simple for the user.) Basically, I just want a database that is easy for me, the developer, to use and deploy.
Would MySQL be a good choice? Or would a different database be a better fit for my needs?
You can use different one file databases.
The one I'm using and am happy with is : SQLite.
You could also use access as Monika suggested, or browse google and see what else you can find ...

Storing SQL commands in .net

I'm building my first web app with .net, and it needs to interact with a very large existing database. I have the connection set up, and have made a class that I can call to build select, insert, update and delete queries passing in several parameters.
I can connect by writing the query I want in the button click, but I want to know is this the best solution? It seems hard to debug this way, as it is mixing the database code with other code.
In the past (in other languages) I have created a class which would contain all of the database query strings and parameters which would be called by the rest of the code. That way if something simple like the stored procedure parameters change, the code is all in one place.
When I look for this in .net, I see nothing about doing it this way and I'm keen to learn the best practices.
protected void Button1_Click(object sender, EventArgs e)
{
NameLabel.Text = UserNoTextBox.Text;
string spName = "SP_SelectUser";
SqlParameter[] parameters = new SqlParameter[]
{
new SqlParameter("#User_No", UserNoTextBox.Text)
};
DataAccess dbAccess = new DataAccess();
DataTable retVal = dbAccess.ExecuteParamerizedSelectCommand(spName, CommandType.StoredProcedure, parameters);
}
Update: The class I was referring to was the DataAccess class from the following website:
http://www.codeproject.com/Articles/361579/A-Beginners-Tutorial-for-Understanding-ADO-NET
(Class available at http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=361579)
Update: In the end I opted for using MVC 3 with Entity Framework - it's great!
This is a huge topic, but a very brief view might be as follows:
DataTable must die (ok, it has a few uses, but in general: it must die); consider using a custom type such as:
public class User {
public int Id {get;set;}
public string Name {get;set;}
public string EmployeeNumber {get;set;}
// etc
}
It should also be noted that many ORM tools will generate these for you from the underlying table structure.
don't mix UI and data access; separate this code, ideally into separate classes, but at the minimum into separate methods:
protected void Button1_Click(object sender, EventArgs e)
{
NameLabel.Text = UserNoTextBox.Text;
var user = SomeType.GetUser(UserNoTextBox.Text);
// do something with user
}
...
public User GetUser(string userNumber) {
... your DB code here
}
use a library such as an ORM (EF, LINQ-to-SQL, LLBLGenPro) or a micro-ORM (dapper, PetaPoco, etc) - for example, here's that code with dapper:
public User GetUser(string userNumber) {
using(var conn = GetOpenConnection()) {
return conn.Query<User>("SP_SelectUser",
new {User_No = userNumber}, // <=== parameters made simple
commandType: CommandType.StoredProcedure).FirstOrDefault()
}
}
or with LINQ-to-SQL (EF is very similar):
public User GetUser(string userNumber) {
using(var db = GetDataContext()) {
return db.Users.FirstOrDefault(u => u.User_No == userNumber);
}
}
not everything needs to be a stored procedure; there used to be a huge performance difference between the two - but that is no longer the case. There are valid reasons to use them (very granular security, shared DB with multiple application consumers, a dba who thinks they are a developer), but they also create maintenance problems, especially when deploying changes. In most cases I would not hesitate to use raw (but parameterized) SQL, for example:
public User GetUser(string userNumber) {
using(var conn = GetOpenConnection()) {
return conn.Query<User>(#"
select [some columns here]
from Users where User_No = #userNumber",
new {userNumber}).FirstOrDefault()
}
}
I would do something like this:
code behind
protected void Button1_Click(object sender, EventArgs e)
{
UserController uc = new UserController();
User u = UserController.GetUser(Convert.ToInt32(UserNoTextBox.Text);
NameLabel.Text = u.UserName;
}
And in your UserController.cs
class UserController{
public User GetUser(int userId)
{
return DataAccess.GetUser(userId);
}
}
And in your User.cs
class User{
private string _userName;
public string UserName{ get{ return _userName;} set{ _userName= value;} }
}
And in your DataAccess.cs using Dapper
public User GetUser(int id)
{
var user = cnn.Query<User>("SP_SelectUser", new {User_No = id},
commandType: CommandType.StoredProcedure).First();
return user;
}
This is just one option, but you can also use different ORM's
It is about personal flavor. Here is a list of .Net ORM's
Good luck!
General best practices tend to be language agnostic in the OOP world. You say you have worked with data access in other OOP languages in the past, so would do exactly the same in .net. See response from #Oded for good links for general best practices.
If you are looking for guidance on how best to use .net's data access technology, try MSDN's articles on ADO as a starting point.
What you are doing will work, but doesn't follow good OOP principles, one of which is separation of concerns - your UI shouldn't be talking to the database directly.
You should have all your data access code placed in a separate layer which your UI layer can call.
Also see the SOLID principles and Don't repeat yourself.
When interacting with the database, many people use an ORM - Entity Framework, nHibernate, Dapper and many others exist for .NET applications. These act as a data access layer and you should investigate their usage for your application.

Implementing queue in c#

I am developing a c# application, in which the server gets requests from many clients at a time. Each client also gets their data from different databases. In this situation sometimes data leakage is happening, means clients get data from an incorrect database. Say for example client1 should get data from db1 and client2 gets data from db2. Instead they get data from opposite databases; client1 gets from db2 and client2 gets from db1.
I am adding the code below where it collects the data.
public string List()
{
Response.ContentType = ContentType.Xml;
try
{
ThingzFilter filter = null;
Dictionary<string, string> parameters = new Dictionary<string, string>();
if (Id!="")
{
// get parameters from http request
foreach (HttpInputItem param in Request.Param)
parameters.Add(param.Name, param.Value);
setServerURLs();
//Request.Clear();
if (Request.QueryString["lang"].Value != null)
{
ThingzDB.TzThing.get_language = Request.QueryString["lang"].Value.ToString();
}
else
{
ThingzDB.TzThing.get_language = SessionDatabase.DefaultLanguage;
}
}
ThingzDatabase db = SessionDatabase;
langStr = db.Language;
// this is run if there was no ID supplied
// which means we want all items of all types
if (Id == "")
{
if (Request.AcceptTypes == null)
{
//TypeController.session_id = Request.QueryString["sessionid"].Value;
jobs.Add(Request.QueryString["sessionid"].Value);
if (nextJobPos > jobs.Count - 1)
return "";
else
{
TypeController.session_id = jobs[nextJobPos];
nextJobPos++;
langStr = SessionDatabase.Language;
}
filter = new AllThingzFilter(SessionDatabase, parameters, langStr);
TypeController.session_id = "";
filter.Execute();
}
In this server is console application and clients are windows where the site names , means the databse names are mentioned.
Please give me a solution to overcome this issue.
Without precisely knowing how SessionDatabase is scoped (from the name it seems to be a session variable) or whether it's implementation is a property that does some kind of complex logic, I would guess you have two problems:
Storing the value at the wrong scope with multiple clients accessing it
Using db and SessionDatabase interchangeably in your code.
For the latter, I would suggest db = SessionDatabase once at the top of the code (making sure that SessionDatabase was the right thing for that client, and then using db for the rest of the method.

Categories