Razor MVC Infragistics View - asp.net-mvc-4

I'm trying to render an Infragistics Grid as part of my view in my MVC application. However, I'm trying to do the following:
#(Html.Infragistics()
.Grid(Model)
.ID("grid")
.Width("100%")
.Height("500px")
.PrimaryKey("ID")
.AutoGenerateColumns(false)
.AutoGenerateLayouts(false)
.Columns(column =>
{
column.For(x => x.omkt).HeaderText("OMKT").Width("30%");
column.For(x => x.dmkt).HeaderText("DMKT").Width("30%");
column.For(x => x.ibu).HeaderText("IBU").Width("20%");
column.For(x => x.count_total).HeaderText("COUNT_ALL").Width("20%");
})
.Features(features =>
{
features.Sorting().Type(OpType.Remote);
features.Paging().Type(OpType.Remote);
features.Filtering().Type(OpType.Remote);
})
.DataSourceUrl(Url.Action("GetMarketAreaData?ibu=" + ViewBag.IBU + "&sort=" + ViewBag.sort + "&startDate=" + ViewBag.startDate + "&endDate=" + ViewBag.endDate))
.Render()
)
The problem is on the DataSourceUrl line, where it's transforming all the ? and & characters into their escape sequences. Using \ doesn't work either, as I get a parser error for an unrecognized escape sequence. The reason why I need this, though, is because all of those are passed in as parameters into the controller function in order to pull the correct data.
As a result, I'm getting a 400 error when pulling the data. Is there any way to force the action to recognize ? characters for ? characters?

Found the answer: I needed to pass in a second parameter into Url.Action with all the parameters.
.DataSourceUrl(Url.Action("GetMarketAreaData", new { ibu = ViewBag.IBU, sort = ViewBag.sort, startDate = ViewBag.startDate, endDate = ViewBag.endDate }))

Related

Does RavenDb's `Include` support constructing a document id, not just selecting one?

This code here is not working as expected. Specifically, it seems the calls to Include are not causing any extra documents to be added to the session. Thus, the Loads are each costing a full db hit. This is RavenDb 3.5.
I couldn't find examples that actually use Include this way. They all seem to emit a "selector" that is used to find a member on the document, and that member holds the literal document id to include. Whereas I am constructing the document id and returning it as a string.
session.Query<Coil>()
.Include(c => nameof(CoilState) + "/" + id)
.Include(c => nameof(CoilExt) + "/" + id)
.Include(c => nameof(Material) + "/" + c.MaterialCode)
.Where(c => c.CoilId == id)
.ToList()
.Select(c =>
Coil_Dto.ToCoilDto(
c
, session.Load<CoilState>(nameof(CoilState) + "/" + c.CoilId)
, session.Load<CoilExt>(nameof(CoilExt) + "/" + c.CoilId)
, session.Load<Material>(nameof(Material) + "/" + c.MaterialCode)
)
)
.SingleOrDefault()
My question is: can Include be used in this way? If not, is there some way to achieve that "include" functionality using my constructed ids?
It sounds like you want to use Lazy, rather than Include.
Include
The .Include method should be passed the name of a property on your object(s) which contains an ID.
// Good:
// Note that StateId, ExtId, and MaterialId are all properties on our Coil class.
session.Query<Coil>()
.Include(c => c.StateId)
.Include(c => c.ExtId)
.Inclide(c => c.MaterialId);
// Bad:
session.Query<Coil>
.Include(c => "CoilStates/123")
.Include(c => "CoilExts/456")
.Include(c => "Materials/789")
In short, make sure your .Include calls are passed the name of properties on the Coil class. Those properties should contain string values which are IDs of other documents. Then they'll all be loaded in a single trip to the database.
Lazy
If Include doesn't make sense for your scenario, but you still want to load disparate objects in a single DB call, use the lazy API
// Lazily load the coil. No DB trip yet.
var lazyCoil = session.Query<Coil>()
.Where(...)
.Lazily();
// Lazily load a CoilState. No DB trip yet.
var lazyCoilState = session.Advanced.Lazily.Load<CoilState>("CoilStates/123");
// Lazily load a Material. Still no DB trip.
var lazyMaterial = session.Advanced.Lazily.Load<Material>("Materials/456");
// Grab one of the values. This will fetch all lazy loaded items in 1 trip.
var coil = lazyCoil.Value;
// Grab the other values. No DB trip needed; they're already loaded!
var coilState = lazyCoilState.Value;
var material = lazyMaterial.Value;

Changes b/w ElasticSearch 1.x and 2.x

