MVC4 AllowHtml not working with Dictionary - asp.net-mvc-4

I have a class
public class TemplateViewModel
{
[AllowHtml]
public string Template { get; set; }
[AllowHtml]
public Dictionary<string, string> LocalizedContents { get; set; }
}
When I input html code for Template, it's fine.
When I input html code for LocalizedContents, it prompt out the error
System.Web.HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (LocalizedContents[en-us]="...ate:
FB: <a href="www.faceboo...").
at System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection)
at System.Web.HttpValueCollection.EnsureKeyValidated(String key)
at System.Web.HttpValueCollection.GetValues(String name)
at System.Web.Mvc.NameValueCollectionValueProvider.ValueProviderResultPlaceholder.GetResultFromCollection(String key, NameValueCollection collection, CultureInfo culture)
at System.Web.Mvc.NameValueCollectionValueProvider.GetValue(String key, Boolean skipValidation)
at System.Web.Mvc.ValueProviderCollection.GetValue(String key, Boolean skipValidation)
at System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.DefaultModelBinder.CreateEntryForModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type valueType, IModelBinder valueBinder, String modelName, Object modelKey)
at System.Web.Mvc.DefaultModelBinder.UpdateDictionary(ControllerContext controllerContext, ModelBindingContext bindingContext, Type keyType, Type valueType)
at System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.DefaultModelBinder.GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
at System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
at System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model)
at System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState)
Any solution for the [AllowHtml] to be use for Dictionary?
I do not prefer to use the [ValidateInput(false)] as it will have security concern
I also do not want to include <httpRuntime requestValidationMode="2.0" /> in my web config

The alternative way to achieve this is to create a class for the datatype and assign the [AllowHtml] for the property of the class.
public class LocalizedContents
{
[AllowHtml]
public string Key { get; set; }
[AllowHtml]
public string Value { get; set; }
}
Then put the class as datatype for LocalizedContents property
public class TemplateViewModel
{
public string Template { get; set; }
public List<LocalizedContents> LocalizedContents { get; set; }
}

Related

nhibernate query select specific colmns including IList

