How to use Actionmailer.Net.Standalone in a console application? - c#

Is is possible to use Actionmailer.Net.Standalone in a console application? I keep getting an error that:
Could not find any CSHTML or VBHTML views named [CRD.html.cshtml] in the path [EmailTemplates]. Ensure that you specify the format in the file name (ie: CRD.html.cshtml.txt.cshtml or CRD.html.cshtml.html.cshtml)
Code
public class Mailer : RazorMailerBase
{
public override string ViewPath
{
get { return "EmailTemplates"; }
}
public RazorEmailResult Processed(string f)
{
From = group;
To.Add(user);
Subject = "CRD Process Server has processed file: " + f;
return Email("CRD.html.cshtml");
}
}
Do I need to implement a RazorViewEngine somewhere since it isn't standard with a console application?

A little late but maybe it still helps:
Try to change
return Email("CRD.html.cshtml");
to
return Email("CRD");
The extensions are appenden automatically.

There is a open source project as a general templating engine called RazorEngine
A templating engine built upon Microsoft's Razor parsing technology.
The RazorEngine allows you to use Razor syntax to build robust
templates.
Simply;
string template = "Hello #Model.Name! Welcome to Razor!";
string result = Razor.Parse(template, new { Name = "World" });
Also available in NuGet;
Install-Package RazorEngine

Related

Version Endpoint for AspCore API Standard Approach

