peverify bugs fixed in .NET 4? - clr

I have VS .NET 2010 installed, and a class library targeting .NET 3.5. The simple C# fragment below generates verifiable IL under .NET 4.0's peverify, but the IL does not verify using .NET 3.5's peverify.
Were there any peverify bugs fixed in this transition?
public static bool IsGenericTypeInstance(this Type typ)
{
return typ.IsGenericType && !typ.IsGenericTypeDefinition;
}
public static IEnumerable<Type> GetAllGenericArguments(this Type type)
{
return type.IsGenericTypeInstance()
? type.GetGenericArguments()
.SelectMany(x => x.IsGenericTypeInstance()
? GetAllGenericArguments(x)
: new[] { x })
: Enumerable.Empty<Type>();
}
The error generated is:
Error 26 [Sasa.dll : Sasa.Types::<GetAllGenericArguments>b__0]
[offset 0x0000001C][found ref 'System.Collections.IEnumerable']
[expected ref 'System.Collections.Generic.IEnumerable`1[System.Type]']
Unexpected type on the stack.
I'm obviously a little concerned since I'm explicitly targeting .NET 3.5, and I don't want runtime verification errors on this platform.

Related

Create a certificate request using .netstandard 2.0 library

NetStandard 2.0 apparently does not include `System.Security.Cryptography.X509Certificates.CertificateRequest'.
So is it not possible to create X509Certificates in a .NETStandard 2.0 library? If not, why not? X509Certificates are included so it seems an odd exclusion.
.NET Standard 2.0 was built between .NET Framework 4.6.1 and 4.6.2, and doesn't have types that weren't present in .NET Framework 4.6.2.
CertificateRequest was added to .NET Framework in 4.7.2.
The easiest answer is to target either .NET Framework or .NET Core instead of .NET Standard, then the type will become available (provided you use a high enough version). Alternatively, unless you're using a custom X509SignatureGenerator, the type is simple enough that you could bind it with reflection.
Type certificateRequestType =
Type.GetType("System.Security.Cryptography.X509Certificates.CertificateRequest");
object request = certificateRequestType.GetConstructor(
new[] { typeof(string), typeof(RSA), typeof(HashAlgorithmName), typeof(RSASignaturePadding) }).Invoke(
new object[] { certDN, key, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1 });
Collection<X509Extension> extensions = (Collection<X509Extension>)
certificateRequestType.GetProperty("CertificateExtensions").GetValue(request);
// add things to the extensions collection
...
DateTimeOffset now = DateTimeOffset.UtcNow;
return (X509Certificate2)certificateRequestType.GetMethod("CreateSelfSigned").Invoke(
new object[] { now.AddMinutes(-5), now.AddDays(30) });

An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code

I had working code on VS 2013 NET4.5. After update (VS 2013, NET 4.5.1) of NuGet packages I got this error
An exception of type 'System.InvalidOperationException' occurred in
System.Web.Mvc.dll but was not handled in user code
Additional information: The given filter instance must implement one
or more of the following filter interfaces: IAuthorizationFilter,
IActionFilter, IResultFilter, IExceptionFilter.
I am sure that I implemented IActionFilter interface, so how can I get error like this and how can I fix it?
FYI:
public class WWWActionFilterAttribute : System.Web.Mvc.ActionFilterAttribute, System.Web.Mvc.IActionFilter
{
public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
{
System.Uri Address = filterContext.HttpContext.Request.Url;
string[] domains = Address.Host.Split('.');
if (domains.Length == 2)
{
System.UriBuilder AddressBuilder = new System.UriBuilder(Address);
AddressBuilder.Host = string.Format("www.{0}", AddressBuilder.Host);
filterContext.HttpContext.Response.Redirect(AddressBuilder.Uri.AbsoluteUri);
}
else
{
base.OnActionExecuting(filterContext);
}
}
}
Config
public class FilterConfig
{
public static void RegisterGlobalFilters(System.Web.Mvc.GlobalFilterCollection filters)
{
filters.Add(new System.Web.Mvc.HandleErrorAttribute());
filters.Add(new TIKSN.HomeWebsite.Generalization.WWWActionFilterAttribute());
filters.Add(new TIKSN.HomeWebsite.Globalization.LanguageActionFilterAttribute());
}
}
Are we talking about System.Web.Mvc.dll having to have the save version and if so where? If I add this DLL to my domain I can only get up to version 4.0. However I have a version 5.1 in my web API the project with web config file. I really don't understand why I would have to match these versions and why my solution doesn't recognize the highest version if that is why its failing. I believe Visual Studio 2013 Express automatically loaded version 5.1, but I had to get my own for the domain project and that doesn't offer 5.1. One of the worst things about MVC is dependency management.
You are adding a HttpFilter (WebAPI filter) to an MVC Global filter. Your filter should be added to HttpFilterCollection
Add this to filterConfig.cs
public static void RegisterHttpFilters(HttpFilterCollection filters)
{
filters.Add(new WWWActionFilterAttribute());
}
And this to Global.ascx.cs:
FilterConfig.RegisterHttpFilters(GlobalConfiguration.Configuration.Filters);
This was because of web.config file. You have to specify exact version of packages there. Look here
Update
In Web.config all packages are registered and have their name and version pairs. The actual versions and the versions in the Web.config were not matching.

How to update breeze.js library

I could use some guidance on how to manually update between versions of Breeze and it's dependencies. I do not believe I can just update with the NuGet Package Manager.
I have been developing my Single Page App with Breeze, Knockout, WebAPI and so forth. I have been using Breeze version 0.61 and want to upgrade to the latest version so I can take advantage of the ODataActionFilters and not have to parse the Request.QueryString to pull out parameters and filters. For example when I call
var getMachineById(machineId) {
var query = EntityQuery
.from("Machines")
.where("machineId", "eq", machineId);
return manager.executeQuery(query)
.then(function (data) {
do_something_with(data.results);
})
.fail(queryFailed);
}
There has to be a way for Breeze to handle that for me, so I can just do something like this:
[AcceptVerbs("GET")]
public IQueryable<Machine> Machines()
{
return _contextProvider.Context.Machines;
}
instead of
// eg "?$filter=machineId%20eq%205"
[AcceptVerbs("GET")]
public IQueryable<Machine> Machines()
{
IQueryable<Machine> x = _contextProvider.Context.Machines;
List<ODataQueryString> list = null;
string qs = Request.RequestUri.Query.ToString(CultureInfo.CurrentCulture);
list = new ODataQueryStringParser(qs).Parse();
if (list != null)
{
int machineId = int.Parse(list[0].Value); // covert string to an int
x = x.Where(o => o.MachineId == machineId);
}
return x;
}
I notice that the Attribute decoration in the Controller has changed in the Samples. Do I need to change mine too?
namespace PilotPlantBreeze.Controllers
{
[JsonFormatter, ODataActionFilter]
public class BreezeController : ApiController
{
readonly EFContextProvider<PilotPlantDbContext> _contextProvider =
new EFContextProvider<PilotPlantDbContext>();
[AcceptVerbs("GET")]
public string Metadata()
{
return _contextProvider.Metadata();
}
[AcceptVerbs("POST")]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
... etc.
}
}
I have my 3rd party libraries in a folder ~\Scripts\lib. If I use the NuGet package manager to update, it puts all the replacements in ~\Scripts. How do I move the files into the lib folder without messing up my Team Foundation Server (Azure) source control?
Are the runtime versions of Antlr3.Runtime.dll, Breeze.WebApi.dll, Irony.dll, Newtonsoft.Json.dll, WebActivator.dll and maybe WebGrease.dll compatible between versions. I bet not. Is there something I have to change in Visual Studio?
Can I just change version entries from the package folder in packages.config?
Thanks.
I think that your best approach would be to remove any existing breeze '.js' files and the webApi and irony.dlls from your project and then simply install the latest breeze nuget package. After installing the nuget package you can go ahead and move the files to other locations within the project to match their "old" locations. I'd do the same for the NewtonSoft nuget package as well, just in case ( breeze will add this back for you). Going forward, you can just update to latest nuget and then move the files.
As you noticed you will also need to replace these attributes
[JsonFormatter, ODataActionFilter]
with this attribute
[BreezeController]
This assumes that you are not running a beta version of ASP.MVC4. I think there are posts in other forums that discuss how to migrate away from the beta.

Why does this ViewResult fail MSpecMVC's ShouldBeAView assertion?

I've been following James Broome's tutorial to teach myself MSpec and some of the related infrastructure. I'm using the latest version of MSpec, MSpecMvc, and ASP.NET MVC 2 and I'm not using J.P Boodhoo's libraries.
When I run this test
[Subject(typeof(HomeController))]
public class when_the_home_controller_is_told_to_display_the_default_view
{
static string key;
static string message;
static ActionResult result;
static HomeController home_controller;
Establish context = () =>
{
key = "Message";
message = "Welcome to ASP.NET MVC!";
home_controller = new HomeController();
};
Because of = () => result = home_controller.Index();
It should_return_the_home_view = () => result.ShouldBeAView().And().ViewName.ShouldBeEmpty();
}
I get the following error
should return the home view : Failed
Should be of type System.Web.Mvc.ViewResult but is of type System.Web.Mvc.ViewResult
When I step through the code it conks in the assertion in this method (in the ActionResultExtensions.cs file of MSpecMVC)
public static ViewResultAnd ShouldBeAView(this ActionResult actionResult)
{
actionResult.ShouldBeOfType<ViewResult>();
return new ViewResultAnd(actionResult as ViewResult);
}
Although, I can confirm that actionResult is of type System.Web.Mvc.ViewResult. I've used the same tools on another computer to run other tests but I've not encountered the current issue.
James Broome's MSpec.MVC extensions use Mspec v0.2. Since you are using Mspec v0.3 there is a mismatch. You should get the source and update the solution to use MSpec v0.3.
Make sure the Mspec.MVC extensions target the same .NET Framwork version as your ASP.NET MVC solution (for example, both are 4.0). That will also depend on which version of MSpec you are using. MSpec v0.3 is compiled against both .NET 3.5 and .NET 4.0

Cannot get assembly version for footer

I'm using the automatic build versioning mentioned in this question (not the selected answer but the answer that uses the [assembly: AssemblyVersion("1.0.*")] technique). I'm doing this in the footer of my Site.Master file in MVC 2. My code for doing this is as follows:
<div id="footer">
webmaster#foo.com - Copyright © 2005-<%= DateTime.Today.Year.ToString() %>, foo LLC. All Rights Reserved.
- Version: <%= Assembly.GetEntryAssembly().GetName().Version.ToString() %>
</div>
The exception I get is a Object reference not set to an instance of an object because GetEntryAssembly() returns NULL. My other options don't work either. GetCallingAssembly() always returns "4.0.0.0" and GetExecutingAssembly() always returns "0.0.0.0". When I go look at my DLLs, everything is versioning as I would expect. But I cannot figure out how to access it to display in my footer!!
That's because Assembly.GetEntryAssembly() is returning null: there is no "entry" assembly in an ASP.NET site (because the .NET framework is hosted in the w3wp.exe process). Assembly.GetEntryAssembly() is used to get the .exe assembly that you launched from (usually in a console or Windows application)
The reason Assembly.GetAssembly(this.GetType()) is returning an assembly with version "0.0.0.0" is because ASP.NET compiles your Site.Master file into a temporary assembly under your "ASP.NET Temporary Files" folder. this is a reference to the "generated" class.
Assembly.GetExecutingAssembly() is basically the same as Assembly.GetAssembly(this.GetType()) (except it also works when there is no "this" (e.g. in static methods).
The best way would be use explicity use a type that you know exists in the assembly you're after. As an example, I assume your "Site.Master" has a code-behind file that is compiled into the assembly. You can use that instead:
Assembly.GetAssembly(typeof(Site)).GetName().Version.ToString()
(assuming the name of the class is Site)
Just as another solution that people may be interested in, I've concocted these helpers to help with this problem:
public static class HtmlHelperExtensions
{
private static string _CachedCurrentVersionDate;
/// <summary>
/// Return the Current Version from the AssemblyInfo.cs file.
/// </summary>
public static string CurrentVersion(this HtmlHelper helper)
{
try
{
var version = Assembly.GetExecutingAssembly().GetName().Version;
return version.ToString();
}
catch
{
return "?.?.?.?";
}
}
public static string CurrentVersionDate(this HtmlHelper helper)
{
try
{
if (_CachedCurrentVersionDate == null)
{
// Ignores concurrency issues - assuming not locking this is faster than
// locking it, and we don't care if it's set twice to the same value.
var version = Assembly.GetExecutingAssembly().GetName().Version;
var ticksForDays = TimeSpan.TicksPerDay * version.Build; // days since 1 January 2000
var ticksForSeconds = TimeSpan.TicksPerSecond * 2 * version.Revision; // seconds since midnight, (multiply by 2 to get original)
_CachedCurrentVersionDate = new DateTime(2000, 1, 1).Add(new TimeSpan(ticksForDays + ticksForSeconds)).ToString();
}
return _CachedCurrentVersionDate;
}
catch
{
return "Unknown Version Date";
}
}
}
This allows consumption as follows in your footer:
Version: <%= Html.CurrentVersion() %> from <%= Html.CurrentVersionDate() %>
You can:
e.g in your Application_Start method in Global.asax file add
protected void Application_Start(object sender, EventArgs e)
{
HttpContext.Current.Application.Add("Version", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
}
in HTML show it by
<div><% =HttpContext.Current.Application["Version"].ToString() %></div>
ALSO Change Assembly version to 1.0.0.* by going to
- Project properties > Application > Assembly Information and assembly version is shown as 1.0.0.0 - change it to 1.0.0.*
this will give you some versioning
If you already have Global.asax in place, it could be a good place to store version globally once.
Global.asax.cs:
public class Global : HttpApplication
{
public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version;
}
Your view:
<div>- Version: #YourNamespace.Global.Version</div>

Resources