Without using "UIHint" how to create .cshtml for certain types of data.
Examples
These are already working!
[DataType(DataType.Url)]
public string Link { get; set; }
will be used
Url.cshtml
[DataType(DataType.MultilineText)]
public string Descrition { get; set; }
will be used
MultilineText.cshtml
These, I am in doubt about how
public IEnumerable<SelectListItem> TypesList { get; set; }
will be used
???????????.cshtml
public DateTime? DateUpdated { get; set; }
will be used
???????????.cshtml
public int? Order { get; set; }
will be used
???????????.cshtml
Questions
In short, do not want to be putting in my ViewModel attributes, like that would work exactly like "Url" and "Multiline"
What should be the file name .cshtml that will be used to int?, IEnumerable<xx> or IEnumerable<string>
Remembering that you can not create files with "<", ">" or "?"
By convention (if you don't specify any template name):
public IEnumerable<SelectListItem> TypesList { get; set; } will use SelectListItem.cshtml (not that since you have an IEnumerable<T> the editor template will be rendered for each element of the collection and will be called T.cshtml)
public DateTime? DateUpdated { get; set; } will use DateTime.cshtml
public int? Order { get; set; } will use Int32.cshtml
...
You could also specify a template name in the view:
#Html.EditorFor(x => x.TypesList, "MyTemplate.cshtml")
Assuming TypesList is an IEnumerable<T> then MyTemplate.cshtml will be strongly typed to IEnumerable<T> and not to T.
Related
I am working with the Podio api in C# and "Groupings" is missing from the View and ViewCreateUpdateRequest model.
When I use the sandbox call the result includes the groupings. So I'm thinking it is missing in the C# nuget package. Is there another way to access groupings for both Get View and Update View?
Sadly they are not maintaining the SDK for C#, but you can download their code from https://github.com/podio/podio-dotnet and update the code yourself.
That's what I did, I change the following
ItemId data type from Integer to Long
Added Groupings in View (Below is my View looks like)
public class View
{
[JsonProperty("view_id")]
public string ViewId { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("created_on")]
public DateTime CreatedOn { get; set; }
[JsonProperty("sort_by")]
public string SortBy { get; set; }
[JsonProperty("sort_desc")]
public string SortDesc { get; set; }
[JsonProperty("filters")]
public JArray Filters { get; set; }
[JsonProperty("fields")]
public JObject Fields { get; set; }
[JsonProperty("groupings")]
public JObject Groupings { get; set; }
[JsonProperty("created_by")]
public ByLine CreatedBy { get; set; }
[JsonProperty("layout")]
public string Layout { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("rights")]
public string[] Rights { get; set; }
[JsonProperty("filter_id")]
public string FilterId { get; set; }
[JsonProperty("items")]
public int Items { get; set; }
}
Search for NuGet Package: Podio.Async by acl2
I am an avid user of PetaPoco. Is there any way to tweak the Database.tt (for generation of POCO's) to specify a ResultColumn in a specific table?
TIA
Currently, the Database.tt states:
// Tweak Schema
tables["tablename"].Ignore = true; // To ignore a table
tables["tablename"].ClassName = "newname"; // To change the class name of a table
tables["tablename"]["columnname"].Ignore = true; // To ignore a column
tables["tablename"]["columnname"].PropertyName="newname"; // To change the property name of a column
tables["tablename"]["columnname"].PropertyType="bool"; // To change the property type of a column
I do not know how to change the template, other then these instructions (which work very well). I was hoping for a similar statement that could produce a POCO like:
[TableName("phoenix.view_medical_records")]
[ExplicitColumns]
public partial class view_medical_records
{
[Column] public string lastname { get; set; }
[Column] public string firstname { get; set; }
[Column] public string birthdate { get; set; }
[Column] public int? chart_number { get; set; }
[ResultColumn] public DateTime tservice { get; set; }
[Column] public string status { get; set; }
[ResultColumn] public DateTime tcompleted { get; set; }
[Column] public string procedure_description { get; set; }
[Column] public string description { get; set; }
[Column] public string provider { get; set; }
}
Note: the [ResultColumn] attribute being automatically supplied?!
Thanks.
As per my comment on the question, PetaPoco doesn't support result columns via the T4 generator files. However, a workaround would be to ignore the columns
tables["phoenix.view_medical_records"]["tservice"].Ignore = true;
tables["phoenix.view_medical_records"]["tcompleted"].Ignore = true;
And, supply partial classes for the generated one which supply the columns.
public partial Poco1
{
// Generated by PP
}
public partial Poco1
{
// Supplied by the developer (Must be in same namespace)
[ResultColumn] public DateTime tservice { get; set; }
[ResultColumn] public DateTime tcompleted { get; set; }
}
I have a project where I have a set of forms:
public class Form
{
public string Id { get; set; }
public string Name { get; set; }
public IList<string> FieldValueIds { get; set; }
public string UserId { get; set; } // the user who completed the form.
public string FormTemplateId { get; set; }
}
Which each "implement" a form template selected at creation of the form.
public class FormTemplate
{
public string Id { get; set; }
public string Name { get; set; }
public IList<string> FieldIds { get; set; }
}
Which defines which fields are present within the form. Each field
public class FormField
{
public string Id { get; set; }
public string Name { get; set; }
public string Caption { get; set; }
public ValueType DataType { get; set; } // Enum specifying the type of data this field accepts.
}
Stores information about the field such as a description and what type it is expecting. Each FormField can be present in multiple FormTemplates with the values for the form being stored as FieldValue objects related to the Form itself.
public class FieldValue
{
public string Id { get; set; }
public string FieldId { get; set; }
public string ValueAsJsonString { get; set; }
}
Other objects include the User Object:
public class User
{
public string Id { get; set; }
public string Username { get; set; }
public string GivenNames { get; set; }
public string Surname { get; set; }
}
I would like to be able to perform a query to find all Forms completed by a user with a specified name, or all Forms where a field with name X has value Y and so forth.
I have looked into usage of indexes as specified in the documentation Indexing related documents, however the implementation as presented in the documentation threw a NotSupportedException when I implemented the example as follows:
class FormTemplates_ByFieldAndName : AbstractIndexCreationTask<FormTemplate>
{
public class Result
{
public string Name { get; set; }
public IList<string> FieldNames { get; set; }
}
public FormTemplates_ByFieldAndName()
{
Map = FormTemplates => from FormTemplate in FormTemplates
select new
{
Name = FormTemplate.Name,
FieldNames = FormTemplate.FieldIds.Select(x => LoadDocument<FormField>(x).Name)
};
}
}
// in code:
IList<FormTemplate> TestResults = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>()
.Where(x => x.Name == "TemplateName" || x.FieldNames.Contains("FieldName"))
.OfType<FormTemplate>()
.ToList();
As best as I can tell this was implemented correctly, however I have seen a suggestion to replace the .Contains with a .Any implementation instead. In lieu of this I have been experimenting with a different approach by applying successive .Where arguments. Like so:
var pre = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>();
var pr2 = pre.Where(x => x.Name == "TypeTest25");
List<FormTemplate> TestResults = pr2
.Where(x => x.FieldNames.Any(a => a == "field25"))
.OfType<FormTemplate>()
.OrderByScoreDescending()
.ToList();
Modifying the system to perform in a more factory oriented approach by applying successive filters based on a supplied string in a pre-specified format.
Is this the way I should be going for this implementation and if not what should I be changing? In particular if I am to proceed with the Indexing option how would I apply this technique to the nested relationship between Forms and FormFields through FormTemplates.
You seems to be trying to do this in a way that is mostly relational, but you don't have to.
Instead of trying to have a set of independent documents that each has part of the data, just store it all in a single document.
public class Form
{
public string Id { get; set; }
public string Name { get; set; }
public IList<FieldValue> FieldValues { get; set; }
public string UserId { get; set; } // the user who completed the form.
public string FormTemplateId { get; set; }
}
public class FieldValue
{
public string Id { get; set; }
// can store the value directly!
//public string ValueAsJsonString { get; set; }
public object Value {get; set; }
}
This will generate documents that looks like this:
{
"Id": "forms/1234",
"Name": "Tom",
"FieldValues": [
{
"Id": "FromValues/SchoolDistrictName",
"Value": "ABi195"
}
],
"UserId": "users/tom",
"FormTemplateId": "FromTemplate/1234"
}
Which is a much more natural way to model things.
At that point, you can use RavenDB's ability to index dynamic data, see the docs here:
https://ravendb.net/docs/article-page/3.5/Csharp/indexes/using-dynamic-fields
I'm having an issue making use of the Mailgun delivered webhook, it can be found here: http://documentation.mailgun.net/user_manual.html#events-webhooks, look for "Delivered Event Webhook"
I am unable to reference Request.Params["Message-Id"] unless I modify the app's requestValidationMode to 2.0
I do get the potentially unsafe error when trying to reference this field without requestValidationMode = 2.0. The contents of the field are: <20130203200110.12345.12345#mydomain.mailgun.org>. I've also tried to declare a model to take advantage of auto model binding. My model looks like this:
public class MailgunDeliveredEvent
{
public string Id { get; set; }
public string Event { get; set; }
public string Recipient { get; set; }
public string Domain { get; set; }
[AllowHtml]
[JsonProperty(PropertyName="Message-Id")]
public object MessageId { get; set; }
public int Timestamp { get; set; }
public string Token { get; set; }
public string Signature { get; set; }
}
When I attempt to reference the MessageId field it returns null. I've tried to add
[Bind(Exclude="message-headers")]
As I'm not interested in that field.
In the Controller, I've set
[ValidateInput(false)]
I can't seem to get the Message-Id field back. Any help?
I seem to have got it working, in case anyone runs into the same issue...
I added a new model binder as referenced here:
Asp.Net MVC 2 - Bind a model's property to a different named value
I then changed my model like so:
[ModelBinder(typeof(DefaultModelBinderEx))]
public class MailgunDeliveredEvent
{
public string Id { get; set; }
public string Event { get; set; }
public string Recipient { get; set; }
public string Domain { get; set; }
[BindAlias("Message-Id")]
public string MessageId { get; set; }
public int Timestamp { get; set; }
public string Token { get; set; }
public string Signature { get; set; }
}
And all seems to work, I didn't need to call
[ValidateInput(false)]
on the controller either.
Hope that helps someone.
I have created a ViewModel called DashboardViewModel:
public class DashboardViewModel
{
public Hardware Hardware { get; set; }
public Software Software { get; set; }
}
I am passing the ViewModel to the view in my ActionResult. But I need to pass other things too. Here is my ActionResult:
public ActionResult Index()
{
HardwareType hwt = new HardwareType { HType = "PC" };
IEnumerable<Hardware> Pcs = db.Hardware.Where(h => h.HardwareType.Contains(hwt));
DashboardViewModel dvm = new DashboardViewModel();
return View(dvm);
}
How do I pass Pcs to the view if I am already passing dvm? I don't even know if this is the right approach. What I am trying to accomplish is to create navigation on the page. So not only will I have PCs, but I'll have monitors and printers to pass to the view, as well as software. Here is my hardware class:
public class Hardware
{
public int Id { get; set; }
public virtual ICollection<DeviceType> Type { get; set; }
public string AssetTagId { get; set; }
public virtual ICollection<Manufacturer> Manufacturer { get; set; }
[Required]
[StringLength(50)]
public string ServiceTagId { get; set; }
[Required]
[StringLength(50)]
public string SerialNumber { get; set; }
[Required]
[StringLength(75)]
public string ProductNumber { get; set; }
// [Required]
[StringLength(20)]
public string PurchaseDate { get; set; }
[StringLength(20)]
public string WarrantyExpiration { get; set; }
[Required]
[StringLength(20)]
public string WarrantyType { get; set; }
public virtual ICollection<Location> Location { get; set; }
public virtual ICollection<HardwareType> HardwareType { get; set; }
[Required]
[StringLength(2000)]
public string Notes { get; set; }
public string POATag { get; set; }
}
What is the best approach for what I want to do (creating the navigation with various categories of hardware and software)? I'm new to MVC and am trying to follow suggestions on what to do, but I could use a higher level approach as maybe I'm going about this all wrong. Thanks.
You can put your Pcs in ViewBag or ViewData as below:
public ActionResult Index()
{
HardwareType hwt = new HardwareType { HType = "PC" };
IEnumerable<Hardware> Pcs = db.Hardware.Where(h => h.HardwareType.Contains(hwt));
ViewBag.Pcs=Pcs;//or ViewData["Pcs"]=Pcs;
DashboardViewModel dvm = new DashboardViewModel();
return View(dvm);
}
ViewBag is the dynamic object. You can add anything to it. With any name e.g. yous Pcs can also be stored in ViewBag as ViewBag.AnyNameYouLike=Pcs;
**RAZOR SYNTAX:**
Just apply loop and you are done.
#foreach(var pc in ViewBag.Pcs)
{
#pc.Id;//Will give you id
}
You can loop through all properties like this
Create a top level view-model - like you have DashboardViewModel - and add all the necessary models as Properties.
It would be good if you created view-models for each business model required in that top level view-model.
Auto-map the business objects to the new view-models - see AutoMapper for one example. That way you are only passing the information the view actually requires.