Can I stop .net 4.0 from encoding single quotes? - c#

After switching to .net 4.0, some javascript code from a third party gridview crashes.
It has got something to do with HtmlEncode and UrlEncode now encode single quotation marks
So before some code on the page was inserted like this:
DataItem.GetMember('Id').Value
and now its like this: DataItem.GetMember('Id').Value
The gridview does an eval on that line, and crashes with a syntax error now. I can't change the javascript code in that gridview.
Is there anyway to solve this, without going backwards like this?
<pages controlRenderingCompatibilityVersion="3.5" />
EDIT: the pages controlRenderingCompatiblityVersion doesn't fix this also. Single quotes are still encoded.

From what I've read, it's a security feature and Microsoft is mum about changing it. The only work-around I've seen is you will need to create a custom encoder class. You can turn-off attribute encoding using this:
public class HtmlAttributeEncodingQuote : System.Web.Util.HttpEncoder
{
protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
{
output.Write(value);
}
}
Then add this to web.config under system.web:
<httpRuntime encoderType="HtmlAttributeEncodingQuote"/>

Related

How Force browser to reload cached static file with versioning?

After deploying a new version of a website the browser loads everything from its cache from the old webpage until a hard, force refresh is done.
In ASP.NET MVC if the file becomes in Bundle, it handled by Optimization framework. a version added to your file link, and if a change occurs in your bundle's file a new token generate. follow below code :
for example, js file name is: datatables
when you put it in a bundle with the same name, you will see the
datatables?v=anY9_bo7KitrGnXQr8ITP3ylmhQe9NDzSjgLpLQWQFE1
as a file name.
change datatables and watch again the name of the file in the browser, surely it will change:
datatables?v=r8yhQBxKyDgrOGyqr1ndtdG92Ije09nqTY7yogrOSTk1
But there's two questions:
What we can do if our file wasn't in Bundle?
Is a way to force the browser to refresh cache?
we have one solution with some different way for implementation. we use above solution for it.
datatables?v=1
we can handle the version of the file, it's mean that every time that we change our file, change the version of it too. but it's not a suitable way.
another way used Guide, it wasn't suitable too, because each time it fetches the file and doesn't use from the browser cache.
datatables?v=Guid.NewGuid()
The last way that is the best Way is :
when file change occur , change version too. check follow code :
<script src="~/scripts/main.js?v=#File.GetLastWriteTime(Server.MapPath("/scripts/main.js")).ToString("yyyyMMddHHmmss")"></script>
by this way, when you change the file, LastWriteTime change too, so the version of the file will change and in the next when you open the browser, it detects a new file and fetch it.
Assuming you cannot use bundling for some reason, the solution suggested by the original poster is good enough, however it's better to put the logic inside a helper method.
It makes the code testable, it helps to change the logic without changing .cshtml , and also helps to not repeat the filename twice. Then you can have have a much cleaner code:
<script src="#Url.ContentWithVersion("~/scripts/main.js")"></script>
To do so, you can add ContentWithVersion extension method to the existing UrlHelper:
using System;
using System.IO;
using System.Web;
using System.Web.Mvc;
public static class UrlHelperExtensions
{
public static string ContentWithVersion(this UrlHelper urlHelper, string path)
{
if (urlHelper == null)
throw new ArgumentNullException(nameof(urlHelper));
var result = urlHelper.Content(path);
var file = HttpContext.Current.Server.MapPath(path);
if (File.Exists(file))
result += $"?v={File.GetLastWriteTime(file).ToString("yyyyMMddHHmmss")}";
return result;
}
}

Passing HTML OBJECT PARAM to C# ActiveX

I've been given the task of updating an old OCX using C#. Everything works fine apart from one thing.
I've now been told that we need to add in a Param specifying a port.
The old HTML looked like this:
<object classid="clsid:D636293D-5687-4847-B53E-D4B4F3FABAD0" id="ActiveXTest3">
<param name="Port" value="8085" />
</object>
The main requirement is that the code to display the control is kept in a static html page.
No Javascript allowed (not sure why but it's what I've been told!)
Now doing some digging some posts say its not possible in .NET. Some say it is possible but hosting the object as an ASPX page. I've found some reference to using
IPropertyBag
in my C# ActiveX Control but can't find any definitive solution or answer.
Can someone clear this up and if possible a simple example?
use a com visible interface and place there something like
String Text { set;get;}
And, In the control class place something like
public String Text
{
get
{
return mStr_Text;// mStr_Text is private variable declared in the control class//
}
set
{
mStr_Text = value;
this.label1.Text = value.ToString();// will change the label's Text
}
}
After that you can place the param name as Text.

