I'm developing an application with XPO/XAF and I need to manage photos together with some additional information.
This is the simplified (pseudo) code I use for my Photo entity:
public class Photo
{
public Photo()
{
CreationDate = DateTime.UtcNow;
}
private Image imageData;
public Image Data
{
get { return imageData; }
set
{
imageData = value;
// Current Impl: Use static code to create thumbnail
Thumbnail = ImageService.CreateThumbnail(value);
}
}
public Image Thumbnail { get; private set; }
public Guid Id { get; }
public DateTime CreationDate { get; private set; }
public string Description { get; set; }
}
The Photo entity is used in various other entities, e.g.
public class Inspection
{
public Photo Photo { get; set; }
}
public class User
{
public Photo Photo { get; set; }
}
Whenever the Data of the Photo is changed, the thumbnail should also be updated. My posted solution works, but it's quite ugly, isn't it?
And it is also not possible to implement a new requirement: It should be possible to specify (application-wide) the quality of the thumbnails based on the usage (e.g. higher quality for Inspection thumbnails, lower quality for User thumbnails).
In XAF I would implement this requirement with a ViewControllerViewController, reacting to changes of a Photo (taking the current 'owning view' into account). But this solution has some drawbacks:
1) Thumbnail property setter cannot be any longer private.
2) It's quite hard to (unit-)test, because additional code is required to setup the ViewController infrastructure.
3) A ViewController is only active if there is a view. But it's also possible to edit photos from a custom OData-Service. Of course I can/should move ImageProcessing code from the ViewController to an utility class/method, but I have to remember to call this code when using my OData Controllers.
4) When viewing/editing Photos from a generic listview, the ViewController does not know which quality setting to use (because right now, there is only a generic Photo class and no back-reference to the 'owner' exists). Of course it's possible to inherit various Photo classes (UserPhoto/InspectionPhoto/...), but does this make sense?
I think generating and persisting thumbnails is quite a common task, therefore I'm really interested your ideas. I also like concepts/ideas of DDD/rich-domain model, therefore I would like to know whether it's possible to adopt such concepts to my situation
You are asking some rather subjective questions about design and there is no 'correct' answer but here are some thoughts.
Is the Thumbnail property necessary in the business object since it's only used during the view? Pulling the logic into a ViewController makes sense.
It is quite easy to unit test XAF Controllers and there are several examples in the DevExpress support centre and the documentation (S32594, How to test an action). Also the eXpand framework has some good example code for setting up XAF framework tests.
Another option would be to implement a custom editor for the thumbnail. You can even add it to the layout dynamically without a persistent property in the business object. There's a lot of options on this page about implementing custom ViewItems.
Yet another approach would be to modifying the layout at runtime to add a non-persistent thumbnail. There is an example in the documentation here which adds an non-persistent image control to a detail view.
You might also be interested in this support centre issue Q512788.
New to MVC. I did the tutorial # [http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/build-a-single-page-application-(spa)-with-aspnet-web-api-and-angularjs] and from this you produce a question and answer website. If I wanted to maintain progress i.e. keep a count of the number of questions correctly answered, do I need to calculate this value from retrieving the db.TriviaAnswers object or do I need to add a Count property to the TriviaAnswer class or do I need a separate variable then how do I maintain state between requests? Like ViewBag is not available in the
public async Task<IHttpActionResult> Post(TriviaAnswer answer){...}
method.
OPTION 1 as suggested below:
namespace GeekQuiz.Models
{
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
public class TriviaResults
{
[Required, Key, Column(Order=1)]
public string UserId { get; set; }
[Required, Key, Column(Order=0)]
public virtual int QuestionId { get; set; }
}
}
This code throws an InvalidOperationException in the method:
private async Task<TriviaQuestion> NextQuestionAsync(string userId)
on the first line of code.
lastQuestionId = ...
I went over this tutorial a few months ago.
option 1: If you want to track progress I assume you mean progress per user, then I would advice you to add a table to the db which states saves the users ids and the ids of questions which were correctly answered - that's in case you want to save this as a persistent data and per user.
option 2: If you want the same thing, save the data per user but only for this session, you can save the data in the session variable as a dictionary<userid, list<questionid>>.
One thing you should notice is that those question repeat in an endless loop, so you might want to change that.
In both options when you need to know the count u can just go to the table or dictionary and get the number of correct answers.
I hope that answers your question.
To use the session var:
Session["name"] = value;
Session.Remove("name");
I hope someone can help me with this.
I am using VS 2012 and MVC4.
I am testing a project using Strongly Typed Model using HttpPostedFileBase. When I try to Scaffold the Views it fails with:
---------------------------
Microsoft Visual Studio
---------------------------
Unable to retrieve metadata for 'ImageTest.Models.ImageHandler'. Value cannot be null.
Parameter name: key
---------------------------
OK
---------------------------
I have tried to Un-Install and then Re-Install MVC as was suggested in a few posts on the net but this has not helped. This is my Model: (Yes I have tried [Key] on the Id but makes no difference)
using System;
using System.Web;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ImageTest.Models
{
public class ImageHandler
{
public int Id { get; set; }
public string ImageName { get; set; }
public HttpPostedFileBase File { get; set; }
}
}
I thought it may be a Context issue but it does not matter if I create a custom Context or use a predefined one I get the same error. This is the pre-defined Context:
using ImageTest.Models;
using System.Data.Entity;
public class ImageHandlerContext : DbContext
{
public ImageHandlerContext() : base("DefaultConnection")
{
}
public DbSet<ImageHandler> ImageHandler { get; set; }
}
As a Test, if I comment out:
// public HttpPostedFileBase File { get; set; }
I can scaffold the View with no problem. Is this a bug? I can not see in the documentation anywhere that Scaffolding HttpPostedFileBase is not supported. See: HttpPostedFileBase
Thanks in advance.
Stan is on the right track.
Model-View-Controller or MVC uses the Entity Framework to Scaffold Views.
Entity Data Model: Primitive Data Types
Primitive Data Types are currently supported in .NET 4.5 unless a Complex Data Type is defined. The following are the supported Primitive Data Types:
Binary
Boolean
Byte
DateTime
DateTimeOffset
Decimal
Double
Float
Guid
Int16
Int32
Int64
SByte
String
Time
See: Complex Type for more Information on extending this functionality.
Thanks Stan Thumbs up from me.
EDIT: One needs to Scaffold the View with Primitive Data Types first and then add HttpPostedFileBase to the Model later to use the File Upload Capabilities. As an example see: Upload Image in form and show it on MVC 4
Also you will need to use (NotMapped) in your Model:
[NotMapped]
public HttpPostedFileBase File { get; set; }
Now in the Scaffolded Create ActionResult Method, your View's Form Return Valus contains a System.Web.HttpPostedFileWrapper that you can use.
So Short Answer:
1: Create your Code First Model with Primitive Data Types only! Unless you use the [NotMapped] Attribute.
2: Scaffold your View's.
3: If not done so in step 1, Add to your Model the Methods needed. E.G: public HttpPostedFileBase File { get; set; } using the [NotMapped] Attribute
4: Add to your Database the necessary Table either manually or from the Console.
5: Add the necessary code to your View's and Controller.
That should be enough to get you working...
I don't think you will be able to HttpPostedFileBase as a property of your model, well at least not have it mapped via EntityFramework and automatically scaffolded. If you think about it - what database fields do you think this property type would map to?
If you want to actually store the binary data in your database, use this
public byte[] File { get; set; }
as your property.
I have an MVC web app where users upload a text file and I parse it out.
The requirement just changed and they will be uploading multiple files of the same kind now. I parse a single file by sending a file-path to the method below, ReadParts which opens a stream and calls the method parseReplicateBlock to retrieve desired fields. For multiple files I could read all the files into one big stream but I am afraid it could exceed the buffer limit etc.
So I am thinking to parse file by file and populate results into an object. My requirement then, is to sort the records based on a date field.
I just need some help in how to write this method ReadLogFile in a better way, espceially for sorting based on initialtionDate and initiationTime. I want to find the minimum record based on initiationDate and Time and then do some other logic.
The problem is if I sort the list member within the object, I would loose positiong of the other records.
You appear to be storing each field of the record in a separate collection within LogFile. This seems a very strange way to store your data.
If you sort one of these collections, then of course it will bear no relationship to the other fields any longer since they are unrelated. There are huge areas for bugs too if you are relying on all the collections tallying up (eg if a field is missing from one of the parsed records)
Instead you should be have a class that represents a SINGLE record, and then Logfile has a SINGLE collection of these records. eg:
public class ReplicateBlock
{
public string ReplicateId { get; set; }
public string AssayNumber { get; set; }
public DateTime InitiationDate { get; set; }
//etc
}
public class LogFile
{
public List<ReplicateBlock> ReplicateBlocks = new List<ReplicateBlock>();
}
I have to say that your code is very difficult to follow. The fact that all your functions are static makes me think that you're not particularly familiar with object oriented programming. I would suggest getting a good book on the subject.
I've built an open source application, and I'd be curious to know how others are handling customer-specific requests. It's important to me to keep the app simple; I'm not trying to make it all things for all people. Apps can get bloated, complex, and just about unusable that way. However, there are some customer-specific options that would be nice (it just wouldn't apply to all customers). For example...
Say we have a domain entity called Server. In the UI, we let a customer pick from a list of servers. For one company, it's helpful to filter the servers by location (US, Germany, France, etc...). It would be easy enough to add a server property like this:
public class Server
{
public Location Location { get; set; }
// other properties here
}
My concern is that Server could become bloated with properties over time. And even if I only add location, not all customers would care about that property.
One option is to allow for user-defined fields:
public class Server
{
public string UserField1 { get; set; }
public string UserField2 { get; set; }
public string UserField3 { get; set; }
// etc...
// other properties here
}
Is that the best way to handle this? I don't like the fact that type safety is gone by making everything a string. Are there other/better ways that people are handling issues like this? Is there even a design pattern for something like this?
In my opinion, a good design pattern for something like this is to use schemas at the database level and then basic inheritance at the class level.
CREATE TABLE dbo.A (
ColumnA INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
ColumnB VARCHAR(50),
ColumnC INT,
etc.
)
And now we have a client who needs some specific functionality, so let's create an extension to this table in a different schema:
CREATE TABLE CustomerA.A (
ColumnA INT NOT NULL PRIMARY KEY,
Location VARCHAR(50)
)
But now we have another client who needs to extend it differently:
CREATE TABLE CustomerB.B (
ColumnA INT NOT NULL PRIMARY KEY,
DataCenterID INT
)
Though the fields may not be relevant, you get the idea, and so now we need to build the customer specific domain models here:
public abstract class A
{
public int ColumnA { get; set; }
public string ColumnB { get; set; }
public int ColumnC { get; set; }
}
public class CustomerA_A : A
{
public string Location { get; set; }
}
public class CustomerB_A : A
{
public int DataCenterID { get; set; }
}
And so now when we need to build something for Customer A, we'll build their subclass, and for Customer B theirs, and so on.
Now, FYI, this is the beginnings of a very dynamic system. I say that because the piece that's missing, that's not yet dynamic, is the user-interface. There is a significant number of ways that can be accomplished, but way outside the scope of this question. That is something you'll have to consider. I say that because the way you manage the interface will determine how you even know to build which subclass.
I hope this has helped.
The usual approach early on is to use the config XML files for this sort of thing. But programming for client-specific needs requires a whole mindset around how you program. Refer to this answer to a similar question.
Of course it always depends on how much customization you want to allow. In our product we went as far as enabling users to completely defined their own entities with properties and relations among them. Basically, every EntityObject, as we call our entities, in the end consists of a value collection and a reference to a meta-model describing the values within them. We designed our own query language that allows us to query the database and use expressions that are translate-able to any target language (although we currently only do SQL and .net).
The game does not end there and you quickly find that things like validation rules, permissions, default values and so on become a must have. Of course all of this then requires UI support, at least for the execution of the meta-model.
So it really depends on the amount of adjustment a end-user should be able to perform. I'd guess that in most cases simple user fields, as you described, will be sufficient. In that case I would provide a single field and store JSON text within that. In the UI you can then provide at least a semi-decent UI allowing structure and extensibility.
Option 1: Say "no". :-)
And while I say that (half) jokingly, there is some truth to it. Too often, developers open themselves up to endless customization by allowing one or two custom features, setting the snowball in motion.
Of course, this has to be balanced, and it sounds like you may be doing this to an extent. But if you truly want to keep your app simple, then keep it simple and avoid adding customizations like this.
Option 2: Inheritance.
If you really need to add the customization, I would lean the way of building a base class with all "standard" options, and then building customer-specific classes containing customer-specific optimizations.
For example:
public class Server
{
// all standard properties here
}
Then for Joe's Pizza, you can have:
public class JoesPizzaServer : Server
{
public Location Location { get; set; }
}
The side-benefit to this is that it will allow you to base your presentation views off of the client-specific (or base) models.
For example, in MVC you could set up your view models like this, and then you could have specific views for each customer.
For example, Bob's Burgers would have its own view on the base model:
#model MyApp.Server
#* implement the base form *#
And Joe's Pizza's view would use the custom model:
#model MyApp.JoesPizza
#* implement the base form -- a partial view -- with addtional custom fields
MVC does a really good job of supporting this type of pattern. If you're not using MVC (maybe WPF or Web Forms), there are still ways to leverage partial "view" files for accomplishing something similar.
Of course, your database can (and probably should) support a similar inheritance model. Entity Framework even supports various inheritance models like this.
I may be wrong here, but it looks like you want to handle different versions of your software with the same code base. I can think of two approaches for this:
Actually define different versions for it and handle changes for each client. This won't give you problems from the domain-modeling point of view, but will require a supporting infrastructure, which will have to scale according to your client requirements. There are some related questions out there (e.g. this, this and this).
Handle this at the domain-model level, as a user-defined configuration. The advantage of this approach is that you don't have to incorporate multiple versions of your software, but this comes at the expense of making your model more generic and potentially more complex. Also your tests will surely have to be adapted to handle different scenarios. If you are going in that direction I would model an object representing the attribute (with a name and a value) and consider the Server class as having a collection of attributes. In that way your model still captures your requirements in an OO style.
HTH
I approach from Python that I think would work rather well hear is a dictionary. The key is your field name, the value is the, errrrr... value ;)
It'd be simple enough to represent in a database too.