Dbcontext with using-clause in Asp.Net Json-Call - asp.net-mvc-4

I ran into a problem when switching from the Local Development Server to the Local IIS Server (ASP.NET MVC4) using the following Controller-Method:
public JsonResult GetJsonData(string Context, string Language)
{
using (KeyValueDBContext db = new KeyValueDBContext())
{
var entries = from u in db.KeyValues
where ((u.Context == Context) && (u.Language == Language))
select u;
return Json(entries, JsonRequestBehavior.AllowGet);
}
}
Using the local server, I received data when calling the method from Javascript without a problem. The method retrieves a collection of basically Key-Value pairs from a database repository and sends them to the client). After switching to IIS I got an Exception telling me that the dbcontext had already been disposed of (although the using clause ends after the return-statement). (NB: Visual Studio also was not able to find JSONSerializer.cs for some reason, but only when the error occurred). Switching to the following version solved the problem completely:
public JsonResult GetJsonData(string Context, string Language)
{
KeyValueDBContext db = new KeyValueDBContext();
var entries = from u in db.KeyValues
where ((u.Context == Context) && (u.Language == Language))
select u;
return Json(entries, JsonRequestBehavior.AllowGet);
}
In both cases, this was the using-block:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using beepov4.Models; // project-models
My question: Is this an acceptable way to use dbcontext for the purpose of JSON-calls (and dropping the using-clause) or is there a particular downside or hidden problem I should be aware of?

Try reading the entries into memory with entries.ToList() before passing them to Json():
using (KeyValueDBContext db = new KeyValueDBContext())
{
var entries = from u in db.KeyValues
where ((u.Context == Context) && (u.Language == Language))
select u;
return Json(entries.ToList(), JsonRequestBehavior.AllowGet);
}

Related

Render Razor View into String using .Net Core Console Application

I have prepared a .net core console application (Framework version .Net Core 2.2) for sending email as a service. Right now its working completely fine with static html content being hardcoded into service method for generating email body string.
I am in seek of the code which provides me a solution to render a razor view to have a html string with the model data.
Tried to implement the RazorEngine dll in entity framework ver. 4.5. with below code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GenerateEmailUsingRazor.Model;
using RazorEngine.Templating;
namespace GenerateEmailUsingRazor
{
class Program
{
static readonly string TemplateFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EmailTemplates");
static void Main(string[] args)
{
var model = GetUserDetail();
var emailTemplatePath = Path.Combine(TemplateFolderPath, "InviteEmailTemplate.cshtml");
var templateService = new TemplateService();
var emailHtmlBody = templateService.Parse(File.ReadAllText(emailTemplatePath), model, null, null);
Console.WriteLine(emailHtmlBody);
Console.ReadLine();
}
private static UserDetail GetUserDetail()
{
var model = new UserDetail()
{
Id = 1,
Name = "Test User",
Address = "Dummy Address"
};
for (int i = 1; i <= 10; i++)
{
model.PurchasedItems.Add("Item No " + i);
}
return model;
}
}
}
Expected Result:
Console Application should render the razor view and provide me the resultant html string.
I've written a clean library Razor.Templating.Core that works with .NET Core 3.0, 3.1 on both web and console app.
It's available as NuGet package.
After installing, you can call like
var htmlString = await RazorTemplateEngine
.RenderAsync("/Views/ExampleView.cshtml", model, viewData);
Note: Above snippet won't work straight away. Please refer the below working guidance on how to apply it.
Complete Working Guidance: https://medium.com/#soundaranbu/render-razor-view-cshtml-to-string-in-net-core-7d125f32c79
Sample Projects: https://github.com/soundaranbu/RazorTemplating/tree/master/examples

SymmetricAlgorithm' does not contain a definition for 'Create'

I'm trying to work on ASP.NET 5 application. Here is a class and it looks good (no red curly underlines). But when I try to build, it gives error - SymmetricAlgorithm' does not contain a definition for 'Create'
using System;
using System.IO;
using System.Security.Cryptography;
namespace SalesBook
{
public static class Encryptor
{
private static byte[] EncryptString(string data)
{
byte[] byteData = Common.GetByte(data);
SymmetricAlgorithm algo = SymmetricAlgorithm.Create();
}
}
}
I'm using .net 4.6.1.
Any help?
This method has not been ported to .NET Core. The recommended alternative is to use the specific Create method associated with the algorithm you need:
var algorithm = Aes.Create();
On CoreCLR, it will automatically determine and return the best implementation, depending on your OS environement.
If you don't need .NET Core support, you can remove the dnxcore50/dotnet5.4 from your project.json.

REST API (JSON) that updates SQL Table using Windows Console Application and Scheduled Tasks

