Automation error on Webclient.Headers - vb6

I have an error in the following code when using the Headers property:
Public Function UploadImage(image As String) As String
Dim wc As System.WebClient
'create WebClient
Set wc = CreateObject("System.Net.WebClient")
Call wc.Headers.Add("Authorization", "Client-ID " & ClientId) <------- Error occurs here

I have repro'd your issue as far as possible. You didn't mention what the error you were getting was, but I got:
Automation error -2146233079 (80131509)
I tried using
CallByName(wc, "Headers", VbGet)
... but that just returns
Automation error 440.
Oh well...
I looked up online, and found this link. My guess is that because the base class of the WebHeaderCollection class is not COM Visible, this causes the error.
My work-around would be to wrap up this functionality in a small .NET component, and make that COM visible.
An example of this would be something like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
namespace WebClientWrapper
{
[ComVisible(true)]
[Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]
public class WebClientWrapper : WebClient
{
[ComVisible(true)]
public WebHeaderCollectionWrapper WHeaders
{
get
{
return new WebHeaderCollectionWrapper(base.Headers);
}
}
}
[ComVisible(true)]
[Guid("yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy")]
public class WebHeaderCollectionWrapper
{
WebHeaderCollection _whc;
internal WebHeaderCollectionWrapper(WebHeaderCollection whc)
{
_whc = whc;
}
[ComVisible(true)]
public void Add(string name, string value)
{
_whc.Add(name, value);
}
[ComVisible(true)]
public void Clear()
{
_whc.Clear();
}
}
}
(You will have to replace the GUIDs with your own values - use GUIDGEN.EXE).
Instantiate this component with CreateObject("WebClientWrapper.WebClientWrapper")
Now you would simply replace references to the Headers property to WHeaders (or whatever you want to call it). WHeaders gives you a true wrapper around WebHeaderCollection - you'll have to define all the other wrapped methods and properties yourself. I was hoping to define WHeaders as public WebHeaderCollectionWrapper, but that didn't seem to work.
Since WebClientWrapper inherits from WebClient, you should be able to use most of the properties and methods. Where you have troubles, just add new methods to the class wrapping up the functionality that doesn't work with VB.
Oh, and do remember to set the checkbox at Project Properties => Build => Output => Register for COM interop. And then reference the type library created.

Related

Access Cloudscribe SiteID outside Controller or Views

I have a class which I want to get the Cloudscribe SiteId but I am unsure how to access it.
If I was using a controller then I would be able to rely on the SiteContext to be DI'd into the constructor but that does not work in this instance.
Can someone tell me how I can access the SiteId property in the code below?
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CoLabR
{
public class Messaging : Hub
{
private string _siteId;
public Messaging()
{
//Code here to get SiteID
_siteId = "<<Code for getting Site ID";
}
public Task Post(string message)
{
return Clients.Group(_siteId).InvokeAsync("Post", message);
}
public Task JoinRoom()
{
Groups.AddAsync(Context.ConnectionId, _siteId);
return Clients.Group(_siteId).InvokeAsync("Post", Context.User.Identity.Name + " joined. " + _siteId);
}
}
}
SignalR Core supports injecting into hubs so you should be able to just inject SiteContext into Messaging.
Here is a related question that shows how to do that.
Although the answer from #Pawel helped me, my final solution differed. I tried registering SiteContext in my Startup.cs and injecting SiteContext into my constructor for the Hub but it kept returning a different SiteID on each page load (or if I used Singleton it gave me the same SiteId across multiple CloudScribe Sites).
In the end my solution was to change the Hub constructor to the below code
public Messaging(SiteUserManager<SiteUser> userManager)
{
//Code here to get SiteID
_siteId = userManager.Site.Id.ToString();
}
This gave me a consistent SiteId for each Tenant site in my application.

Does Subject.Subscribe only work in a static instance (or am I missing something)

