Get url parameters in NancyFx - nancy

I am using NancyFx to build a web API, but I am facing some problems when getting parameters from the URL.
I need to send, to the API, the request .../consumptions/hourly?from=1402012800000&tags=%171,1342%5D&to=1402099199000 and catch the value of the parameters: granularity, from, tags and to. I tried several approches and none worked. I tried, for example,
Get["consumptions/{granularity}?from={from}&tags={tags}&to={to}"] = x =>
{
...
}
How can I do this?
Luis Santos

There are 2 things that you are trying to get from the URL. One is a part of the path hourly - and the other is the parameters in the query string - namely the values for from and to.
You can get to the part of the path through the parameter to the handler - the x in your example.
You can get to the query string through the Request which is accessible on the NancyModule.
To put this in code:
Get["consumptions/{granularity}"] = x =>
{
var granularity = x.granularity;
var from = this.Request.Query["from"];
var to = this.Request.Query["to"];
}
The variables granularity. from, and to are all dynamic, and you may need to convert them to whatever type you want.

You can let NancyFx's model binding take care of the url query string.
public class RequestObject
{
public string Granularity { get; set; }
public long From { get; set; }
public long To { get; set; }
}
/consumptions/hourly?from=1402012800000&to=1402099199000
Get["consumptions/{granularity}"] = x =>
{
var request = this.Bind<RequestObject>();
}

You can simply use:
var from = Request.Query.from;

Related

WCF Service and Windows Application Client. why client receives null

I have mapped the service with a linq to Sql classes and I am using wcf library for vs 2019 and in client a win form app.
I am trying sending the class created for linq to sql the next way
public List<Trades> GetAllTradings()
{
context = new DCStockTradingDataContext();
List<Trades> tradings = (from t in context.Trades
select t).ToList();
return tradings;
}
and the client
private void btnRun_Click(object sender, EventArgs e)
{
Service1Client client = new Service1Client();
var trades = client.GetAllTradings();
dgViewStocks.DataSource = trades;
//string ret = client.GetData("Hello");
//Console.WriteLine(ret);
}
I din´t know what is happening and I don´t know what is wrong
The service
and the client receives all null
I would appreciate any help about this and thank you in advance
If you get null response in WCF client, some advices:
try to call the service in SoapUi with Validation of request and response turned on. It may be useful in detecting problems.
debug Reference.cs file to see more closely what is going on
use MessageInspector to see what is received in AfterReceiveReply method
examine namespaces attentively, response often cannot be deserialized because of the difference in namespaces that are in Reference.cs and in real service
Thanks for your response and everything if this I did.
I found how I have to work with linq to sql classes and wcf. We need to take into account that you need to convert the List of linq classes to List<string. What I did
enter code here
public List<string[]> GetAllStocks()
{
context = new DCStockTradingDataContext();
System.Data.Linq.Table<Stocks> stocks = context.GetTable<Stocks>();
var allStock = (from st in stocks
select new
{
stockId = (string) st.CodeID,
currency = (char) st.Currency,
stName = st.Name,
price = (decimal) st.Price,
volument = (decimal) st.Volumen
}).ToList();
List<string[]> listRetruned = new List<string[]>();
foreach (var tr in allStock)
{
string[] t = new string[5];
t[0] = tr.stockId;
t[1] = tr.currency.ToString();
t[2] = tr.stName;
t[3] = tr.price.ToString();
t[4] = tr.volument.ToString();
listRetruned.Add(t);
}
return listRetruned;
}
and the client
I have created a model class with the expected data
public class TradingModel
{
public string TradeID { get; set; }
public string StockId { get; set; }
public decimal Bid { get; set; }
public int BidQty { get; set; }
public decimal Ask{get;set;}
public int AskQty { get; set; }
public decimal Last { get; set; }
}
and finally the method
List<TradingModel> models = new List<TradingModel>();
for(int i = 0; i < trades.Length; i++)
{
TradingModel model = new TradingModel()
{
Ask = Convert.ToDecimal(trades[i][0]),
Bid = Convert.ToDecimal(trades[i][1]),
BidQty = Convert.ToInt32(trades[i][2]),
AskQty = Convert.ToInt32(trades[i][3]),
Last = Convert.ToDecimal(trades[i][4]),
StockId = trades[i][5],
TradeID = trades[i][6],
};
models.Add(model);
}
dgViewStocks.DataSource = models;
I am not sure if this is the best way to jump to next step, but it worked for me. If someone is looking for this info as I did, wasting several days chasing the solution, I leave what I did.
There is off course changing the service and generate the proxy again

Azure Search - Query