I am a newbie at JSON programming. Most of my experience is in C# and some in XML and Javascript. So I am a bit lost. I will attempt to be as specific as possible.
I have written a windows console application that runs via the task scheduler. Basically the windows application is supposed to take the API from a site that is managed by an outside company but the information is owned by my company and put the information within a SQL table. The API is pretty standard and written in JSON.
I am successful in parsing the JSON language and (for example) displaying it in a command prompt but I need to be able to parse the language and place it into an SQL table. I have read up on SQL injection attacks and I feel fairly confident that we have covered our bases here. So the problem lies in the fact that it does not update the table when the application is run via the scheduler or without the scheduler.
I have included a little bit of the JSON language below along with the language for my console application.
{"date":"2015-09-24","data":[{"cid":"17","rank":1},{"cid":"26","rank":1},{"cid":"80","rank":1},{"cid":"30","rank":1},{"cid":"90","rank":1},{"cid":"62","rank":1},{"cid":"147","rank":1},{"cid":"28","rank":1}"s":1,"e":null}
using System;
using System.Collections;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Formatting;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace JsonApiClient
{
class Program
{
static void Main(string[] args)
{
ExecuteRiskSearch();
Console.ReadLine();
}
static void ExecuteRiskSearch()
{
string url = "https://localhost/api/getWatchList/";
string json = new WebClient().DownloadString(url);
JObject results = JObject.Parse(json);
foreach (var result in results)
{
string cid = (string)results["CID"];
JToken rank = results["rank"];
string risk = "";
if (rank is JValue)
{
risk = (string)rank;
}
else if (rank is JArray)
{
risk = (string)((JArray)rank).First;
}
else
{
SqlConnection connection = null;
SqlCommand command = null;
try
{
connection = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=apiData;Data Source=serverName;");
command = new SqlCommand("UPDATE apiData.dbo.API SET [Category] WHERE CID=CID", connection);
connection.Open();
int numrows = command.ExecuteNonQuery();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
finally
{
command.Dispose();
connection.Dispose();
}
}
}
}
}
}
What am I missing to make the JSON data update my SQL table? I have scoured Google search results and I haven't found much information. Any help would be so greatly appreciated.
For the need to foreach with the correct part of the JSON object, what I mean is very simply that your variable results includes the entire JSON object, from the "date" through the "e". You need to start with the "data" object and iterate through its array or your string cid will error out on assignment, as it will be attempting to assign an array to a single value. The same goes for your JToken rank. I believe it should be this:
foreach(datum in results["data"])
{
string cid = datum["cid"];
JToken rank = datum["rank"];
/* ... */
}
In addition, your set command isn't doing anything. You need to use SET columName = " + newValue + " WHERE CID == " + cid to actually affect a change, where columnName is the column you wish to alter and newValue is your C# variable carrying the desired replacement.
It's also a best practice to include a change to an updated date field when updating via an automated process, if there is one present. Generally the convention is to have a created date and an updated date for each row in a table.
I hope this at least points you in the right direction.
-C§
As an alternative, you can send entire text to Sql Server and load it there.
Sql Server 2016 will enable you to store JSON using single command - OPENJSON. In the older versions you can use existing CLR/JSON libraries such as Json4Sql or JsonSelect.

TFS 2012 Backup and Restore BuildDefinitions only

I installed a TFS2012 as a test system and doing some tests before we go productive.
This includes to define many BuildDefinitions which was a lot of work.
After the tests are successful, an new server will be installed with TFS2012 on it.
For this new server - which operates then as the productive system - i would like to restore the BuildDefinitions from the test system. But only the BuildDefinitions, not the whole TeamCollections. Because i ran test checkins and i don`t want these on my productive server.
Now, is it possible to backup and restore BuildDefinitions only?
Maybe it is possible directly throught the Sql database?, but i`am a little affraid of references there, pointing on some other tables.
Best Regards, Peter Bucher
Build definitions are not source controlled. The only option is relying on the TFS database backup where can restore or view the tbl_BuildDefinition* tables in the Tfs_DefaultCollection database.
There is a user voice for this feature and also you can use TFS API to do it.
Add a vote on uservoice:
provide a way to version-control build definitions
Using TFS API
How can I copy a TFS 2010 Build Definition?
Finally i decided not to touch the database, because there are references to a lot of other tables.
I used the TFS API v11 (TFS2012) and a bit C# Code, which i fitted to my needs from this base: How can I copy a TFS 2010 Build Definition?
It copies all Build Definitions from one TFS2012 Server to another. For both servers there is the need to specifiy a TeamCollection and a TeamProject.
So, the copy-task has to be done per TeamProject.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace TFSBuildDefinitionCreator
{
internal class Program
{
private static void Main(string[] args)
{
// Copies build definitions from one server to another.
// Uses the TeamFoundation API V11 (TFS2012).
// Code was used to copy b uild definitions from a test server to a productive.
string sourceServer = "http://testTfs:8080/tfs/MyTeamCollection";
string sourceTeamProject = "MyTeamProject";
string targetServer = "https://productiveTfs:8080/tfs/MyTeamCollection";
string targetTeamProject = "MyTeamProject";
// DropLocation for defininitions: Share on which the build should be dropped.
string defaultDropLocation = "\\\\MyBuildserver\\Builds$";
// Change the DefaultProcessTemplate in the following method below: GetDefaultProcessTemplateByServerPathFromBuildServer.
CopyBuildDefinitions(sourceServer, sourceTeamProject, targetServer, targetTeamProject, defaultDropLocation);
Console.Read();
}
private static IBuildServer GetBuildServerFromServerUrl(string serverUrl)
{
var tfs = TeamFoundationServerFactory.GetServer(serverUrl);
return (IBuildServer)tfs.GetService(typeof(IBuildServer));
}
private static IBuildController GetDefaultBuildControllerFromBuildServer(IBuildServer buildServer)
{
return buildServer.QueryBuildControllers()[0];
}
private static IProcessTemplate GetDefaultProcessTemplateByServerPathFromBuildServer(IBuildServer buildServer, string teamProject)
{
var processTemplates = buildServer.QueryProcessTemplates(teamProject);
var result = processTemplates.First(t => t.ServerPath.Contains("/BuildProcessTemplates/MyDefaultTemplate.xaml"));
return result;
}
private static void CopyBuildDefinitions(string sourceServer, string sourceTeamProject, string targetServer,
string targetTeamProject, string defaultDropLocation)
{
var sourceBuildServer = GetBuildServerFromServerUrl(sourceServer);
var sourceBuildDetails = sourceBuildServer.QueryBuildDefinitions(sourceTeamProject);
foreach (var sourceBuildDetail in sourceBuildDetails)
{
CopyBuildDefinition(sourceBuildDetail, targetServer, targetTeamProject, defaultDropLocation);
}
}
private static void CopyBuildDefinition(IBuildDefinition buildDefinition, string targetServer, string targetTeamProject, string defaultDropLocation)
{
var targetBuildServer = GetBuildServerFromServerUrl(targetServer);
var buildDefinitionClone = targetBuildServer.CreateBuildDefinition(targetTeamProject);
buildDefinitionClone.BuildController = GetDefaultBuildControllerFromBuildServer(targetBuildServer);
buildDefinitionClone.ContinuousIntegrationType = buildDefinition.ContinuousIntegrationType;
buildDefinitionClone.ContinuousIntegrationQuietPeriod = buildDefinition.ContinuousIntegrationQuietPeriod;
// Noch ändern.
//buildDefinitionClone.DefaultDropLocation = buildDefinition.DefaultDropLocation;
buildDefinitionClone.DefaultDropLocation = defaultDropLocation;
buildDefinitionClone.Description = buildDefinition.Description;
buildDefinitionClone.Enabled = buildDefinition.Enabled;
//buildDefinitionClone.Name = String.Format("Copy of {0}", buildDefinition.Name);
buildDefinitionClone.Name = buildDefinition.Name;
//buildDefinitionClone.Process = buildDefinition.Process;
buildDefinitionClone.Process = GetDefaultProcessTemplateByServerPathFromBuildServer(targetBuildServer, targetTeamProject);
buildDefinitionClone.ProcessParameters = buildDefinition.ProcessParameters;
foreach (var schedule in buildDefinition.Schedules)
{
var newSchedule = buildDefinitionClone.AddSchedule();
newSchedule.DaysToBuild = schedule.DaysToBuild;
newSchedule.StartTime = schedule.StartTime;
newSchedule.TimeZone = schedule.TimeZone;
}
foreach (var mapping in buildDefinition.Workspace.Mappings)
{
buildDefinitionClone.Workspace.AddMapping(
mapping.ServerItem, mapping.LocalItem, mapping.MappingType, mapping.Depth);
}
buildDefinitionClone.RetentionPolicyList.Clear();
foreach (var policy in buildDefinition.RetentionPolicyList)
{
buildDefinitionClone.AddRetentionPolicy(
policy.BuildReason, policy.BuildStatus, policy.NumberToKeep, policy.DeleteOptions);
}
buildDefinitionClone.Save();
}
}
}
Hope that helps others.

Using SMO Library in SSIS 2008

Good afternoon,
Im having some trouble writing a simple script using SMO objects in C# to validate if an object exists and then create it. This code is within a Script Task Component in SSIS. The code executes successfully, however the new database does not show up on my local instance. Any help would be greatly appreciated.
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Collections;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
public void Main()
{
//String DBName = Dts.Variables["TmpViewDBName"].Value.ToString();
//String Instance = Dts.Variables["TmpViewDBInstance"].Value.ToString();
String DBName = "localhost";
String Instance = "TmpViewDB";
Server TmpViewServer = new Server(Instance);
//Windows Auth
TmpViewServer.ConnectionContext.LoginSecure = true;
TmpViewServer.ConnectionContext.Connect();
if (TmpViewServer.Databases[DBName] != null)
{
TmpViewServer.Databases[DBName].Drop();
}
Database TmpViewDB = new Database(TmpViewServer, DBName);
if (TmpViewServer.ConnectionContext.IsOpen)
TmpViewServer.ConnectionContext.Disconnect();
Dts.TaskResult = (int)ScriptResults.Success;
}
I believe you need to add a line to actually create the object. As it stands now, you've only instantiated the object but never actually made the call to the database to create the remote object.
Database TmpViewDB = new Database(TmpViewServer, DBName);
TmpViewDB.Create();