I have created an OData v3 service which includes EntityTypes with properties whose type is a collection (http://www.odata.org/documentation/odata-version-3-0/common-schema-definition-language-csdl#csdl5.1), for example:
<EntityType Name="Apps">
…
<Property Name="tags" Nullable="false" Type="Collection(Edm.String)"/>
…
</EntityType>
I have created a client for that service with Visual Studio (2012 and 2013) through right click in the project > Add Service Reference which creates a proxy class (AndroidContext in my example) for the service.
My problem is, when I try to retrieve an entity:
var app = androidContext.Apps.Where(a => a.Title == "Some title").First();
it throws an InvalidOperationException:
"Collection types are only supported in version 3.0 of the OData protocol and higher versions. They are not supported in version 2.0."
I have found that the proxy class created by Visual Studio has only one constructor which receives as only parameter the URI of the service. This constructor calls a base constructor (of the inherited class DataServiceContext) that use Odata v2 by default:
public DataServiceContext(Uri serviceRoot)
: this(serviceRoot, DataServiceProtocolVersion.V2)
{
}
I don’t understand why there is not a constructor that allows the creation of a proxy for OData v3. The solution I have used is to declare a new constructor for the proxy class (is partial) that allows OData v3:
public partial class AndroidContext
{
public AndroidContext(Uri serviceRoot, DataServiceProtocolVersion version) :
base(serviceRoot, version)
{
//The same that the generated constructor do
}
}
Does someone knows why Visual Studio does not allows the use of OData v3 by default? Does someone knows another solution?
Related
I have decorated my service interface with Http Verb Attributes, but is not working.
Every method is treated as Post verb.
I'm using AspNetCore 1.1 and Abp packages 2.3.0
public interface ISettlementAppService : IApplicationService
{
Task<PagedResultDto<SettlementListDto>> GetPaged(GetSettlementInput input);
[HttpDelete]
Task Cancel(EntityDto<string> input);
}
For AspNet Core, add these attributes to the application service class, not to interface. Because they are handled by AspNet Core MVC (not by ABP) and it does not know about interfaces.
From the documentation (https://aspnetboilerplate.com/Pages/Documents/AspNet-Core#controllers):
Note: Previously, dynamic web api system was requiring to create service interfaces for application services. But this is not required for ASP.NET Core integration. Also, MVC attributes should be added to the service classes, even you have interfaces.
Do it like this;
public class SettlementAppService : ISettlementAppService
{
[HttpDelete]
Task Cancel(EntityDto<string> input){
//...
}
}
VS2013: WCF service and client.
Service contains class like:
[DataContract]
[KnownType(typeof(Class2))]
public class BaseClass1
{
...
}
When I generate client proxy using Visual studio 2013 'Update Service Reference' then proxy class does not contain KnownTypeAttribute of Class2.
But if I generate it manually using command string:
svcutil.exe http://localhost:8082/IService/mex /noConfig
the generated class has this attribute.
Also, VS2010 generates correct proxy class containing KnownTypeAttribute.
How to solve this problem?
I have a ASP.NET web API project and since it does not support having 2 body parameters, I use a JObject parameter and then extract the actual parameters from it. Like this.
Public bool mymethod(JObject data){
myclassA a = data["a"].toObject<myclassA>();
myclassA b = data["b"].toObject<myclassB>();
}
But the 2 class types implement ISerializable and I need the JSON.NET to ignore it. I have set up the default JSON.NET serializer to do that and it works fine when serialization is done automatically.
But I need to get a reference to the built in JSON.NET serializer so that I could use it like this in the above code.
myclassA b = data["b"].toObject<myclassB>(defaultSerializer);
Currently I create a new instance of the JSON.NET serializer and use it. But how can I get a reference to the default built in serializer in the asp.net WEB API ?
Also I cannot change anything in class types as this is sort of a legacy app that I'm converting to web api. Thanks.
Try this:
JsonSerializer serializer = JsonSerializer.Create(Configuration.Formatters.JsonFormatter.SerializerSettings);
That should give you the same serializer Web API uses.
I added ASP.NET Web API RC to my MVC3 project using NuGet:
Install-Package AspNetWebApi
Then I configured it. In Global.asax.cs:
// configure regular controllers
var configuration = GlobalConfiguration.Configuration;
var container = Bootstrapper.ConfigureContainer(configuration);
containterProvider = new ContainerProvider(container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// Set the dependency resolver implementation for Web API.
var resolver = new AutofacWebApiDependencyResolver(container);
configuration.DependencyResolver = resolver;
And in Boostrapper.ConfigureContainer(...) I added:
// I register my types as InstancePerLifetimeScope()
// but I also tried .InstancePerHttpRequest().InstancePerApiRequest()
// to the same end
builder.RegisterType<SomeService>()
.AsImplementedInterfaces().InstancePerLifetimeScope();
// Register API controllers using assembly scanning.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(config);
This is described here and here.
I also updated Autofac, Autofac.Web, Autofac.Mvc3 packages using NuGet and installed Autofac.WebApi package.
With this configuration I tried running my ApiController and got the following error:
No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
Then as I read this comment from Alex Meyer-Gleaves:
I suspect you are using the Web API package with MVC3 and this is causing the problem. In the MVC3 integration the tag for the InstancePerHttpRequest lifetime scope was "httpRequest". It was in the MVC4 Beta and Web API Beta packages that I changed both InstancePerHttpRequest and InstancePerApiRequest to use the common tag "AutofacWebRequest". You can grab the MVC4 integration package from NuGet using Autofac.Mvc4.
source article with comment
So following the advice from Alex I got the package Autofac.Mvc4 but it works only with Mvc4 and my project wouldn't build. I then grabbed the source code of Autofac to build Autofac.Mvc4 against Mvc3:
hg clone https://code.google.com/p/autofac/ --branch "MVC4 beta" C:\my\path
After using this assembly as my reference ApiController started working but regular Controllers worked ok only for a single controller action call. When the view called Html.RenderAction(...) and when I refresh or navigate to another controller action it crashes with this error:
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
I thought building from the newest source for Autofac.Mvc4 version 2.6.2.859 against Mvc3 could help but I can't find the source for that. Or maybe there's something else wrong in here?
I found the problem. I also used Autofac.Integration.Web to inject dependencies into custom Membership and Role providers. But in WebLiftime.cs there was this line:
public static readonly object Request = "httpRequest";
Once I changed it to:
public static readonly object Request = "AutofacWebRequest";
and used the built assembly everything works fine and I get no errors :)
I believe this constant value should the same as in all projects Autofac.Integration.Web, Autofac.Integration.Mvc and 'Autofac.Integration.WebApi for Mvc4 so this supposedly is a bug.
I am creating a MVC3 website that will expose a REST API using WCF Web API.
To register routes to the REST API I add code to the Global.asax similar to the code below.
routes.MapServiceRoute<RelationsService>("relations");
This works well enough but i need to use a DI approach to inject the dependencies that the Service depends on.
As you can see in the code above the MVC framework is creating the instance of the RelationsService but this should be done by the DI container.
Does anyone know how to configure MVC3 so that my own DI container is used for creating the instances of the Services?
You have to extend your current service registration call with an IHttpHostConfigurationBuilder that has been created with an IResourceFactory.
var configurationBuilder = HttpHostConfiguration.Create()
.SetResourceFactory(new ResourceFactory());
routes.MapServiceRoute<RelationsService>("relations", configurationBuilder);
Then if you for instance use StructureMap as preferred IoC/DI tool you can just ask for the service in the GetInstance method.
public class ResourceFactory : IResourceFactory
{
public object GetInstance(Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
{
return ObjectFactory.GetInstance(serviceType);
}
}