Receive data in MVC controller from webrole - asp.net-mvc-3

I understood how to communicate between Web, Worker role and the flow in MVC architecture.
My question is, after I query the data from a table in web role, how can the controller in MVC get this data to diplay in the view?
I tried using a global static variable in webrole, where the data gets populated, but when I access the static variable from the controller, it only returned 'null'. Why am I getting a null?
Thanks.

ok, in case you use the storage client, the implementation would be like:
Create your Model:
public class MyEntity : Microsoft.WindowsAzure.StorageClient.TableServiceEntity
{
public MyEntity()
{
PartitionKey = DateTime.UtcNow.ToString("MMddyyyy");
RowKey = string.Format("{0:10}_{1}",
DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
}
// Define the properties.
public string Title { get; set; }
public string Name { get; set; }
}
}
2. Define your context class:
public class MyDataContext : TableServiceContext
{
public MyDataContext(string baseAddress,
StorageCredentials credentials)
: base(baseAddress, credentials)
{ }
public IQueryable GetMyEntity
{
get
{
return this.CreateQuery("MyTableName");
}
}
}
Implement your controller action method:
public ActionResult Index()
{
var context = new MyDataContext(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
var results = from g in context.GetMyEntity
where g.PartitionKey ==
DateTime.UtcNow.ToString("MMddyyyy")
select g;
return View(results.FirstOrDefault());
}
this is reference code only, which is very ugly and will hardly work as it is, but it still provides an example of how you can query the table storage in your MVC project.

are we talking about an application whose MVC part is hosted in a worker role and which gets data from a web role which is querying the table storage? Or are we talking about a ASP.NET MVC application here which is hosted in a web role?
static variables is not a good idea at all because of concurrency issues.
in case of scenario 1, how do you communicate with a web role? via web service call directly?
you cold simply call the service from your controller or delegate the call to another layer and then put this data in your model which is then displayed by the corresponding view.
have you tried debugging this application locally using the [azure local dev env][1]
[1]: http://blogs.msdn.com/b/morebits/archive/2010/12/01/using-windows-azure-development-environment-essentials.aspx ? or do you use the real azure infrastructure? Are you sure you are getting the data from your query? maybe the query is wrong? have you observed any exceptions?
we need more information here to be able to help you

Related

500 Server Error with data transfer in API

public APIController()
{
db = new ApplicationDbContext();
}
ApplicationDbContext db;
[HttpGet]
public List<Category> GetCategories()s
{
return db.Categories.ToList();
}
I am trying to get categories from the Web API. I am using AJAX, but it gives a 500 exception.
Since connection string is right and all setup correctly, There are 2 possible issues in the code I see:
1- Your Api Controller is named APIController which is a reserved word in .NET Api
2- Your get service is trying to return a complete Object from categories which might be related to parent objects and the parent objects are related to other related objects which results in returning the whole database.
I suggest using select new in lambda like this:
[HttpGet]
public List<Category> GetCategories()s
{
return db.Categories.Select(a => new { a.Name, a.ID, a.Description }).ToList();
}
This way you avoid querying the whole database.

In the MVC programming pattern, which category does the following code fall under?

If I have some code which is will HTTP request a remote website and extract data from it, or login to this website and extract data from it; what would I put this under? The model or the controller? I'm think that it is a model, because the controller should talk to the user and call upon my models to do stuff.
Is this correct?
Model is correct. The data crunching portion should be left to the models. The controllers direct the traffic between the models and views. Finally, views are used to display the data.
You would probably do this a view or controller. If you will need to do any large manipulation with the data, you could create and action that makes a request and then manipulates the data and then pass that data onto a view. If you will need simpler operations, and depending on your framework, you can make the request in the view itself.
You would possibly use all of the View, Model and controller. But if you don't want to display the result, it would likely be just the controller and model.
For example, the controller code would have an ActionResult method which would call your remote website.
e.g. your model
public class RemoteWSData
{
public string Code { get; set; }
public string Name { get; set; }
}
your controller:
public ActionResult GetRemoteWebsiteData()
{
RemoteWSData model = repository.GetRemoteWebsiteData();
string code = model.Code;
string name = model.Name;
}
with the repository above being a data access class. This data access class would contain references to the connections required to access the data or server and get these values from a web.config file.

How to configure odata web api route for method that always returns single entity

I'd like to configure a route that always returns a single entity.
The controller looks like:
class StatsController: ODataController {
public Stats Get() {
return new Stats();
}
}
The url to access it should be: GET ~/service-prefix/stats
All the options I've seen involve having to return IQueryable, or when returning a single entity, passing in a key in a form of ~/service-prefix/EntitySet(1)
Is there a way to achieve the above without having to return an IQueriable?
By default any action of the following forms should be reachable for your scenario:
Example:
public Stat Get([FromODataUri] int key) { }
or
public Stat Get#your-entity-name#([FromODataUri] int key) { }
To access a single object without needing to have an entityset, odata v4 introduces the concept of singletons.
From OData v4 spec:
A singleton allows addressing a single entity directly from the entity container without having to know its key, and without requiring an entity set.
More info:
Use Singleton to define your special entity
ODataLib for OData v4: Singletons and Containment
I believe Singleton could meet your requirement, but it is not implemented in WebApi. Fortunately, there is another option: unbound function. Just follow this sample: http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataFunctionSample/.
There is a method in ProductsController:
[HttpGet]
[ODataRoute("GetSalesTaxRate(state={state})")]
public IHttpActionResult GetSalesTaxRate([FromODataUri] string state)
{
return Ok(GetRate(state));
}
It is requested through this URL: ~/service-prefix/GetSalesTaxReate(state='WA') and is very close to your scenario. The only thing you need to do is to remove the parameter of the function:
[HttpGet]
[ODataRoute("GetStats()")]
public IHttpActionResult GetStats()
{
return Ok(new Stats());
}
Now you can request ~/sevice-prefix/GetStats().

How to use a Dictionary or Hashtable for LINQ query performance underneath an OData service

I am very new to OData (only started on it yesterday) so please excuse me if this question is too dumb :-)
I have built a test project as a Proof of Concept for migrating our current web services to OData. For this test project, I am using Reflection Providers to expose POCO classes via OData. These POCO classes come from in-memory cache. Below is the code so far:
public class DataSource
{
public IQueryable<Category> CategoryList
{
get
{
List<Category> categoryList = GetCategoryListFromCache();
return categoryList.AsQueryable();
}
}
// below method is only required to allow navigation
// from Category to Product via OData urls
// eg: OData.svc/CategoryList(1)/ProductList(2) and so on
public IQueryable<Category> ProductList
{
get
{
return null;
}
}
}
[DataServiceKeyAttribute("CategoryId")]
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public List<Product> ProductList { get; set; }
}
[DataServiceKeyAttribute("ProductId")]
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
}
To the best of my knowledge, OData is going to use LINQ behind the scenes to query these in-memory objects, ie: List in this case if somebody navigates to OData.svc/CategoryList(1)/ProductList(2) and so on.
Here is the problem though: In the real world scenario, I am looking at over 18 million records inside the cache representing over 24 different entities.
The current production web services make very good use of .NET Dictionary and Hashtable collections to ensure very fast look ups and to avoid a lot of looping. So to get to a Product having ProductID 2 under Category having CategoryID 1, the current web services just do 2 look ups, ie: first one to locate the Category and the second one to locate the Product inside the Category. Something like a btree.
I wanted to know how could I follow a similar architecture with OData where I could tell OData and LINQ to use Dictionary or Hashtables for locating records rather than looping over a Generic List?
Is it possible using Reflection Providers or I am left with no other choice but to write my custom provider for OData?
Thanks in advance.
You will need to process expression trees, so you will need at least partial IQueryable implementation over the underlying LINQ to Objects. For this you don't need a full blown custom provider though, just return you IQueryable from the propties on the context class.
In that IQueryable you would have to recognize filters on the "key" properties (.Where(p => p.ProductID = 2)) and translate that into a dictionary/hashtable lookup. Then you can use LINQ to objects to process the rest of the query.
But if the client issues a query with filter which doesn't touch the key property, it will end up doing a full scan. Although, your custom IQueryable could detect that and fail such query if you choose so.