Ive got a problem with selecting specyfic columns (properties), code below:
Entities:
public class Item {
public Item() {
Images = new List<Image>();
}
public virtual int Id { get; set; }
public virtual int ItemNum { get; set; }
public virtual Channel Channel { get; set; }
public virtual string Title { get; set; }
public virtual string Comment { get; set; }
public virtual string Text { get; set; }
public virtual string Link { get; set; }
public virtual string Category { get; set; }
public virtual DateTime? PublishDate { get; set; }
public virtual string ExternalId { get; set; }
public virtual string SourceImage { get; set; }
public virtual string Bubble { get; set; }
public virtual IEnumerable<Image> Images { get; set; }
}
public class Image {
public Image() { }
private string type;
public virtual int Id { get; set; }
public virtual bool IsMobile { get; set; }
public virtual Item Item { get; set; }
public virtual string Type {get;set;}
public virtual string ImageUrl { get; set; }
public virtual int? Height { get; set; }
public virtual int? Width { get; set; }
public virtual int? ImgXOff { get; set; }
public virtual int? ImgYOff { get; set; }
public virtual decimal? ImgZoom { get; set; }
}
And now I would like to get only Item.Id and all related to row with this Id, my query
var minDate = DateTime.Today - TimeSpan.FromDays(config.ItemsFromLastDaysCount);
var items = session.Query<Item>()
.Fetch(x => x.Channel)
.Where(x => x.Channel.InsertionDate >= minDate)
.OrderByDescending(x => x.Channel.InsertionDate)
.Take(config.ItemsOnOnePage)
.Select(x => new
{
Id = x.Id,
Images = x.Images
}).ToList();
But query like this throws strange to me exception:
"An exception of type 'System.ArgumentException' occurred in System.Core.dll but was not handled in user code
Additional information: Expression of type 'System.Collections.IList' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable`1[System.Object]'"
Stack trace:
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.Invoke(Expression expression, IEnumerable`1 arguments)
at System.Linq.Expressions.Expression.Invoke(Expression expression, Expression[] arguments)
at NHibernate.Linq.ExpressionToHqlTranslationResults.MergeLambdasAndCompile(IList`1 transformations)
at NHibernate.Linq.ExpressionToHqlTranslationResults..ctor(HqlTreeNode statement, IList`1 itemTransformers, IList`1 listTransformers, IList`1 postExecuteTransformers, List`1 additionalCriteria)
at NHibernate.Linq.IntermediateHqlTree.GetTranslation()
at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory)
at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
at Remotion.Linq.QueryableBase`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at TicTac.Service.Controllers.HomeController.Index() in d:\Projekty\Hypermedia\TicTac.RssReader\branches\TicTac.RssReader\TicTac.Service\Controllers\HomeController.cs:line 27
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
exception is because of line:
Images = x.Images
I will be very greatefull for response.

Autofac and ASP .Net MVC 4 Web API

I am using Autofac for IoC in my ASP .Net MVC 4 project. Autofac is having some trouble initializing the repository and passing it to the API Controller.
I am sure I am missing something in my configuration.
Here is the error I get when I navigate to: https://localhost:44305/api/integration
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'
on type 'EL.Web.Controllers.API.IntegrationController' can be invoked with
the available services and parameters: Cannot resolve parameter
'EL.Web.Infrastructure.IRepository`1[EL.Web.Models.Integration] repository' of
constructor 'Void .ctor(EL.Web.Infrastructure.IRepository`1[EL.Web.Models.Integration])'.
</ExceptionMessage>
<ExceptionType>Autofac.Core.DependencyResolutionException</ExceptionType>
<StackTrace>
at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
at Autofac.Core.Resolving.InstanceLookup.Execute()
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)
at Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type serviceType)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
</StackTrace>
</Error>
Here are some relevant bits of code:
IoC Bootstrapper:
public static class Bootstrapper
{
public static void Initialize()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.Register(x => new SharePointContext(HttpContext.Current.Request)).As<ISharePointContext>().SingleInstance();
builder.RegisterType<SharePointRepository<IEntity>>().As<IRepository<IEntity>>();
builder.RegisterType<SharePointContextFilter>().SingleInstance();
builder.RegisterFilterProvider();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
var resolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
}
IRepository:
public interface IRepository<T>
{
void Add(T entity);
void Delete(int id);
IEnumerable<T> Find(Expression<Func<T, bool>> filter = null);
void Update(int id, T entity);
}
SharePointRepository:
internal class SharePointRepository<T> : IRepository<T> where T : IEntity
{
private readonly ISharePointContext _context;
private readonly string _listName;
internal SharePointRepository(ISharePointContext context)
{
_context = context;
object[] attributes = typeof (T).GetCustomAttributes(typeof (SharePointListAttribute), false);
if (!attributes.Any())
{
throw new Exception("No associated SharePoint list defined for " + typeof (T));
}
_listName = ((SharePointListAttribute) attributes[0]).ListName;
}
public void Add(T entity)
{
throw new NotImplementedException();
}
public void Delete(int id)
{
throw new NotImplementedException();
}
public IEnumerable<T> Find(Expression<Func<T, bool>> filter)
{
throw new NotImplementedException();
}
public void Update(int id, T entity)
{
throw new NotImplementedException();
}
}
IntegrationController:
public class IntegrationController : ApiController
{
private readonly IRepository<Integration> _repository;
public IntegrationController(IRepository<Integration> repository)
{
_repository = repository;
}
public void Delete(Guid integrationId)
{
_repository.Delete(Get(integrationId).Id);
}
public IEnumerable<Integration> Get()
{
return _repository.Find();
}
public Integration Get(Guid integrationId)
{
return _repository.Find(i => i.IntegrationId == integrationId).FirstOrDefault();
}
public void Post([FromBody] Integration integration)
{
_repository.Add(integration);
}
public void Put(Guid integrationId, [FromBody] Integration integration)
{
_repository.Update(Get(integrationId).Id, integration);
}
}
IEntity:
internal interface IEntity
{
int Id { get; }
}
Entity:
public abstract class Entity : IEntity
{
protected Entity(int id)
{
Id = id;
}
public int Id { get; private set; }
}
Integration:
[SharePointList("Integrations")]
public class Integration : Entity
{
public Integration(int id) : base(id)
{
}
public string ApiUrl { get; set; }
public bool DeletionAllowed { get; set; }
public Guid IntegrationId { get; set; }
public string Key { get; set; }
public string List { get; set; }
public bool OutgoingAllowed { get; set; }
public string RemoteWeb { get; set; }
public string Web { get; set; }
}
You have registered your IRepository wrong. With the line:
builder.RegisterType<SharePointRepository<IEntity>>().As<IRepository<IEntity>>();
You told Autofac that whenever somebody will request an IRepository<IEntity> give them a SharePointRepository<IEntity>, but you are requesting a concrete IRepository<Integration> so you get an exception.
What you need is the open generic registration feature of Autofac. So change your registration to:
builder.RegisterGeneric(typeof(SharePointRepository<>))
.As(typeof(IRepository<>));
It will work as you would expect you when you ask for a IRepository<Integration> it will give a SharePointRepository<Integration>.
You also have a second unrelated problem: your SharePointRepository has only an internal constructor.
Autofac by default only looks for public constructors so you either change your constructor and class to public or you need to tell to Autofac to look for NonPublic constructors with the FindConstructorsWith method:
builder
.RegisterType<SharePointRepository<IEntity>>()
.FindConstructorsWith(
new DefaultConstructorFinder(type =>
type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)))
.As<IRepository<IEntity>>();