Data Driven MSTest: DataRow is always null

I am having a problem using Visual Studio data driven testing. I have tried to deconstruct this to the simplest example.
I am using Visual Studio 2012. I create a new unit test project.
I am referencing system data.
My code looks like this:
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
[DeploymentItem(#"OrderService.csv")]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "OrderService.csv", "OrderService#csv", DataAccessMethod.Sequential)]
[TestMethod]
public void TestMethod1()
{
try
{
Debug.WriteLine(TestContext.DataRow["ID"]);
}
catch (Exception ex)
{
Assert.Fail();
}
}
public TestContext TestContext { get; set; }
}
}
I have a very small csv file that I have set the Build Options to to 'Content' and 'Copy Always'. I have added a .testsettings file to the solution, and set enable deployment, and added the csv file.
I have tried this with and without |DataDirectory|, and with/without a full path specified (the same path that I get with Environment.CurrentDirectory). I've tried variations of "../" and "../../" just in case. Right now the csv is at the project root level, same as the .cs test code file.
I have tried variations with xml as well as csv.
TestContext is not null, but DataRow always is.
I have not gotten this to work despite a lot of fiddling with it. I'm not sure what I'm doing wrong.
Does mstest create a log anywhere that would tell me if it is failing to find the csv file, or what specific error might be causing DataRow to fail to populate?
I have tried the following csv files:
ID
1
2
3
4
and
ID, Whatever
1,0
2,1
3,2
4,3
So far, no dice.
I am using ReSharper, could it be interfering in some way?
Updated
I have it mostly working now! I am able to use XML, but when I use CSV my column, which is named ID comes back as ID
Not sure why. I've checked the actual file of course, and no weird characters are present.
For anyone having a similar problem, I turned off Just My Code and enabled Net Framework source stepping, etc. so that I could get more detailed debug information. This allowed me to determine that ReSharper was causing me problems. I disabled resharper and modified my attributes like this:
[DeploymentItem("UnitTestProject1\\OrderService.csv")]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\bin\\Debug\\OrderService.csv", "OrderService#csv", DataAccessMethod.Sequential)]
And it worked (except as noted). I am still suspicious of the "bin\debug" in my path, but I'm just happy my DataRow is no longer null.
Thanks!
Any ideas?
I was struggling with a similar problem today when trying to make data-driven tests work with CSV input file. The name of the first column had some garbage at the beggining of it, i.e. ID instead of just ID.
It turned out it was an encoding issue. The CSV file was saved in UTF-8 which adds a byte order mark at the beginning, obviously confusing the parser. Once I saved the file in ANSI encoding, it worked as expected.
I know it's an old question, but this information might help someone else ending up on this page.
Have you tried adding it through the properties window?
Go to Test menu -> Windows -> Test View -> the tests will load up.
Click on the test to alter i.e. TestMethod1 and press F4 (properties).
Look for 'Data Source' and click the ellipses next to it
It will walk you through a wizard that sets up the attributes properly for the TestMethod
You have the deployment part set up properly, which is normally the big stumbling block.
You also don't have to set the build action to Copy Always as the deployment does this for you. This option is used if you include items like .xml files you use for configs, or icons/images as part of your project.
Update 1:
Also try this tutorial on MSDN.
Update 2:
Try this post, involving ProcMon
I see that you said you tried putting the CSV itself into the testsettings file, but have you tried just putting in the directory?
<Deployment>
<DeploymentItem filename="Test\Data\" />
</Deployment>
Then your DataSource line will look something like this:
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\YOURCSV.csv", "YOURCSV#csv", DataAccessMethod.Sequential)]
If you do it this way, you don't need to specify the DeploymentItem line.
Our folder structure looks like this: Trunk\Test\Test\Data
We include: Test\Data in the deployment
We then access Test\Data via the |DataDirectory|\
All CSVs live within the \Data folder

How to concat a variable into some <asp: .. /> attribute?

