How to filter breeze.webapi returned entities from the server - entity-framework-6

I have a standard breeze web-server which exposes the Project
[HttpGet]
public IQueryable<Project> Projects()
{
return _db.Context.Projects;
}
How can i prevent a Project with NoLongerExist=true from begin included in queries returned to the JavaScript client from here affecting the functionality of the breezejs client?.. um i would also like to hide this property also, people wont like to see that their projects are not actually deleted!

you can try this on your breeze controller...
public IQueryable<Project> Projects()
{
return _db.Context.Projects.Where(o => o.NoLongerExist == true);
}
prevent json serialization of the NoLongerExist property using data annotations on your model by doing this, i'm assuming you are using EF6 with JSON.NET on your backend...
[Table("Project")]
public partial class Project
{
public Project()
{
}
public int id { get; set; }
[JsonIgnore]
public bool NoLongerExist { get; set; }
}

Related

.NET Core Web API with Swagger: Post both a file AND data on the same call

I've created a .NET Core 3.1 Web API and I use swagger for the documentation/preview of it. I want to both upload a file and send a long some data to a post call. I can make 1 call to upload data and that works. I can make another call to send object data and that works. But trying to combine the 2 together (by using swagger interface to fill out the data) never hits the method and gives me the error: Unsupported Media Type.
[HttpPost]
[Route("Send")]
public void Send(IFormFile file, Email emailInfo)
{
}
[HttpPost]
[Route("Test")]
public void Test(IFormFile file)
{
}
public class Email
{
public List<string> To { get; set; }
public string Body { get; set; }
public string Subject { get; set; }
public IFormFile Files { get; set; }
}
One thing you may notice is on the Send I have IFromFile as a parameter but IFromFile in Email obejct as well. For some reason in order for Swagger to show the file select button in the parameters it needed to be in both places.
Try using [From Query] binding:
[HttpPost]
[Route("Send")]
public void Send([FromQuery] Email emailInfo)
{
var emailFromParam = emailInfo;
}
Input:
Debug output showing param values:

EF Core + MVC 6 + .NET Core RC2 - EF not returning results

Entity Framework Core is not returning any results. I've been searching near and far. I find some tutorials saying one thing and others saying another. Here is what I have so far:
Buyer.cs
[Table("DealerCustomer", Schema = "dbo")]
public class Buyer
{
[Key]
public int DealerCustomerKey { get; set; }
public int DealerId { get; set; }
}
BuyerContext.cs
public class BuyerContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer("db connection string here");
}
public DbSet<Buyer> Buyers { get; set; }
}
Startup.cs > ConfigureServices function
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddDbContext<BuyerContext>(options =>
options.UseSqlServer("db connection string here");
services.AddMvc();
}
Now I am trying to load the Buyers data from my BuyerController.cs:
[Route("api/[controller]")]
public class BuyersController : Controller
{
private BuyerContext _context;
public BuyersController(BuyerContext context)
{
_context = context;
}
[HttpGet]
public IEnumerable<Buyer> Get()
{
System.Diagnostics.Debug.WriteLine("getting buyers");
System.Diagnostics.Debug.WriteLine(_context.Buyers);
return _context.Buyers;
}
}
This is all returning empty brackets when I load the page, instead of a list of Buyers. However there are over 1000 rows in that table (dbo.DealerCustomer). I know I have two places adding the db connection string but tutorials kept show both ways of doing it and when I only did it in startup.cs I was getting errors about the _context. I can make everything look pretty later, right now I just want a good connection so I have a starting place to work from.
I found there was a timeout because one of the decimal fields was returning null.
EF Core Timing out on null response

How to use a custom class in Odata v4 instead of class from designer.cs