Does documentation exist on how to change code written in NEST 1.x to 2.x?
I've looked at these sites and they're incomplete:
https://github.com/elastic/elasticsearch-net/blob/master/docs/2.0-breaking-changes/nest-breaking-changes.md
https://github.com/elastic/elasticsearch-net
https://www.elastic.co/blog/ga-release-of-nest-2-0-our-dot-net-client-for-elasticsearch
For example I'd like to know how to replace the following:
1)
given ISearchResponse<T> searchResults = ...
How to do:
searchResults.ConnectionStatus
searchResults.RequestInformation.Request
2)
client.Get<T>(s => s.Id(id));
3)
Given QueryContainer query
new SearchDescriptor<T>()
.From(from)
.Size(pageSize)
.Query(query); //this dosen't work anymore
4)
MatchQuery doesn't accept fuziness as double and type parameters as string as it used to
5) QueryDescriptor seems gone gasp
6) client.Update is busted
var result = client.Update<CustomerProfile>(request => request
.Id(customer.CustomerId)
.Doc(customer)
.Refresh()
);
7) client.Get is busted in a similar way to client.Update
8) In Mappings the following setup doesn't work anymore
CreateIndexDescriptor cid = ...
cid.NumberOfReplicas(numReplicas)
.NumberOfShards(numShards)
.Settings(s => s
.Add("merge.policy.merge_factor", "10")
.Add("search.slowlog.threshold.fetch.warn", "1s")
)
.Analysis(a => a.TokenFilters etc etc
EDIT
9) Date Ranges:
startDate and endDate are DateTime type
var qd = new QueryContainerDescriptor<EsActivity>();
QueryContainer qc = qd.Range(r =>
r.Field("esactivity.timestamp")
.GreaterThanOrEquals(DateMath.Anchored(startDate))
.LessThanOrEquals(DateMath.Anchored(endDate))
);
.GreaterThanOrEquals expects a double parameter but on the documentation page it takes DateMath.Anchored(startDate)
10) Highlighting:
highlightFields: List<string>
Action<HighlightFieldDescriptor<T>> [] tmp = highlightFields.Select(field =>
new Action<HighlightFieldDescriptor<T>>(
highlighter => highlighter.Field(field)
)
).ToArray();
sd:SearchDescriptor<..>..
sd.Highlight(h => h
.PreTags(preTag)
.PostTags(postTag)
.OnFields(tmp)
);
I see I can replace OnFields(tmp) with .Fields(f=>f.OnAll()) but I'd still like to specify the fields myself in some way.
And how come there is a HighlightQuery option available since we already apply highlighting on a query object.. now there are 2 query calls.
I've converted the highlighting above to
var tmp = highlightFields.Select(field =>
Tuple.Create<Field, IHighlightField>(
Field.Create(field),
new HighlightField()
)
).ToDictionary(x => x.Item1, x => x.Item2);
sd.Highlight(h => new Highlight
{
PreTags = new[] { preTag },
PostTags = new[] { postTag },
Fields = tmp
}
);
1) searchResults.ApiCall replaces searchResults .ConnectionStatus.
You can get the request bytes with searchResults.ApiCall.RequestBodyInBytes and you will also need to set .DisableDirectStreaming() on ConnectionSettings in order to capture the bytes as the request is written to the request stream directly by default.
2) Use client.Get<T>(id) - The first parameter is a DocumentPath<T> type.
3) To pass a QueryContainer to a Fluent API descriptor, just return it from the Func<QueryContainerDescriptor<T>, QueryContainer>
new SearchDescriptor<T>()
.From(from)
.Size(pageSize)
.Query(_ => query);
4) match query fuzziness as a double mapped to a formula to calculate edit distance in Elasticsearch 1.x. Since this was removed in Elasticsearch 2.x, it is also gone from NEST. You can set fuzziness edit distance with
client.Search<Document>(s => s
.Query(q => q
.Match(m => m
.Query("this is my query")
.Fuzziness(Fuzziness.EditDistance(3))
)
)
);
Not sure what you're referring to with type, but I think you're referring to document type? If that's the case, document type takes a Types type which string implicitly converts to
client.Search<Document>(s => s
.Type("other-type")
.MatchAll()
);
5) QueryDescriptor<T> was renamed to QueryContainerDescriptor<T> to better reflect the fact that it's a descriptor for building a QueryContainer
6) Update API works
// specifying id
client.Update<Document>("document-id", u => u
.Doc(document)
.Refresh()
);
Since the first parameter is a DocumentPath<T>, the document instance (if you have it) can be passed as the first parameter
client.Update<Document>(document, u => u
.Doc(document)
.Refresh()
);
where index, type and id will be inferred from the document instance
7) See above
8) Create index settings have been revised to reflect the level at which the settings appear in the REST API json call
client.CreateIndex("index-name", c => c
.Settings(s => s
.NumberOfShards(2)
.NumberOfReplicas(2)
.SlowLog(sl => sl
.Search(sls => sls
.Fetch(slsf => slsf
.ThresholdWarn("1s")
)
)
)
.Analysis(a => a) // etc...
)
);
You can also use strings for settings if you prefer, although the fluent API will ensure the correct setting values are sent e.g. "search.slowlog.threshold.fetch.warn" is now "index.search.slowlog.threshold.fetch.warn"
client.CreateIndex("index-name", c => c
.Settings(s => s
.NumberOfShards(2)
.NumberOfReplicas(2)
.Setting("index.search.slowlog.threshold.fetch.warn", "1s")
.Analysis(a => a) // etc...
)
);
merge.policy.merge_factor is removed in Elasticsearch 2.0