I'm mucking about with reactive extensions and Iv'e hit a snag that I can't for the life of me work out what the cause is.
If I use a .NET 4 console mode app, where everything is static as follows:
using System;
using System.Reactive.Subjects;
using FakeDal;
using FakeDal.Entites;
using RxProducer;
namespace Runner
{
class Program
{
private static readonly Subject<DaftFrog> _subject = new Subject<DaftFrog>();
private static readonly Repository<DaftFrog> _frogRepo = new Repository<DaftFrog>();
static void Main()
{
_subject.Subscribe(RespondToNewData);
}
private static void RespondToNewData(DaftFrog frog)
{
_frogRepo.Save(frog);
}
}
}
DaftFrog is just a test class in my fake DAL class, this is a simple .NET 4 Class library project, the DaftFrog class, is a simple poco with a few fields in, the dal.save method just simply does a console.WriteLine of a field in the DaftFrog object.
Both classes are just simple stand in's for the real things once I get around to making the RX code work.
Anyway, back to the problem, so the code above works fine, and if I do a few
_subject.OnNext(new DaftFrog());
calls, the fake dal class, prints out what I expect and everything works fine...
HOWEVER>....
If I then transport this code as is, to a class library, and then new up that class library from within my "static program" as follows:
using System.Reactive.Subjects;
using FakeDal;
using FakeDal.Entites;
namespace RxProducer
{
public class Producer
{
private readonly Subject<DaftFrog> _subject = new Subject<DaftFrog>();
private readonly Repository<DaftFrog> _frogRepo = new Repository<DaftFrog>();
private int _clock;
public void Start()
{
_subject.Subscribe(RespondToNewData);
}
public void Stop()
{
}
public void Tick()
{
if(_clock % 5 == 0)
{
DaftFrog data = new DaftFrog();
_subject.OnNext(data);
}
_clock++;
}
private void RespondToNewData(DaftFrog frog)
{
_frogRepo.Save(frog);
}
}
}
And then use that class in my program
using System;
using RxProducer;
namespace Runner
{
class Program
{
private static readonly Producer _myProducer = new Producer();
static void Main()
{
_myProducer.Start();
while(!line.Contains("quit"))
{
_myProducer.Tick();
line = Console.ReadLine();
}
_myProducer.Stop();
}
}
}
Then my project fails to compile.
Specifically it fails on the line:
_subject.Subscribe(RespondToNewData);
in the RxProducer class library, mores the point, the error the compiler throws back makes little sense either:
Error 1 The best overloaded method match for 'System.Reactive.Subjects.Subject<FakeDal.Entites.DaftFrog>.Subscribe(System.IObserver<FakeDal.Entites.DaftFrog>)' has some invalid arguments H:\programming\rxtesting\RxProducer\Producer.cs 17 7 RxProducer
Error 2 Argument 1: cannot convert from 'method group' to 'System.IObserver<FakeDal.Entites.DaftFrog>' H:\programming\rxtesting\RxProducer\Producer.cs 17 26 RxProducer
At first I thought that it might have been the static thing, so I made everything in the class library static, and that made no difference at all.
Iv'e really not done much with Rx until now, but I work with C# and VS 99% of the time, so I'm aware that the error is telling me it can't convert a type of some description, I just don't understand why it's telling me that, esp when the code works perfectly in the static program, but not in a class library.
Shawty
UPDATE
Second thoughts, I just know there are going to be those who insist that I post the fakedal and daft frog definitions, even though IMHO they won't be required, but to pacify the hordes of pretenders who will ask here they are :-)
using System;
namespace FakeDal
{
public class Repository<T>
{
public void Save(T entity)
{
Console.WriteLine("Here we write T to the database....");
}
}
}
namespace FakeDal.Entites
{
public class DaftFrog
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsTotalyDaft { get; set; }
}
}
Include using System; into file where you have Producer, this will help to convert RespondToNewData to IObserver<T>.
Sounds like the compiler is having trouble inferring the Action...might be missing a using statement for the relevant extension method. Alternatively, try either of:
_subject.Subscribe ((Action<DaftFrog>) RespondToData);
Or:
var obs = Observer.Create ( I forget the overload );
_subject.Subscribe( obs);

In which namespace is the extension method EntityTypeConfiguration.MapSingleType

I am trying to implement the following code to map a database to a POCO that has slightly different Property names then the corresponding columns, and a slightly different class name than the table name.
Here's the article
The problem is there is no method called MapSingleType. I have the following two methods available:
public EntityTypeConfiguration<TEntityType> Map<TDerived>(Action<EntityMappingConfiguration<TDerived>> derivedTypeMapConfigurationAction) where TDerived : class, TEntityType;
public EntityTypeConfiguration<TEntityType> Map(Action<EntityMappingConfiguration<TEntityType>> entityMappingConfigurationAction);
However, I can't find any examples of how to use them and I'm hoping to find the MapSingleType method since that works perfect for the very large number of columns I have to map.
I have downloaded CTP4 from here
And I am using EF 4.0.3
Here is the code I have so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using PlayingWithEF.DAL.CLS.Classes;
using System.Data.Entity.ModelConfiguration;
namespace PlayingWithEF.DAL.CLS.Context
{
public class CLSContext : DbContext
{
public DbSet<Listing> Listings { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Listing>().Map(...?)
}
}
}
You're going to have to map each property individually:
modelBuilder.Entity<Listing>()
.Property(l => l.YourProperty)
.HasColumnName("PropertyName");
modelBuilder.Entity<Listing>()
.ToTable("TableName");
You can't use CTP4 and EF 4.0.3 together, they're different versions of the same library.
I believe this functionality was removed from the betas at some point, and is no longer in the shipping version.