C# Web.Api Odata APplication
I’m implementing Odata V4 for the first time and would like to use my own custom class instead of the data class from the designer.
Here is what I did:
I created a Data project in Visual Studios and added my SQL Linq data table “Video”
I created the data context as follows:
public class VideoDataContext : DbContext
{
public VideoDataContext(): base("name=VideoData")
{
DbSet<VideoEf> Videos { get; set; }
}
And my custom class as follows:
[Serializable]
[DataContract]
public class VideoEf : Repository
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Isrc { get; set; }
}
And model builder:
public Microsoft.OData.Edm.IEdmModel GetEdmModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
EntityTypeConfiguration<VideoEf> titleType = builder.EntityType<VideoEf>();
builder.EntitySet<VideoEf>("Video");
return builder.GetEdmModel();
}
And in my video controller:
public class VideoController : ODataController
{
VideoDataContext db = new VideoDataContext ();
[EnableQuery(PageSize = 20, MaxExpansionDepth = 5)]
public IHttpActionResult Get()
{
return Ok(db.Videos.AsQueryable());
}
When I make the call to get the video entities I keep getting a ” 406 Not Acceptable” error message
How can I ensure that the data returned from the database is mapped to my custom model ?
Is my model builder correct?
what could be causing the above error?
You don't need to return IQueryable because you have EnableQuery attribute, just return DbSet.
You also don't need any wcf attribute and EntityTypeConfiguration<VideoEf> titleType = builder.EntityType<VideoEf>();
Then it should just work.
Hope it helps.
Edit
My mistake for IQueryable, I also use it.

Self referencing loop detected when serializing Data models in MVC5 / EF6

I am getting this error "Self referencing loop detected" while serializing using 'Json.NET'
I have a Book model
public class Book
{
public Book()
{
BookPersonMap = new List<BookPersonMap>();
}
public int BookId { get; set; }
public virtual ICollection<BookPersonMap> BookPersonMap { get; private set; }
(And many other virtual Icollections)
}
And this is the BookPerson Mapping class:
public class BookPersonMap
{
public int BookId { get; set; }
public string PersonName { get; set; }
public int PersonTypeId { get; set; }
public virtual Book Book { get; set; } // Foreign keys
public virtual PersonType PersonType { get; set; }
}
When I try to Serialize the Book object it throws:
"Self referencing loop detected for property 'Book' with type 'System.Data.Entity.DynamicProxies.Book_57F0FA206568374DD5A4CFF53C3B41CFDDC52DBBBA18007A896 08A96E7A783F8'. Path 'BookPersonMap[0]'."
I have tried the things suggested in some of the similar posts
Example:
PreserveReferencesHandling = PreserveReferencesHandling.Objects in Serializer settings returned a string with length 3 million!
ReferenceLoopHandling = ReferenceLoopHandling.Ignore in Serializer settings :
"An exception of type 'System.OutOfMemoryException' occurred in Newtonsoft.Json.dll but was not handled in user code"
^ Same luck with "ReferenceLoopHandling.Serialize"
MaxDepth = 1 : Infinite loop again.
Putting [JsonIgnore] on the virtual properties is working but it is a tedious task (because of numerous FK references) and not efficent, since if I miss one property and it will throw exception.
What is missing from above Json settings for them be not working?
services.AddMvc().AddJsonOptions(opt => {
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
I have found the best way to solve this type of error is to flatten your model using a view model.
Put a break point on your object before it is serialized and start drilling into the child properties. You will probably find that you can go on indefinitely.
This is what the serializer is choking on.
Create a Constructor for your controller and put on it this line of code :
db.Configuration.ProxyCreationEnabled = false;
//db is the instance of the context.
For asp.net mvc 5 use this
Add the code below to your Application_Start method inside globax.asax file or startup file.
protected void Application_Start()
{
..
GlobalConfiguration.Configuration.Formatters.JsonFormatter
.SerializerSettings
.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
}
Disable lazy loading and
ensure your controller does not return
Json(..obj)
rather it should return
Ok(..obj)

ASP.NET Web-API not serializing readonly property

I migrated an API method from a standard MVC action to the new asp.net Web-API beta and suddenly a read only property is no longer serialized (both returning JSON). Is this expected behaviour?
Edit: Added code sample
I have both Newtonsoft.Json 4.0.8 and System.Json 4.0 referenced through nuget packages
public IQueryable<Car> Gets()
{
return _carRepository.GetCars();
}
public class Car
{
public IEnumerable<Photo> Photos
{
get { return _photos; }
}
public string PreviewImageUrl // No longer serialized
{
get
{
var mainImage = Photos.FirstOrDefault(o => o.IsMainPreview) Photos.FirstOrDefault();
return mainImage != null ? mainImage.Url : (string.Empty);
}
}
}
}
The JsonMediaTypeFormatter that ships with the Beta uses a serializer that does not support read-only properties (since they would not round-trip correctly). We are planning on addressing this for the next realese.
In the mean-time you could use a custom JSON MediaTypeFormatter implementation that uses Json.NET (there's one available here) instead of the built-in formatter.
Update: Also check out Henrik's blog about hooking up a JSON.NET formatter: http://blogs.msdn.com/b/henrikn/archive/2012/02/18/using-json-net-with-asp-net-web-api.aspx
I don't know if this is an expected behavior or not. I would say that this is expected for input parameters (because you cannot set their values) but not for output parameters. So I would say this is a bug for an output parameter. And here's an example illustrating the issue:
Model:
public class Product
{
public Product()
{
Prop1 = "prop1 value";
Prop2 = "prop2 value";
Prop3 = "prop3 value";
}
public string Prop1 { get; set; }
[ReadOnly(true)]
public string Prop2 { get; set; }
public string Prop3 { get; protected set; }
}
Controller:
public class ProductsController : ApiController
{
public Product Get(int id)
{
return new Product();
}
}
Request:
api/products/5
Result:
{"Prop1":"prop1 value","Prop2":"prop2 value"}
So if the property doesn't have a public setter it is not serialized which doesn't seem normal as the Product class is used as output in this case.
I would suggest opening a connect ticket so that Microsoft can fix this before the release or at least tell that this is by design.

Resources