ASP.NET Web Api System.Runtime.Serialization.SerializationException

I have a fully working MVC4 web site to which today I am trying to add a Web API though without success.
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'System.Data.Entity.Infrastructure.DbQuery`1[[LeasingWeb.Models.Car, LeasingWeb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' with data contract name 'ArrayOfCar:http://schemas.datacontract.org/2004/07/LeasingWeb.Models' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.SerializationException
</ExceptionType>
<StackTrace>
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteCarDBToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract ) at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.<>c__DisplayClass7.<WriteToStreamAsync>b__6() at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)
</StackTrace>
</InnerException>
</Error>
My objects are these:
public class Image
{
public int ID { get; set; }
[Required(ErrorMessage="Please select a car")]
[ForeignKey("Car")]
public int CarID { get; set; }
[DisplayName("Picture")]
[Required]
[FileExtensions(ErrorMessage = "Please specify a valid image file (.jpg, .jpeg, .gif or .png)", Extensions = ("jpg,png,jpeg"))]
public string Name { get; set; }
public virtual Car Car { get; set; }
}
public class Car
{
public int ID { get; set; }
[Required]
[DisplayName("Car Model")]
public string Name { get; set; }
[Required]
public string Company { get; set; }
[Required]
[DisplayName("Car Type")]
[ForeignKey("CarType")]
public int CarTypeID { get; set; }
[Required]
[Range(1,5)]
[DisplayName("Number Of Doors")]
public float NumDoors { get; set; }
[Required]
[Range(0, Int32.MaxValue)]
public float Acceleration { get; set; }
public virtual CarType CarType { get; set; }
}
public class CarType
{
[Key]
public int ID { get; set; }
[Required]
[DataType(DataType.Text)]
public string Type { get; set; }
}
And an object that holds them both:
public class CarDB
{
public IQueryable<Car> Cars { get; set; }
public IEnumerable<Image> Images { get; set; }
}
The API Controller:
public CarDB Get(int ID = -1)
{
CarDB car = new CarDB();
if (ID == -1)
{
car = new CarDB { Cars = db.Cars.Include(c => c.CarType), Images = db.Images };
}
else
{
car = new CarDB { Cars = db.Cars.Where(c => c.ID == ID).Include(c => c.CarType), Images = db.Images.Where(c => c.CarID == ID) };
}
return car;
}
Thanks to anyone that can help.
The issue here is the Cars member on the CarDB object. The DataContractSerializer special cases collection interfaces like IEnumerable and IList, but it doesn't special case derived interfaces like IQueryable. For these interfaces, they're treated as if the type were object and any implementations must be declared as known types.
You can try fixing this by changing the IQueryable<Car> member to IEnumerable<Car>.
I had this problem with legacy code using 30 tables with about 40 Foreign Keys with Lazy Loading. I found it easier, rather than adding more annotations to all the database classes, to just create a ViewModel with the fields that I wanted to be returned.
If the data being returned is complex, then I suggest using automapper.