TypeInitializationException When Using Moles With HtmlAgilityPack

I am attempting to use Moles to test a non-static method in a separate assembly. When running the test without the [HostType("Moles")] tag, the test runs fine. When I replace it I receive the following error:
"The type initializer for 'HtmlAgilityPack.HtmlNode' threw an exception."
I have attached code samples that perform in an identical manner.
Any help would be great!
Class/method being called by the unit test
using System;
using HtmlAgilityPack;
using System.Web;
namespace HAPAndMoles
{
public class Class1
{
public void fooBar()
{
HtmlDocument foo = new HtmlDocument();
}
}
}
Unit Test
using System;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using HAPAndMoles;
using Microsoft.Moles.Framework;
using HtmlAgilityPack;
using System.Web;
namespace HAPAndMoles
{
[TestClass]
public class UnitTest1
{
[TestMethod]
[HostType("Moles")]
public void TestMethod1()
{
Class1 bar = new Class1();
bar.fooBar();
}
}
}
I'm not sure I understand your example because in fact you don't use Moles.
If you just want to "Mole" our own non-virtual method, in the references of your test project you just have to right-click on the assembly of the tested project and choose Add Moles Assembly. That will create an HAPAndMoles.Moles reference.
Then add the corresponding using and you can call your class "moled" starting with M (Class1 => MCLass1). I show you an example testing the MClass1 behaviour:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using HAPAndMoles;
using HAPAndMoles.Moles;
namespace HAPAndMoles {
[TestClass]
public class UnitTest1
{
[TestMethod]
[HostType("Moles")]
public void TestMethod1()
{
bool called = false;
var bar = new MClass1()
{
fooBar = () => called = true
};
((Class1)bar).fooBar();
Assert.IsTrue(called);
}
}
}
When I want Moles of mscorlib, I right-click directly on the references of the test project and I can Add Moles Assembly for mscorlib. Then the
using Microsoft.Moles.Framework;
is needed.

Common DataAnnotations in ASP.Net MVC2

Howdy, I have what should be a simple question. I have a set of validations that use System.CompontentModel.DataAnnotations . I have some validations that are specific to certain view models, so I'm comfortable with having the validation code in the same file as my models (as in the default AccountModels.cs file that ships with MVC2). But I have some common validations that apply to several models as well (valid email address format for example). When I cut/paste that validation to the second model that needs it, of course I get a duplicate definition error because they're in the same namespace (projectName.Models). So I thought of removing the common validations to a separate class within the namespace, expecting that all of my view models would be able to access the validations from there. Unexpectedly, the validations are no longer accessible. I've verified that they are still in the same namespace, and they are all public. I wouldn't expect that I would have to have any specific reference to them (tried adding using statement for the same namespace, but that didn't resolve it, and via the add references dialog, a project can't reference itself (makes sense).
So any idea why public validations that have simply been moved to another file in the same namespace aren't visible to my models?
CommonValidations.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
namespace ProjectName.Models
{
public class CommonValidations
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class EmailFormatValidAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value != null)
{
var expression = #"^[a-zA-Z][\w\.-]*[a-zA-Z0-9]#[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$";
return Regex.IsMatch(value.ToString(), expression);
}
else
{
return false;
}
}
}
}
}
And here's the code that I want to use the validation from:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Growums.Models;
namespace ProjectName.Models
{
public class PrivacyModel
{
[Required(ErrorMessage="Required")]
[EmailFormatValid(ErrorMessage="Invalid Email")]
public string Email { get; set; }
}
}
You have declared EmailFormatValidAttribute as a subclass to CommonValidations. As such you need to reference it like CommonValidations.EmailFormatValidAttribute. Or alternatively move the EmailFormatValidAttribute class out of the CommonValidations class.
This should work:
[CommonValidations.EmailFormatValid(ErrorMessage="Invalid Email")]
public string Email { get; set; }
By the way, you can simplify your class as follows:
public class EmailFormatValidAttribute : RegularExpressionAttribute
{
public EmailFormatValidAttribute() :
base(#"^[a-zA-Z][\w\.-]*[a-zA-Z0-9]#[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$")
{}
}
Also, take a look at this: Data Annotations Extensions. It's a great DataAnnotations library which has already the most common validations included in it.

Resources