Recently working on a ASPCore Web Api (C#) I wanted to add a version endpoint so I can tell which version of a given API Im working with. Its a public API so I don't want to include things that might be used to determine vulnerabilities such as third party package version etc.
So far I've got the Following.
// GET api/values
[HttpGet]
public string Get()
{
var attributes = Assembly.GetEntryAssembly().CustomAttributes;
string versionInfo=null;
foreach(var attribute in attributes)
{
if (attribute.AttributeType.Name.StartsWith("Assembly")&& attribute.AttributeType.Name.EndsWith("Attribute"))
{
string name = attribute.AttributeType.Name;
name = name.Substring(8, name.Length - 17);
versionInfo = string.Concat(versionInfo, name, ":");
versionInfo = string.Concat(versionInfo, attribute.ConstructorArguments.FirstOrDefault());
versionInfo = string.Concat(versionInfo, System.Environment.NewLine);
}
}
return versionInfo;
}
which Produces
Company:"Company Name"
Configuration:"Debug"
Description:"Package Description"
FileVersion:"0.0.1.0"
InformationalVersion:"0.0.1"
Product:"ProductName"
Title:"PackageTitle"
Is there any more industry standard approach to this. Seems it would be a fairly standard issue but Im not seeing any sort of standard way to accomplish this from my brief date with Google.

How to Integrate NodeJs in Existing .Net MVC application Using EdgeJs?

Can any one suggest another way to integrate NodeJs in .Net MVC application? I am now using the following code:
public class Startup
{
public async Task<object> Invoke(dynamic input)
{
DepartmentRep person = new DepartmentRep(new MvcAppUsingEdgeJSMongoDbContext());
var department= person.GetAllDepartments();
//var department = "hello";
return department;
}
}
public class DepartmentController : Controller
{
DepartmentRepository departmentRepository = new DepartmentRepository(new MvcAppUsingEdgeJSMongoDbContext());
string connectionString = ConfigurationManager.AppSettings["connectionString"].ToString();
public ViewResult Index()
{
// var clrMethod = Edge.Func("DepartmentRep.cs");
var getData = Edge.Func("./DepartmentRep.dll");
// return View(clrMethod);
return View(departmentRepository.GetAllDepartments());
}
}
It seems to me, you may have a misunderstanding of the EdgeJs use case.
Your Startup/Invoke class/Signature is meant to be called from Node(JavaScript),
And from the code you are showing it looks like you are loading .Net from .Net
Also , as the Invoke signature suggest, It should be asynchronous.
If you want to use node from .Net side. You should check the project documentation from
scripting-nodejs-from-clr downwards.
var func = Edge.Func(#"
return function (data, callback) {
callback(null, 'Node.js welcomes ' + data);
}
");
As you can see there the wrapped code is Javascript, this time running in .Net more specifically running in Node.
The perfect use case IMMO is the Socket-Server, that is, something Node does better than .Net (IMMO again)
Which is in perfect contrast with the .Net Ado Sql Server access from NodeJs, a .Net Specialization from NodeJs context

How to read data from multiple (multi language) resource files?

I am trying the multi language features in an application. I have created the resource files GlobalTexts.en-EN.resx GlobalTexts.fr-FR.resx and a class that sets the culture and returns the texts like (I will not go in all the details, just show the structure):
public class Multilanguage
{
...
_res_man_global = new ResourceManager("GlobalResources.Resources.GlobalTexts", System.Reflection.Assembly.GetExecutingAssembly());
...
public virtual string GetText(string _key)
{
return = _res_man_global.GetString(_key, _culture);
}
}
...
Multilanguage _translations = new Multilanguage();
...
someText = _translations.GetText(_someKey);
...
This works just fine.
Now, I would like to use this application in another solution that basically extends it (more windows etc.) which also has resource files ExtendedTexts.en-En.resx ExtendedTexts.fr-FR.resx and a new class like:
public class ExtendedMultilanguage : Multilanguage
{
...
_res_man_local = new ResourceManager("ExtendedResources.Resources.ExtendedTexts", System.Reflection.Assembly.GetExecutingAssembly());
...
public override string GetText(string _key)
{
string _result;
try
{
_result = _res_man_local.GetString(_key, _culture);
}
catch (Exception ex)
{
_result = base.GetText(_key);
}
}
...
ExtendedMultilanguage _translations = new Multilanguage();
...
someText = _translations.GetText(_someKey);
...
the idea being that if the key is not found in ExtendedTexts the method will call the base class which is looking into GlobalTexts. I did this in order to use the call GetText(wantedKey) everywhere in the code without having to care about the location of the resource (I do not want to include the translations from the extensions in the GlobalTexts files); it is juts the used class that is different from project to project.
The problem I am facing is that the try/catch is very slow when exceptions raise- I wait seconds for one window to populate. I tested with direct call and works much faster, but then I need to care all the time where the resource is located...
The question is: is there an alternative way of doing this (having resources spread in various files and have only one method that gives the desired resource without throwing an error)?
In the end I took a workaround solution and loaded all the content of the resource files in dictionaries. This way I can use ContainsKey and see if the key exists or not.

MVC Razor, Include JS / CSS files from another project

I've got a C# MVC project that uses Razor syntax.
To be able to reuse some code, I want to put some of my JavaScript and CSS files in a different project and include them somehow.
This is how my scripts are included at the moment:
<script src="#Url.Content("~/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/bootstrap-dropdown.js")" type="text/javascript"></script>
At the moment, the scripts are in the same project as the cshtml file but they should be placed in the Common.Web project instead...
What I want to do is this (doesn't work though):
<script src="#Url.Content("Common.Web/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>
<script src="#Url.Content("Common.Web/Scripts/bootstrap-dropdown.js")" type="text/javascript"></script>
I do this very thing. However I embed the Javascript files and other content in another DLL and then call them from my razor syntax like so. Here is the code I use.
In the View:
Script example:
<script src=#Url.Action("GetEmbeddedResource", "Shared", new { resourceName = "Namespace.Scripts.jquery.qtip.min.js", pluginAssemblyName = #Url.Content("~/bin/Namespace.dll") }) type="text/javascript" ></script>
Image Example:
#Html.EmbeddedImage("corporate.gif", new { width = 150, height = 50})
Here is my helper methods:
public static MvcHtmlString EmbeddedImage(this HtmlHelper htmlHelper, string imageName, dynamic htmlAttributes)
{
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
var anchor = new TagBuilder("img");
anchor.Attributes["src"] = url.Action("GetEmbeddedResource", "Shared",
new
{
resourceName = "Namespace.Content.Images." + imageName,
pluginAssemblyName = url.Content("~/bin/Namespace.dll")
});
if (htmlAttributes != null)
{
string width = "";
string height = "";
PropertyInfo pi = htmlAttributes.GetType().GetProperty("width");
if (pi != null)
width = pi.GetValue(htmlAttributes, null).ToString();
pi = htmlAttributes.GetType().GetProperty("height");
if (pi != null)
height = pi.GetValue(htmlAttributes, null).ToString();
if (!string.IsNullOrEmpty(height))
anchor.Attributes["height"] = height;
if (!string.IsNullOrEmpty(width))
anchor.Attributes["width"] = width;
}
return MvcHtmlString.Create(anchor.ToString());
}
Lastly my shared Controller:
[HttpGet]
public FileStreamResult GetEmbeddedResource(string pluginAssemblyName, string resourceName)
{
try
{
string physicalPath = Server.MapPath(pluginAssemblyName);
Stream stream = ResourceHelper.GetEmbeddedResource(physicalPath, resourceName);
return new FileStreamResult(stream, GetMediaType(resourceName));
//return new FileStreamResult(stream, GetMediaType(tempResourceName));
}
catch (Exception)
{
return new FileStreamResult(new MemoryStream(), GetMediaType(resourceName));
}
}
private string GetMediaType(string fileId)
{
if (fileId.EndsWith(".js"))
{
return "text/javascript";
}
else if (fileId.EndsWith(".css"))
{
return "text/css";
}
else if (fileId.EndsWith(".jpg"))
{
return "image/jpeg";
}
else if (fileId.EndsWith(".gif"))
{
return "image/gif";
}
else if (fileId.EndsWith(".png"))
{
return "image/png";
}
return "text";
}
Resource Helper:
public static class ResourceHelper
{
public static Stream GetEmbeddedResource(string physicalPath, string resourceName)
{
try
{
Assembly assembly = PluginHelper.LoadPluginByPathName<Assembly>(physicalPath);
if (assembly != null)
{
string tempResourceName = assembly.GetManifestResourceNames().ToList().FirstOrDefault(f => f.EndsWith(resourceName));
if (tempResourceName == null)
return null;
return assembly.GetManifestResourceStream(tempResourceName);
}
}
catch (Exception)
{
}
return null;
}
}
Plugin Helper
public static T LoadPluginByPathName<T>(string pathName)
{
string viewType = typeof(T).GUID.ToString();
if (HttpRuntime.Cache[viewType] != null)
return HttpRuntime.Cache[viewType] is T ? (T)HttpRuntime.Cache[viewType] : default(T);
object plugin = Assembly.LoadFrom(pathName);
if (plugin != null)
{
//Cache this object as we want to only load this assembly into memory once.
HttpRuntime.Cache.Insert(viewType, plugin);
return (T)plugin;
}
return default(T);
}
Remember that I am using these as embedded content!
To my knowledge you can't do this as the path would lie outside of the website.
You can however do the following:
1) Put all the scripts you want to share in Common.Web\Scripts
2) For each script file in your Web application 'Add as Link' to your Common.Web Scripts (you don't even need to do this step; it is however nice to see what scripts your web app uses in VS)
3) Add a post-build event to your Web application that copies the scripts from Common.Web\Scripts to your WebApp\Scripts folder:
copy $(ProjectDir)..\Common.Web\Scripts* $(ProjectDir)\Scripts
so from your perspective in Visual Studio you will only have a single place to update your .js files that can be used by multiple projects.
Instead of using Url helper use relative addressing. What you tried to do makes no sense, as helper is used to resolve paths relative to it's project.
Since you are trying to use resources of another project, it's ok to assume that you know upfront where you're going to deploy each project. Even though I don't like this practice, I can think of a pragmatic solution for this.
If your two applications are at urls:
http://www.mysite.com/app1
http://www.mysite.com/Common.Web
you could address like this:
<script src="#Url.Content("~")/../Common.Web/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>
meaning, resolve my app root folder, go up a level, and go down rest of the path.
I just found this question while looking for the same answer. Thanks to the previous posters, who made it clear that this cannot be done using Visual Studio alone: you will always end up with a copy of the original file, or an incomplete set of shipping files.
I do not wish to reinvent the wheel whenever I have simple common functionality, so I have a folder for common scripts on my hard drive:
/Common/Javascript
My web project is located in:
/ProjectName
so my common scripts lie outside my web project.
I solved this via source control. Most source control repositories will have the functionality to show a file in another directory. My steps were:
Create empty folder under my VS project: /ProjectName/Scripts/Common
Committed the empty folder to source control
Using Subversion (my source control), I set up an "extern" so that my common file was linked to the new folder. Other source control software may call this a "link" or some other such thing.
Updated the new folder, and my common Javascript files came in, and could now be added to my web project in Visual Studio.
Obviously, I tested this by changing the files within Visual Studio and committing them. The changes were indeed reflected in the original files, sitting in /Common/Javascript.
I can now simply add an extern to any other web project which needs to use the same functionality: though, of course, changing those files comes with additional risk now, as I may unexpectedly break other projects which use them. Though I can configure an extern to use a specific revision of a file, that's not what I want to do at this point; I shall await such complexity as and when it occurs.

How can i use response.redirect from inside a function defined in Class file in c# 3.0

I have a simple function GetPageName(String PageFileName, String LangCode) defined inside a class file. I call this function from default.aspx.cs file, In this function I am not able to use Response.Redirect("Error.aspx") to show user that error has been generated.
Below is example of Code
public static string GetPageName(String PageFileName, String LangCode)
{
String sLangCode = Request("Language");
String pgName = null;
if ( sLangCode.Length > 6)
{
Reponse.Redirect("Error.aspx?msg=Invalid Input");
}
else
{
try
{
String strSql = "SELECT* FROM Table";
Dataset ds = Dataprovider.Connect_SQL(strSql);
}
catch( Exception ex)
{
response.redirect("Error.aspx?msg="+ex.Message);
}
}
return pgName;
}
I have may function defined in Business and Datalayer where i want to trap the error and redirect user to the Error page.
HttpContext.Current.Response.Redirect("error.aspx");
to use it your assembly should reference System.Web.
For a start, in one place you're trying to use:
response.redirect(...);
which wouldn't work anyway - C# is case-sensitive.
But the bigger problem is that normally Response.Redirect uses the Page.Response property to get at the relevant HttpResponse. That isn't available when you're not in a page, of course.
Options:
Use HttpContext.Current.Response to get at the response for the current response for the executing thread
Pass it into the method as a parameter:
// Note: parameter names changed to follow .NET conventions
public static string GetPageName(String pageFileName, String langCode,
HttpResponse response)
{
...
response.Redirect(...);
}
(EDIT: As noted in comments, you also have a SQL Injection vulnerability. Please use parameterized SQL. Likewise showing exception messages directly to users can be a security vulnerability in itself...)

Categories

Resources