Using the entity modal with mvc -mvvm

Hi there I am hoping someone can point me in the right direction.
I want to create an mvc applicaton I have worked my way through the music store example and still am not 100% sure the correct way to do things.
Lets say I want to create an application that stores cooking receipes.
I have a 3 tables
RecipeTable
RecipeID
RecipeName
RecipeIngredients
RecipeIngredientID
RecipeID
IngredientID
Measurement
IngredientTable
IngredientID
IngredientName
All have PK & FK mappings very basic, I create a new mvc application and use the entity framework to create a new entity e.g. RecipeDB
My next step is I create a new model for each of the tables and give the properties my desired displaynames and specify required fields extra.
Do I then create a viewmodel e.g. RecipesViewModel that looks something like
public class RecipesViewModel
{
public int RecipeID { get; set; }
public string RecipeName { get; set; }
public List<RecipeIngredients> { get; set; }
}
I now create the controller (Ithink) but I am not really sure how to bind that to database entity.
I know you can call the database by doing something like RecipeEntities db = new recipeEntites(); however binding the results to the vm I am little confussed on how to do that.
Am I heading in the right direction so far?
You could use AutoMapper. It's a great tool allowing you to convert from one type to another and in your case from the model to the view model.
public ActionResult Foo()
{
RecipeDB model = _repository.GetRecipies();
RecipesViewModel viewModel = Mapper.Map<RecipeDB, RecipesViewModel>(model);
return View(viewModel);
}
or you could even define a custom action attribute (like the one I used in my sample MVC project) allowing you to simply write:
[AutoMap(typeof(RecipeDB), typeof(RecipesViewModel))]
public ActionResult Foo()
{
RecipeDB model = _repository.GetRecipies();
return View(model);
}

Resources