I'm working on small web form,in C#/ASP.NET. I want to store the errors messages into variables of C# class; something like this:
public static class ErrorMessages {
public static string fooX = "baa";
// etc..
}
And then concat it in some attribute of an ASP tag:
<asp:RegularExpressionValidator runat="server"
ControlToValidate="baain"
ErrorMessage= *ErrorMessages.fooX*
/>
Is it possible? if yes, how to do this?
In the aspx page you may try:
ErrorMessage='<%# ErrorMessages.fooX %>'
In your code behind on page load call DataBind();:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DataBind();
}
}
I am not sure about concatenating the aspx part of the page, you can set the ErrorMessage property of your RegularExpressionValidator in the code behind. Something like:
RegularExpressionValidator1.ErrorMessage = "Your message";
or
RegularExpressionValidator1.ErrorMessage = ErrorMessages.fooX;
One approach to this, is to create your own custom expression builder.
The ExpressionBuilder class is the base class for expression builders, such as the AppSettingsExpressionBuilder class, that create code expressions during page parsing.
Expression builders parse declarative expressions and create code to retrieve values bound to a control property. In no-compile scenarios, an expression builder that supports a no-compile feature evaluates the expression during run time.
Please see the link from msdn for more detailed explanation and example.
http://msdn.microsoft.com/en-us/library/system.web.compilation.expressionbuilder.aspx
This is simple, have you tried this:
<%= YourNamespace.YourConstant %>
Or (.Net 4, this option will automatically encode the text)
<%: YourNamespace.YourConstant %>
There are several operators:
<%# Used for data binding
<%$ Used for expressions, not code; often seen with DataSources:
<%= Returns a string
<%: Same as <%= but it auto-html-encodes the value within the tag
Edit 1
Well I just tested and it appears that you cannot use inline code with server controls...
So alternative approaches:
Simply assign the value using code behind
this.myRegularExpressionValidator.ErrorMessage = ErrorMessages.Foo;
Use resources instead. With resources you will gain many benefits like localization for your site and since resources are simply xml files, you can drop them in your site without recompile (assuming you are not using satellite assemblies to store your resources)
<asp:RegularExpressionValidator runat="server" ErrorMessage="<%$ Resources:Resource, MyResource %>" />
Where
Resource refers to the global resource file
MyResource refers to the key in the resource file containing the text
The global resources must be placed in the App_GlobalResources ASP.Net special folder, as an example the resource file name: Resource.resx
Example of the resource file
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="MyResource" xml:space="preserve">
<value>My error message</value>
</data>
</root>
The resource files can be added and managed using Visual Studio so you do not have to deal manually with the XML

ASP.NET framework bug

Go into your iis machine level settings and add
<deployment retail="true" />
As specified in http://msdn.microsoft.com/en-us/library/ms228298.aspx
Create a new web project, add a label and then the following code.
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = HttpContext.Current.IsDebuggingEnabled.ToString();
}
//Result: true
What am I missing?
Update: I updated the value on the 64 and 32 bit versions of the machine config. The server is running IIS7.5. Reboot didn't help.
Update 2:
Stepping through V4 of the framework using Reflector I get the following code.
public bool IsDebuggingEnabled
{
get
{
try
{
return CompilationUtil.IsDebuggingEnabled(this);
}
catch
{
return false;
}
}
}
internal static bool IsDebuggingEnabled(HttpContext context)
{
return MTConfigUtil.GetCompilationConfig(context).Debug;
}
//Here is where I lose whats going on... Either way, if what Yaur said is correct then
//I believe that value is not only useless but dangerously misleading.
internal static CompilationSection GetCompilationConfig(HttpContext context)
{
if (!UseMTConfig)
{
return RuntimeConfig.GetConfig(context).Compilation;
}
return GetConfig<CompilationSection>(context);
}
Either way. What I can confirm is that the functionality does not seem to work.
PS: #Yaur - Yes I have tried changing the value and I am well aware of the alternatives to using this method but the point is that this method is supposed to simplify deployment.
According to : http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx, it should force :
<system.web>
<compilation debug="false">
</system.web>
Have you rebooted your server ?
Which machine.config did you edit ?
Looking at HttpContext in reflector all this method does is to load the value found in the compilation section. So set that as mathieu suggested and you you should be golden.
Also (if you care) it will throw an exception if running under mono.
from the 2.0 version of System.Web:
it calls
CompilationUtil.IsDebuggingEnabled(this);
which calls
RuntimeConfig.GetConfig(context).Compilation.Debug;
Compilation.Get returns
(CompilationSection) this.GetSection("system.web/compilation", typeof(CompilationSection), ResultsIndex.Compilation);
the 4.0 version is a bit different... based on what I can tell it looks the "extra stuff" is multitargeting support. So if you are targeting .net 4 and setting <compilation debug="false"> didn't work try following the example here and use
<system.web>
<compilation debug="false" targetFramework="4.0">
</compilation>
instead

Categories