Unboxing object - asp.net

I have a web method that accepts object
[WebMethod]
public static void GetObject(object data)
{
}
Also, I have 2 classes:
class ConnectionString
{
public string ConnectionString { get; set; }
public DatabaseType DatabaseType { get; set; }
}
class Path
{
public string Path { get; set; }
public bool IsNetwork { get; set; }
}
On client side, using javascript, i defined 2 similar classes as well:
function ConnectionString() {
this.ConnectionString = '';
this.DatabaseType = 0;
};
function Path() {
this.Path = '';
this.IsNetwork = false;
};
Now, according to user decision, he can ether choose to create log in database or file system. When I send data to the method, my object resulted as null. If I create method
for each object, it works. Is there a way to unbox or desirialize from OBJECT type to ?

You need to create two method overloads that each take in one of the possible classes. In the current implementation the engine does not know what classes should be put in the WSDL...
If you are using WCF you could use [KnownType] attribute to specify which classes your method supports.

Related

How to specify default property values for owned entity types in Entity Framework Core 2.0?

I have a simple POCO type, say something like
public class OwnedEntity {
public string stringProperty { get; set; }
public decimal decimalProperty { get; set; }
public bool boolProperty { get; set; }
public int intProperty { get; set; }
}
and an actual entity with an OwnedEntity reference
public class SomeEntity {
public string Id { get; set; }
public OwnedEntity OwnedEntity { get; set; }
}
I set up the relationship like described in the documentation using EF Core's Fluent API:
protected override void OnModelCreating (ModelBuilder builder) {
base.OnModelCreating (builder);
builder.Entity<SomeEntity> ().OwnsOne (e => e.OwnedEntity);
}
I can't find anything on how to define default-values for all the properties of OwnedEntity. I tried to initialize the properties like this:
public class OwnedEntity {
public string stringProperty { get; set; } = "initial"
public decimal decimalProperty { get; set; } = -1M;
public bool boolProperty { get; set; } = false;
public int intProperty { get; set; } = -1;
}
but with no effect. Same goes with the [DefaultValueAttribute] (but that was to expect since it's explicitly mentioned).
There's a bit of information on how to handle initial values for regular entities:
modelBuilder.Entity<SomeOtherEntity>()
.Property(e => e.SomeIntProperty)
.HasDefaultValue(3);
But since I'm facing an Owned Entity Type, I can't access the type via Entity<T>.
Is there a way of doing what I'm looking for?
Some things worth mentioning:
I have a solid amount of specific entities where most of them are using the OwnsOne relation
Declaring all OwnedEntity-properties in a base class is not an option since not all the entities have those properties
I`m using EF Core 2.0.3 and ASP.NET Core MVC 2.0.4
Edit:
Originally, I wanted to have newly created SomeEntity instances to come with preset properties for all of the 'embedded' SomeEntity.OwnedEntity properties.
But looking at how my associated controller works, it all makes sense... I have the following methods for the 'Create' operation:
[HttpGet]
public IActionResult Create () {
return View (nameof (Create));
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create (SomeEntity model) {
context.Add (model);
await context.SaveChangesAsync ();
// redirect etc.
}
Which means that no object is created for the [HttGet] overload of Create and all the HTML inputs linked to properties (via asp-for) are initially empty. Okay. So I guess the proper way of doing this is to manually create a new instance of SomeEntity and pass it to the Create view like this:
[HttpGet]
public IActionResult Create () {
return View (nameof (Create), new SomeEntity());
}
Is this the right approach then or are there some more things to keep in mind?
Assuming you understand what EF Core Default Values are for, and just looking for equivalent of Entity<T>().Property(...) equivalent.
The owned entities are always configured for each owner type by using the ReferenceOwnershipBuilder<TEntity,TRelatedEntity> class methods. To access this class you either use the result of OwnsOne method, or use the OwnsOne overload taking second argument of type Action<ReferenceOwnershipBuilder<TEntity,TRelatedEntity>>.
For instance, using the second approach:
builder.Entity<SomeEntity>().OwnsOne(e => e.OwnedEntity, ob =>
{
ob.Property(e => e.stringProperty)
.HasDefaultValue("initial");
ob.Property(e => e.decimalProperty)
.HasDefaultValue(-1M);
// etc.
});

POST Method fails to populate request object in ServiceStack

I've been using service stack for a while and came upon a scenario where the POST method uses the default instance of the IReturn object (with all the properties defaulting to their datatype values). The values supplied as part of the Route (/product/1234345/) are the only ones populated. I've laid out an example below:
[Route("/search/{searchMethod}/books")]
public class SearchRequest : IReturn<SearchResponse>
{
public SearchProvider searchProvider { get; set; }
public string searchTerm { get; set; }
public string categoryID { get; set; }
public long maxResults { get; set; }
//Only this property gets populated if method is post
public string searchMethod { get; set; }
}
public SearchResponse Any(SearchRequest searchRequest)
{
//This works only for non-post requests
return Put(searchRequest);
}
public SearchResponse Get(SearchRequest searchRequest)
{
//This works
return Put(searchRequest);
}
public SearchResponse Post(SearchRequest searchRequest)
{
//This does not
return Put(searchRequest);
}
public SearchResponse Put(SearchRequest searchRequest)
{
//Code for put method goes here
}
I'm then using a client to call these methods
SearchServiceClient searchClient = new SearchServiceClient(SearchServiceAPIUrl);
SearchResponse searchResponse = searchClient.Search(SearchProvider.SampleSearchProvider, searchterm, categoryID, 100,"conservative");
Any help is really appreciated
Thanks
I've always just populated my request object in the constructor and sent it to the service
searchClient.Post(new SearchRequest(SearchProvider.SampleSearchProvider,
searchterm, categoryID, 100,"conservative")):
I finally found the solution after tinkering with the DTO. It seems for post requests all DTO properties needed to have a [DataMember] attribute for serialization/deserialization and make sure that the class also has a [DataContract] attribute.

ASP.NET MVC How to avoid static variables?

recently posted about questioning how unsafe static variables are, I've since discovered I need to get rid of them. But I cannot figure out how to? Was thinking a static Get() method for each class, that returns a single instance, but then that instance would have to be declared static.
So the only way to do it, is to have the instance references (for each helper, I.E user helper.cs, imagehelper.cs etc.) is to declare them as instance properties on some sort of globally accessible class? But which class? Is there something I'm missing here?
Code below of a sample class I need to change:
sing System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Mvc.Mailer;
namespace MVCWebsite.Helpers
{
public class AppSettings
{
public static void OnAppInit()
{
//General
AppName = "MyApp";
DesktopBaseURLs = new Dictionary<string, string>();
DesktopBaseURLs.Add("dev", "localhost:50560");
DesktopBaseURLs.Add("test", "www.test.whatever.com");
DesktopBaseURLs.Add("live", "www.whatever.com");
MobileBaseURLs = new Dictionary<string, string>();
MobileBaseURLs.Add("dev", "m.local.whatever.com");
MobileBaseURLs.Add("test", "m.test.whatever.com");
MobileBaseURLs.Add("live", "m.whatever.com");
//Emails
EmailHostName = AppName + ".com"; //For the moment atleast
NoReplyEmailAddress = "no-reply#" + EmailHostName.ToLower();
SupportEmailAddress = "support#" + EmailHostName.ToLower();
ErrorEmailAddress = "errors#" + EmailHostName.ToLower();
//Resources
TempFileURL = "/content/temp/";
UserDataURL = "/content/user-content/";
ProfilePicturesURL = UserDataURL + "profile-pictures/";
var a = GlobalHelper.GetURLAsServerPath(ProfilePicturesURL);
var b = a;
}
//General
public static string AppName { get; set; }
public static Dictionary<string, string> DesktopBaseURLs;
public static Dictionary<string, string> MobileBaseURLs;
//Emails
public static string EmailHostName { get; set; }
public static string NoReplyEmailAddress { get; set; }
public static string SupportEmailAddress { get; set; }
public static string ErrorEmailAddress { get; set; }
//Resources
public static string UserDataURL { get; set; }
public static string TempFileURL { get; set; }
public static string ProfilePicturesURL { get; set; }
//Methods
public static void SetAppURL()
{
}
}
}
I recommend creating an interface for your AppSettings class, so that you can use it in your controllers now, and implement it in different ways as you see fit:
public interface IAppSettings
{
string AppName { get; set; }
...
}
You can then implement it immediately with your static class via a wrapper class:
public class AppSettingsWrapper : IAppSettings
{
public AppName
{
get
{
return AppSettings.AppName;
}
set
{
AppSettings.AppName = value;
}
}
...
}
Later on, you can create an implementation of IAppSettings that uses session, or cookies, or database values, or whatever. The important thing is to abstract the way you store things so that you can implement in a way that meets your needs.
The answer to you previous question clearly stated that the IDictionary was the only unsafe variable in your static method because it's not thread safe. You just need to store these variables differently. You don't need to get rid of all of your static variables. You just need to change IDictionary to something thread safe.
By the way, someone there makes a good coment about web.config
Right I think I've figured it out, they should be stored as instance variables within Global.asax.cs. This file contains your Application class which inherits from System.Web.HttpApplication. This master class is limited to one instance (of itself) per request. So if you store any references to your helpers here, you can reference them by going, MvcApplication.MyHelper.DoSomething(); Someone please correct me if this is wrong, but seems right to me. "At any single point of time, an HTTPApplication instance handles only one request, so we don't need to think about locking and unlocking of any non static members, but for static members we do require. " -from : http://www.codeproject.com/Articles/87316/A-walkthrough-to-Application-State#c

Map all properties of a class using reflection

I have two domain classes
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string HouseName { get; set; }
public string StreetName { get; set; }
public string PinCode { get; set; }
}
I want to map object of Employee class to another class.
I am using reflection to map empData object to another object. The code i used is
private void GetValues(object empData)
{
System.Type type = empData.GetType();
foreach (PropertyInfo pInfo in type.GetProperties())
{
//do some stuff using this pInfo.
}
}
I could easily map all the properties except the Address property in the emp object which is an object of another class.
So how can i map all the properties irrespective of its type ? i.e, if address contains object of another class it should also get mapped.
Can't you use AutoMapper for mapping classes?
You can know the type of property you are mapping by
if (propertyInfo.PropertyType == typeof(Address))
{ // do now get all properties of this object and map them}
Assuming that you want to be able to do this on any type of object and not just this specific one, you should use some sort of recursive solution. However if it's just for this object - why are you even using reflection? To me it just adds unnecessary complexity to something as simple as mapping six properties to another set of objects.
If you want to get more concrete help with code examples, you'll have to give us some more context. Why does a method named "GetValues" has a return type of void? I have a hard time coding up an example with that in mind. :)

C# Optional Object Action MVC Parameter

Is it possible to specify an object as a parameter in MVC with default values in some way?
E.g.
public virtual ViewResult Index(RequirementFilters requirementFilters)
I'd like to initialize the values of a couple of parameters on RequirementFilters?
At the moment I am doing
public virtual ViewResult Index(int status=1, bool required =false)
I wanted to create a Filter Object so I could re-use it but I can't figure out way of setting defaults for the object in the Action Parameters.
Thanks
Graeme
You could create a custom ActionFilter attribute and create an instance of your Filter Object there. You can provide some properties through the custom attribute.
Here's an example:
public class DefaultQuerySettingsAttribute : ActionFilterAttribute
{
public string ParameterName { get; set; }
public Type SettingsType { get; set; }
public int Rows { get; set; }
public string SortColumn { get; set; }
public string SortOrder { get; set; }
public bool PagingEnabled { get; set; }
public DefaultQuerySettingsAttribute()
{
this.ParameterName = "settings";
var defaultSettings = new QuerySettings();
this.Rows = defaultSettings.Rows;
this.SortColumn = defaultSettings.SortColumn;
this.SortOrder = defaultSettings.SortOrder;
this.PagingEnabled = defaultSettings.PagingEnabled;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (filterContext.ActionParameters.ContainsKey(this.ParameterName))
{
var querySettings = filterContext.ActionParameters[this.ParameterName] as QuerySettings;
if (querySettings == null || string.IsNullOrWhiteSpace(querySettings.SortColumn))
filterContext.ActionParameters[this.ParameterName] = this.GetQuerySettings();
}
}
private QuerySettings GetQuerySettings()
{
var querySettings = (QuerySettings)Activator.CreateInstance(SettingsType ?? typeof(QuerySettings));
querySettings.Rows = Rows;
querySettings.SortColumn = SortColumn;
querySettings.SortOrder = SortOrder;
querySettings.PagingEnabled = PagingEnabled;
return querySettings;
}
}
ParameterName is the name of the argument in the action method (requirementFilters in your case).
You can also specify actual type that will be instantiated by providing SettingsType.
Users sometimes prefer to see the defaults on screen, rather than allowing the system to hide the defaults internally.
A better way of having defaults will be to actually show the defaults on int UI, in the HTML by rendering it with together with the defaults. That way when someone posts the page, the defaults which you pre-rendered is also posted and binded to the model.
So try and see if you can render with defaults whatever for you are rendering and posted to the Index action.
Finally, if you can't do it that way, what is preventing you from initializing the properties with default values in the no-arg constructor while creating the object?
EDIT
Or you can use the C# language feature the null coalescent operator to implement defaults. Look here to read about it.
As long as you don't need to change the defaults per action, you can set them in the default constructor of the Model.

Resources