IEnumerable and WCF - yet again

OK... I've looked on the web and found two possible solutions to my issue of not being able to return an IEnumerable type in a .Net 4.0 WCF service.
See below link. This is exactly what I'm getting when I am executing the WCF Test Client tool and trying to invoke a method.
https://connect.microsoft.com/wcf/feedback/details/336696/ienumerable-t-serialization-bug
Mind you, to be sure there is nothing wrong with my web service, I am able to return a type of this object for a single record, just not an IEnumerable.
Both solutions that I have tried, shown below do not work for me. I get the same error. This is driving me crazy. I know what the issue is, followed steps to circumvent the issue, but I am still getting the same error.
How can I resolve this?
This is the first solution I tried: Note that I even tried removing the "ToList" and "ToArray" on the last statement in each of the methods because it's implied already.
Interface
[OperationContract]
IList<Priority> GetPriorities();
Method
public IList<Priority> GetPriorities()
{
YeagerTechEntities DbContext = new YeagerTechEntities();
IList<Priority> priority = DbContext.Priorities.Where(p => p.PriorityID > 0).ToList();
CloseConnection(DbContext);
return priority.ToList();
}
This is the second solution I tried:
Interface
[OperationContract]
Priority[] GetPriorities();
Method
public Priority[] GetPriorities()
{
YeagerTechEntities DbContext = new YeagerTechEntities();
Priority[] priority = DbContext.Priorities.Where(p => p.PriorityID > 0).ToArray();
CloseConnection(DbContext);
return priority.ToArray();
}
Here it is with a List instead of an IList which still doesn't work.
Interface
[OperationContract]
List<Priority> GetPriorities();
Method
public List<Priority> GetPriorities()
{
YeagerTechEntities DbContext = new YeagerTechEntities();
List<Priority> priority = DbContext.Priorities.Where(p => p.PriorityID > 0).ToList();
CloseConnection(DbContext);
return priority.ToList();
}
Notice that the below method works fine when retrieving just one object instead of a list.
[OperationContract]
Priority GetPriorityID(Int16 priorityid);
public Priority GetPriorityID(Int16 priorityid)
{
YeagerTechEntities DbContext = new YeagerTechEntities();
Priority priority = null;
var priorityEntity = (from p in DbContext.Priorities
where p.PriorityID == priorityid
select p).FirstOrDefault();
if (priorityEntity != null)
{
priority = new Priority();
priority.PriorityID = priorityEntity.PriorityID;
priority.Description = priorityEntity.Description;
CloseConnection(DbContext);
}
else
{
CloseConnection(DbContext);
throw new Exception("Priority " + priorityid + " not found!");
}
return priority;
}
The entire error msg from the wcf test client for the first method in this post is as follows. What is the resolution in order to be able to return a list of objects?
Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy; the existing proxy is invalid. Refer to the stack trace for more detail. You can try to recover by starting a new proxy, restoring to default configuration, or refreshing the service.
An error occurred while receiving the HTTP response to http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableChannelBinder1.RequestClientReliableChannelBinder1.OnRequest(TRequestChannel channel, Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.ClientReliableChannelBinder1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.ClientReliableChannelBinder1.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at IYeagerTechWcfService.GetPriorities()
at YeagerTechWcfServiceClient.GetPriorities()
Inner Exception:
The underlying connection was closed: An unexpected error occurred on a receive.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
Inner Exception:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
Inner Exception:
An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
I modified my classes (see below), but am still getting the same exact error.
Surely, there must be someone who has tried this before where they get an object back from Entity Framework and want to pass it back as an IEnumerable. I'm very frustrated with this. Please help me out...
Based on my previous post, my classes are exactly the same with the following changes. I tried two methodologies.
Please refer to the first and second scenarios separately.
First scenario for Interface
I tried using just the Customer class and then an IEnumerable declaration of it.
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using YeagerTechModel;
namespace YeagerTechWcfService
{
//[ServiceKnownType(typeof(YeagerTechModel.Customer))]
[ServiceKnownType(typeof(IEnumerable<YeagerTechModel.Customer>))]
[ServiceContract]
public interface IYeagerTechWcfService
{
[OperationContract]
IEnumerable<Customer> GetCustomers();
[OperationContract]
Customer GetCustomerID(Int16 customerid);
It resides in my YeagerTechModel project in the same solution referenced by my web service (the other project in the same solution).
First scenario for Customer object
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace YeagerTechModel
{
[Serializable]
[DataContract]
public partial class Customer
{
public Customer()
{
this.Projects = new HashSet<Project>();
}
[DataMember]
public short CustomerID { get; set; }
[Required]
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public string Email { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Company { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string FirstName { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string LastName { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Address1 { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Address2 { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string City { get; set; }
[StringLength(2)]
[DataType(DataType.Text)]
[DataMember]
public string State { get; set; }
[StringLength(10)]
[DataType(DataType.Text)]
[RegularExpression(#"^\d{5}(-\d{4})?$")]
[DataMember]
public string Zip { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
public string HomePhone { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[DataMember]
public string CellPhone { get; set; }
[StringLength(100)]
[DataType(DataType.Url)]
[DataMember]
public string Website { get; set; }
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public string IMAddress { get; set; }
[DataMember]
public System.DateTime CreatedDate { get; set; }
[DataMember]
public Nullable<System.DateTime> UpdatedDate { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
Second scenario for interface:
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using YeagerTechModel;
namespace YeagerTechWcfService
{
[ServiceContract]
public interface IYeagerTechWcfService
{
[OperationContract]
IEnumerable<Customer> GetCustomers();
[OperationContract]
Customer GetCustomerID(Int16 customerid);
Second scenario for Customer object
I have tried using just the Customer class and then an IEnumerable declaration of it at the bottom of this class.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace YeagerTechModel
{
[KnownTypeAttribute("KnownTypes")]
[Serializable]
[DataContract]
public partial class Customer
{
public Customer()
{
this.Projects = new HashSet<Project>();
}
[DataMember]
public short CustomerID { get; set; }
[Required]
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public string Email { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Company { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string FirstName { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string LastName { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Address1 { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Address2 { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string City { get; set; }
[StringLength(2)]
[DataType(DataType.Text)]
[DataMember]
public string State { get; set; }
[StringLength(10)]
[DataType(DataType.Text)]
[RegularExpression(#"^\d{5}(-\d{4})?$")]
[DataMember]
public string Zip { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
public string HomePhone { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[DataMember]
public string CellPhone { get; set; }
[StringLength(100)]
[DataType(DataType.Url)]
[DataMember]
public string Website { get; set; }
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public string IMAddress { get; set; }
[DataMember]
public System.DateTime CreatedDate { get; set; }
[DataMember]
public Nullable<System.DateTime> UpdatedDate { get; set; }
public virtual ICollection<Project> Projects { get; set; }
static Type[] KnownTypes()
{
return new Type[] { typeof(IEnumerable<Customer>) };
}
}
I tried:
return customer;
return customer.ToList();
return customer.ToArray();
public IEnumerable<Customer> GetCustomers()
{
YeagerTechEntities DbContext = new YeagerTechEntities();
IEnumerable<Customer> customer = DbContext.Customers.Where(p => p.CustomerID > 0);
CloseConnection(DbContext);
return customer;
}
The problem seems to be a serialization issue when trying to pass back the Customer object which is part of an Entity Framework model. There has to be a documented way of passing back an object of this type which is derived from an Entity Framework model.
Where is it????
Here is the latest of what I tried and am still getting the same exact error....
namespace YeagerTechWcfService
{
[ServiceContract]
public interface IYeagerTechWcfService
{
[OperationContract]
List<Customer> GetCustomers();
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace YeagerTechModel
{
[Serializable]
[DataContract]
public partial class Customer
{
public Customer()
{
this.Projects = new HashSet<Project>();
}
[DataMember]
public short CustomerID { get; set; }
[Required]
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public string Email { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Company { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string FirstName { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string LastName { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Address1 { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Address2 { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string City { get; set; }
[StringLength(2)]
[DataType(DataType.Text)]
[DataMember]
public string State { get; set; }
[StringLength(10)]
[DataType(DataType.Text)]
[RegularExpression(#"^\d{5}(-\d{4})?$")]
[DataMember]
public string Zip { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
public string HomePhone { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[DataMember]
public string CellPhone { get; set; }
[StringLength(100)]
[DataType(DataType.Url)]
[DataMember]
public string Website { get; set; }
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public string IMAddress { get; set; }
[DataMember]
public System.DateTime CreatedDate { get; set; }
[DataMember]
public Nullable<System.DateTime> UpdatedDate { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
public List<Customer> GetCustomers()
{
YeagerTechEntities DbContext = new YeagerTechEntities();
List<Customer> customer = DbContext.Customers.Where(p => p.CustomerID > 0).ToList();
return customer.ToList();
}
The answer was as simple as setting a property to false before making my EF call to the database.
DbContext.Configuration.ProxyCreationEnabled = false;
EF automatically generates a proxy class. Dynamic Proxies – They don’t play nice over the wire – Turn these off (ContextOptions.ProxyCreationEnabled == false).

wcf Service Known type attribute question

i wanna add a service behavior(or anything u'll suggest) that will automatically insert the types from dll to the service known types of the service
is it possible? how?
Known type attributes are passed to the DataContractSerializer constructor. You can customize the way this serializer is instantiated and provide the known types to the constructor of the serializer by reflecting over your assemblies and finding all types that derive from a base class.
Here's a sample code (not tested):
[ServiceContract]
public interface FooContract
{
[OperationContract]
[KnownTypesDataContractFormat(typeof(SomeBaseType))]
void MyOperation(SomeBaseType arg);
}
public class KnownTypesDataContractFormatAttribute : Attribute, IOperationBehavior
{
public Type BaseType { get; private set; }
public KnownTypesDataContractFormatAttribute(Type baseType)
{
BaseType = baseType;
}
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
{ }
public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
{
IOperationBehavior innerBehavior = new KnownTypesDataContractSerializerOperationBehavior(description, BaseType);
innerBehavior.ApplyClientBehavior(description, proxy);
}
public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
{
IOperationBehavior innerBehavior = new KnownTypesDataContractSerializerOperationBehavior(description, BaseType);
innerBehavior.ApplyDispatchBehavior(description, dispatch);
}
public void Validate(OperationDescription description)
{ }
}
public class KnownTypesDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
{
public Type BaseType { get; private set; }
public KnownTypesDataContractSerializerOperationBehavior(OperationDescription operationDescription, Type baseType) : base(operationDescription)
{
BaseType = baseType;
}
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
return new DataContractSerializer(type, name, ns, knownTypes);
}
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
{
return new DataContractSerializer(type, name, ns, knownTypes);
}
private IEnumerable<Type> GetKnownTypes()
{
// Try to find all types that derive from BaseType in the
// executing assembly and add them to the knownTypes collection
return
from type in Assembly.GetExecutingAssembly().GetTypes()
where type != BaseType && BaseType.IsAssignableFrom(type)
select type;
}
}