So I'm using the C# nuget wrapper around Azure Search. My problem is I have a index of products:
public class ProductDocument
{
[System.ComponentModel.DataAnnotations.Key]
public string Key { get; set; }
[IsSearchable]
public string Sku { get; set; }
[IsSearchable]
public string Name { get; set; }
[IsSearchable]
public string FullDescription { get; set; }
[IsSearchable]
public List<CustomerSkuDocument> CustomerSkus { get; set; }
}
public class CustomerSkuDocument
{
[IsSearchable]
public int AccountId { get; set; }
[IsSearchable]
public string Sku { get; set; }
}
Example data would be:
new Product() { Key= 100,Name="Nail 101",Sku = "CCCCCCCC", CustomerSkus = new List<ProductCustomerSku>()
{
new ProductCustomerSku() {AccountId = 222, CustomerSku = "BBBB"},
new ProductCustomerSku() {AccountId = 333, CustomerSku = "EEEEEEE"}
}
So the problem is around CustomerSkuDocument.
When I Search I need to pass the AccountId in as well as the search term, however the AccountId is only used for when searching the ProductCustomerSkus.
Basically an Account can have different customer skus but it's only associated to that account - I don't want a separate index per account.
So my call would be something like /AccountId=222&term=BBBB which would find the match.
However /AccountId=333&term=BBBB would not find a match.
So I'm calling it like:
SearchParameters sp = new SearchParameters();
sp.SearchMode = SearchMode.Any;
sp.QueryType = QueryType.Full;
DocumentSearchResult<ProductDocument> results =
productIndexClient.Documents.Search<ProductDocument>(term, sp);
Where term is the normal search term, tried it with adding the AccountId but it doesn't work.
Azure Search does not support repeating data structures nested under a property of the outer document. We're working on this (see https://feedback.azure.com/forums/263029-azure-search/suggestions/6670910-modelling-complex-types-in-indexes), but we still have some work to do before we can release that.
Given that, the example you're showing is not probably indexing the nested parts. Can you post the search index definition you're using? While we work in direct support for complex types, you can see your options for approach here: https://learn.microsoft.com/en-us/azure/search/search-howto-complex-data-types
From the above you'll arribe at a index structure that will also guide your query options. If all you need is equality, perhaps you can simply include the accountId and the SKU in the same field and use a collection field so you can have multiple instances. For your query you would issue a search query that requires the accountId and has the rest as optional keywords.

How to search for empty strings in a text field with Entity Framework?

I'd like to know how can I search for empty strings when I'm using a text type field with Entity Framework.
I've looked the SQL query that Entity is generating and It's using LIKE to compare because It's searching in a text type field, so when I use .Equals(""), == "", == string.Empty, .Contains(""), .Contains(string.Empty), and everything else, It's returning all results because it sql query is like '' and the == command throws exception because It uses the = command that is not valid with text type field.
When I try to use .Equals(null), .Contains(null), == null, It returns nothing, because It is generating FIELD ISNULL command.
I already tried the .Lenght == 0 but It throws an exception...
This works for me:
public class POCO
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
static void Main(string[] args)
{
var pocos = new List<POCO>
{
new POCO { Id = 1, Name = "John", Description = "basic" },
new POCO { Id = 2, Name = "Jane", Description = "" },
new POCO { Id = 3, Name = "Joey", Description = string.Empty }
};
pocos.Where(x => x.Description == string.Empty)
.ToList()
.ForEach(x => Console.WriteLine($"{x.Id} {x.Name} {x.Description}"));
}
However the issue MAY BE that your T4 generated object is not fully realized with data you can use, if you are using Entity Framework. EG the translation from the database is not populating objects to interrogate correctly. I would just do an operation like this to see:
using (var context = new YOURCONTEXTNAME())
{
var persons = context.YOURDATABASEOBJECT.ToList();
persons.ForEach(x => Console.WriteLine($"{x.COLUMNINQUESTION}"));
}
If you are successfully having data in it, it should be retrieved. I would not use text if possible. Use a varchar(max) nvarchar(max) xml, whatever text will be deprecated eventually and is bad form so to speak to continue using at this point.
EDIT
Okay I see, the answer is you cannot interogate the object until it is fully realized when it is text. I did a test on my local database and created a context and tested it and sure enough you cannot do a '== string.empty', '== ""', or 'String.IsNullOrEmpty()' on a text. However you can do it once the object is materialized in a realized object. EG:
// Won't work as context does not understand type
//var persons = context.tePersons.Where(x => x.Description == string.Empty).ToList();
//Works fine as transformation got the object translated to a string in .NET
var start = context.tePersons.ToList();
var persons = start.Where(x => x.Description == String.Empty).ToList();
This poses a problem obviously as you need to get ALL your data potentially before performing a predicate. Not the best means by any measure. You could do a sql object for this instead then to do a function, proc, or view to change this.

How to parse dynamic object in mvc?

I am working on ASP.NET MVC4.0.
My string is posting like this from view :-
[{"name":"AddressNumber","value":"1"},{"name":"OrganizationProd","value":""},{"name":"ClientId","value":""},{"name":"ProductId","value":""},{"name":"TaxId1","value":""},{"name":"TaxId2","value":""},{"name":"LaborID","value":"0"}]
And below is my controller's action method for that,which is receiving the input :-
[AllowAnonymous]
[HttpPost]
public ActionResult UpdateProducts(string ModelString){
}
And below is the string which i am getting in action(in ModelString variable):-
[{"name":"AddressNumber","value":"1"},{"name":"OrganizationProd","value":""},{"name":"ClientId","value":""},{"name":"ProductId","value":""},{"name":"TaxId1","value":""},{"name":"TaxId2","value":""},{"name":"LaborID","value":"0"}]
And after that i am deserializing the string like that :-
var sear = new JavaScriptSerializer();
var dictDynamic = sear.Deserialize<dynamic>(ModelString);
And i am getting the dynamic array in dictDynamic variable.And now i want to get the properties by its name not by indexing from dictDynamic object.
Currently i am getting the properties by indexing like this :-
dictDynamic[0]["value"]
dictDynamic[1]["value"]
But i want to parse it by properties name like this :-
dictDynamic["Name"]["value"]
dictDynamic["Description"]["value"]
Can anyone help me out on this ?
You could use ViewModel on server side, not sending model string.
You create ViewModel like this:
class ProductViewModel {
public int AddressNumber { get; set; }
public int ProductId { get; set; }
...
}
Then change your controller method:
[AllowAnonymous]
[HttpPost]
public ActionResult UpdateProducts(ProductViewModel vm){
...
}
And from your View you'll send json object like this:
{
"AddressNumber":"10",
"OrganizationProd":"1",
"ClientId":"1",
"ProductId":"1",
"TaxId1":"23",
"TaxId2":"23",
"LaborID":"10"
}
This will automaticaly bind your values from View to ViewModel on controller, and you can than use ViewModel object in your code, and you then have strongly typed entity.
Instead of this:
dictDynamic["AddressNumber"]
dictDynamic["OrganizationProd"]
now you can write this:
vm.AddressNumber
vm.OrganizationProd
You need to pass a JavaScript object to your function instead of an array. Array is not the correct data structure to use in this case. Objects have keys and values. The keys will be AddressNumber, OrganizationProd, ClientId, ProductId, TaxId1 etc. Their values will be 1, "", "0" etc.
For instance, for your example, this will be your object:
{
"AddressNumber":1,
"OrganizationProd":"",
"ClientId":"",
"ProductId":"",
"TaxId1":"",
"TaxId2":"",
"LaborID":0
}
You deserialize it like you do now:
var s = "{\"AddressNumber\":1, \"OrganizationProd\":\"\", \"ClientId\":\"\", \"ProductId\":\"\", \"TaxId1\":\"\", \"TaxId2\":\"\", \"LaborID\":0}";
var sear = new JavaScriptSerializer();
var dictDynamic = sear.Deserialize<dynamic>(s);
Once you deserialize, you will be able to reference the values like this:
dictDynamic["AddressNumber"]
dictDynamic["OrganizationProd"]

Autofixture test for invalid constructor parameter

I have the following class and test. I want to test passing a null value as a parameter to the constructor and are expecting an ArgumentNullException. But since I use the Autofixture's CreateAnonymous method I get a TargetInvocationException instead.
What is the correct way to write those kinds of tests?
public sealed class CreateObject : Command {
// Properties
public ObjectId[] Ids { get; private set; }
public ObjectTypeId ObjectType { get; private set; }
public UserId CreatedBy { get; private set; }
// Constructor
public CreateObject(ObjectId[] ids, ObjectTypeId objectType, UserId createdBy) {
Guard.NotNull(ids, "ids");
Guard.NotNull(objectType, "objectType");
Guard.NotNull(createdBy, "createdBy");
Ids = ids;
ObjectType = objectType;
CreatedBy = createdBy;
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void constructor_with_null_ids_throw() {
fixture.Register<ObjectId[]>(() => null);
fixture.CreateAnonymous<CreateObject>();
}
IMO, Ruben Bartelink's comment is the best answer.
With AutoFixture.Idioms, you can do this instead:
var fixture = new Fixture();
var assertion = new GuardClauseAssertion(fixture);
assertion.Verify(typeof(CreateObject).GetConstructors());
The Verify method will provide you with a quite detailed exception message if any constructor argument in any constructor is lacking a Guard Clause.
FWIW, AutoFixture extensively uses Reflection, so I don't consider it a bug that it throws a TargetInvocationException. While it could unwrap all TargetInvocationException instances and rethrow their InnerException properties, that would also mean disposing of (potentially) valuable information (such as the AutoFixture stack trace). I've considered this, but don't want to take AutoFixture in that direction, for exactly that reason. A client can always filter out information, but if information is removed prematurely, no client can get it back.
If you prefer the other approach, it's not too hard to write a helper method that unwraps the exception - perhaps something like this:
public Exception Unwrap(this Exception e)
{
var tie = e as TargetInvocationException;
if (tie != null)
return tie.InnerException;
return e;
}
I came across this while I was searching for something similar. I would like to add that, combined with automoqcustomization and xunit, below code also works and its much cleaner.
[Theory, AutoMoqData]
public void Constructor_GuardClausesArePresent(GuardClauseAssertion assertion)
{
assertion.Verify(typeof(foo).GetConstructors());
}
You just need to create the AutoMoqData attribute as follows.
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute() : base(() => new Fixture().Customize(new AutoMoqCustomization()))
{
}
}

Resources