Shopify API Updating Fulfillments

I am writing a private app in Shopify with PHP. I have been able to get most of the other access to the json data, however, I am having trouble with Fulfillments - specifically updating a single line-item.
I am using the api-skeleton (phpish)?
Here is my code (the process as described seems so simple):
$orderid = "1350520065";
$itemid = "2338134657";
$quantity = 1;
$arguments = array(
'fulfillment' => array(
'tracking_number' => null,
'notify_customer' => true,
'line_items' => array(array('id' => $itemid, 'quantity' => 1))
)
);
$response = $shopify('POST /admin/orders/' . $orderid . '/fulfillments.json', $arguments);
I am getting [line_items] => Required parameter missing or invalid.
Any help would be appreciated.
Skip the line items unless you are doing a partial fulfillment. If you are, then obviously you need a quantity. You forgot that it seems, hence your error of missing parameter.
Add a header 'Content-Type:application/json' to your POST. That worked for me.

Parse a URL and remove end portion

I am trying to parse URLs. For example where I am trying to pull out:
~/locations/1 => [locations,1]
~/locations/1/comments => [locations,1]
~/locations/1/comments/22 => [locations,1]
~/locations/1/buildings/3 => [buildings,3]
~/locations/1/buildings/3/comments => [buildings,3]
~/locations/1/buildings/3/comments/34 => [buildings,3]
The format is pretty consistent. I started with arrays but it seems to still fail:
#request_path = request.path.downcase.split('/')
#comment_index = #request_path.index("comments").to_i
if #comment_index > 0
#request_path = #request_path.drop_while { |i| i.to_i >= #comment_index }
end
resource, id = #request_path.last(2)
I added the downcase just incase someone manually typed in an uppercase URL. The drop_while seems to not be working.
What kind of output you have after processing your code?
Edited
Your problem is that you convert element to_i and it is 0. But you want to compare index of element, but can normally get index of element in that situation using Array#index method.
Correct approach:
#request_path.drop_while { |i| #request_path.index(i) >= #comment_index }
You can parse path without drop_while.
My solution:
def resource_details(path)
resource_array = path.downcase.split("/").reject!(&:empty?)
key = resource_array.index("comments")
return key.present? ? (resource_array - resource_array[key..key + 1]).last(2) : resource_array.last(2)
end
It will cut out ["comments"] or ["comments","2"] for your path.
Invoke that method:
1.9.3p0 :051 > resource_details("/locations/1/buildings/3/comments")
=> ["buildings", "3"]
1.9.3p0 :052 > resource_details("/locations/1/comments/2")
=> ["locations", "1"]

Symfony file upload - "Array" stored in database instead of the actual filename

I'm using Symfony 1.4.4 and Doctrine and I need to upload an image on the server.
I've done that hundreds of times without any problem but this time something weird happens : instead of the filename being stored in the database, I find the string "Array".
Here's what I'm doing:
In my Form:
$this->useFields(array('filename'));
$this->embedI18n(sfConfig::get('app_cultures'));
$this->widgetSchema['filename'] = new sfWidgetFormInputFileEditable(array(
'file_src' => '/uploads/flash/'.$this->getObject()->getFilename(),
'is_image' => true,
'edit_mode' => !$this->isNew(),
'template' => '<div id="">%file%</div><div id=""><h3 class="">change picture</h3>%input%</div>',
));
$this->setValidator['filename'] = new sfValidatorFile(array(
'mime_types' => 'web_images',
'path' => sfConfig::get('sf_upload_dir').'/flash',
));
In my action:
public function executeIndex( sfWebRequest $request )
{
$this->flashContents = $this->page->getFlashContents();
$flash = new FlashContent();
$this->flashForm = new FlashContentForm($flash);
$this->processFlashContentForm($request, $this->flashForm);
}
protected function processFlashContentForm($request, $form)
{
if ( $form->isSubmitted( $request ) ) {
$form->bind( $request->getParameter( $form->getName() ), $request->getFiles( $form->getName() ) );
if ( $form->isValid() ) {
$form->save();
$this->getUser()->setFlash( 'notice', $form->isNew() ? 'Added.' : 'Updated.' );
$this->redirect( '#home' );
}
}
}
Before binding my parameters, everything's fine, $request->getFiles($form->getName()) returns my files.
But afterwards, $form->getValue('filename') returns the string "Array".
Did it happen to any of you guys or do you see anything wrong with my code?
Edit: I added the fact that I'm embedding another form, which may be the problem (see Form code above).
Alright, I got it. I wasn't properly declaring my validator.
What i should've done is:
$this->setValidator('filename', new sfValidatorFile(array(
'mime_types' => 'web_images',
'path' => sfConfig::get('sf_upload_dir').'/flash',
)));
Silly mistake, I hope that will help those who have the same problem.
Alternatively you can use;
$this->validatorSchema['filename']
in place of;
$this->setValidator['filename']