Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
mortarr
Apr 28, 2005

frozen meat at high speed
I have an internal site that serves branding content to other internal sites. It's made up of some dynamic css and images that are held in a database (accessed via EF) plus some static css, image and font files.

The dynamic stuff is accessed via a get to an MVC controller action method, with a query string like so: `http://url/template/css?unit=city-future&division=communications`. I wanted to use named params rather than primary keys, so it was clear in the secondary sites what was being pulled.

My main concern is that it's taking almost 1s to do the roundtrip to serve the css, and it's quite noticable with styles updating part way though page-load.

I thought I could add some kind of cache because the data is effectively static, but I've not worked with caching before, so can anyone give me some pointers or recommend some resources on caching in ASP.Net MVC / IIS?

Adbot
ADBOT LOVES YOU

mortarr
Apr 28, 2005

frozen meat at high speed
Does anyone use reporting services? I've got an image that I want to place behind some text in the page header and I want to export the report to PDF.

If I just place a text control over the image, the text is not rendered. If I set the image as background in the text control, the text is rendered, but the image is clipped. Is there any way with the default SSRS controls to tell an image to fit proportionally if it's the background in a text control, or are there any 3rd party controls that will allow this?

This was a solved problem in Access 97 of all things!

mortarr
Apr 28, 2005

frozen meat at high speed

RICHUNCLEPENNYBAGS posted:

OK, I'm gonna go ahead and ask this dumb question: MVC seems to have an attribute you can put on actions where you can cache the page render, but how could caching the entire page be useful when you have a bar showing the username and so on? What I'd really like to do, of course, is cache portions of pages, and for certain circumstances (like caching one tenant's version of a page and serving it to everyone in a multi-tenant app is also bad). Is there like, an obvious built-in tool for that or should I be rolling my own?

I haven't used it myself, but it seems like you're looking for donut caching. From the link:

quote:

What is Donut Caching?

When we talk about output caching, there are three different scenarios that we may encounter:

Full page caching
Full page caching is where you cache the entire page with no substitutions. It is handled with the built-in OutputCache attribute that has been available since ASP.NET MVC 1.

Partial page caching (Donut hole caching)
Donut hole caching is where you cache one or more parts of a page, but not the entire page. It is handled by using the built-in OutputCache attribute on one or more child actions (called using Html.Action or Html.RenderAction from the parent view). It has been available since ASP.NET MVC 3.

Partial page caching (Donut caching)
Donut caching is where you cache the entire page except for one or more parts. It was possible in ASP.NET MVC 1 by using the substitution control, but is not available out of the box in ASP.NET MVC 3.

The omission of donut caching in MVC3 is unfortunate as it is an extremely popular requirement. In fact, any site that allows a user to log in will usually not be able to use full page caching (at least, not without employing secondary ajax requests as a workaround).

mortarr
Apr 28, 2005

frozen meat at high speed
Does anyone have or know of a .net wrapper for ghostscript, or some other free pdf library?

I'm trying to render single pages to png using imageresizers' pdf renderer, but I've got some kind of wierd pdf that is causing it to fail, and I want to get to grips with what's causing my failure without going through the imageresizer pipeline.

mortarr
Apr 28, 2005

frozen meat at high speed

gently caress me, 10 lines of code to fix what three days of loving around writing bindings for other pdf libraries and a call to the vendor couldn't. Thanks!

code:
private static Bitmap Decode(Stream s, string page)
{
  const int Dpi = 96;

  using (var rasterizer = new GhostscriptRasterizer())
  {
    rasterizer.Open(s);
        
    var img = rasterizer.GetPage(Dpi, Dpi, int.Parse(page));

    return new Bitmap(img);
  }      
}

mortarr
Apr 28, 2005

frozen meat at high speed
I'm setting up a TFS 2013 server today, so we can finally get shot of VSS!

mortarr
Apr 28, 2005

frozen meat at high speed

Knyteguy posted:

Anyone have an opinion on the Telerik tools, http://www.telerik.com/windows-universal-ui, or telerik appbuilder? As a .NET developer who uses their tools - have you found them to be worth the cost?

My team have been using telerik devcraft for the last year or so, and although I've not used the win ui stuff (just the asp.net mvc and kendo ui).

I've found they keep their tools up to date, they have good response times to posts in their own forums, they do quarterly releases plus fairly regular updates in between times. I think for the most part their getting started and api docs are good, certainly enough to get something of medium complexity/sophistication going, and from there you can hit their forums or stack overflow. They do webinars every now and then about the devcraft toolset, although I've not taken part in one so far.

I've not tried any alternatives and I can't remember why we chose telerik in the first place, but the controls themselves are way better than the VS defaults or hacking together a bunch of open source components that were never designed to fit together. With that plus the support you get with paid-for tools, I think they're pretty sweet.


Edit:

That particular product is in beta, and there are only a few components, but you might be interested to know that kendo ui has had maybe 10-15 controls added in the last year, so I would expect they'll release a bunch of extra controls plus enhancements to existing ones over the next few months - it looks like they're coming out of beta in October too.

mortarr fucked around with this message at 23:03 on Aug 24, 2014

mortarr
Apr 28, 2005

frozen meat at high speed

Ciaphas posted:

Am I the only one who thinks chaining dot-notation function calls is a gently caress of a lot easier to read? Or is that my C++ background showing? :v:

Nope, I was writing sql for years before linq was a thing, and I just don't like the way it looks. I always get tangled up mentally translating its syntax back to actual sql and it pisses me off to need to hit google for every goddamn query I try to write that way, so I always end up either writing a view for complex joins / selects and doing the dot notation thing like yourself for the basics.

I'm lucky in that I'm able to write my own views and procs etc I guess, seems like I might be in the minority in here? Don't know how I'd get on if I wasn't able to do that.

mortarr
Apr 28, 2005

frozen meat at high speed
Does anyone have any ideas on how to take a querystring like so:

code:
take=20
&skip=20
&page=2
&pageSize=20
&sort[0][field]=JobBagNumber&sort[0][dir]=asc
&filter[logic]=or&filter[filters][0][value]=what&filter[filters][0][operator]=eq&filter[filters][0][field]=JobBagNumber
&filter[filters][1][value]=what&filter[filters][1][operator]=contains&filter[filters][1][field]=State
&filter[filters][2][value]=what&filter[filters][2][operator]=contains&filter[filters][2][field]=Title
and parse it into a dynamic / expando object based on json like so:

code:
{
  take: "20",
  ...
  sort: [ { field: "JobBagNumber" }, { dir: "asc" } ],
  filter: { 
    logic: "or", 
    filters: [ { value: "what", operator: "eq", field: "JobBagNumber" }, ... ]
  },
  ...
}
I've been bashing my head against a brick wall all day on this goddamn thing.


Edit: gently caress me, just figured out a way to post this data as json instead, now I don't need to do this at all. 15 years of cutting code and I still miss the basics sometimes!

mortarr fucked around with this message at 05:04 on Sep 4, 2014

mortarr
Apr 28, 2005

frozen meat at high speed

GrumpyDoctor posted:

What have you tried, and what's not working?

I was treating c# like javascript and it turns out if I do a Post instead of a Get I can JSON.stringify() my object and send it up as post data, and then it's all sweet from there. Can't believe I wasted like four hours on this poo poo.

mortarr
Apr 28, 2005

frozen meat at high speed

gently caress them posted:

That worked great, thank you.

It's still weird letting LINQ just do it all for me, but it definitely works when it does.

If you're after optional conditions in the where clause, there's always predicate builder.

mortarr
Apr 28, 2005

frozen meat at high speed

Bognar posted:

Enterprisey stuff
That's some serious business... Can you go into how you end up building something like that, like how did you choose EF, how long did it take to design and put together, what's your team size etc. Assuming you're allowed to discuss that?

mortarr
Apr 28, 2005

frozen meat at high speed
I've got a problem with a 3rd-party component not playing nicely... maybe someone in here can point me in the right direction?

Not sure what info is relevant, so here's the config:
- I have a c#/MVC web app that takes a word doc (docx), adds a bunch of text and images using OpenXmlSdk.
- Some of the images are extracted from other pdf or tiff documents using PageExtractor (the 3rd party component).
- PageExtractor comes in x86 and x64 versions, however we need to use the x86 version because OpenXmlSdk is x86 and there is no x64 version, and both assemblies are used in the same VS project.
- The three VS projects (one holding PageExtractor, one the word doc wrapper code and the last holding the MVC site) are all set to build with an x86 platform target.
- I also have an integration test project using xunit & testdriven.net that tests key PageExtractor methods for a bunch of tiff and pdf files.
- I'm running this in VS 2012 and targetting .net v4.5

What's happening is that I have one tiff that I can extract the pages from and save to disk inside the test project, but can't extract the pages from and insert into the word doc (or save to disk) when running the mvc app inside VS - I get an exception on a method on PageExtractor for the ones that fail.

I've logged a bug with the vendor, but they're not familiar with IIS, and I'm suspicious that it's my environment that's at fault. Does anyone have any tips on nutting this one out?

mortarr
Apr 28, 2005

frozen meat at high speed

quote:

2014-10-03 11:49:01,602 [12] ERROR PNCC.LimDocumentBuilder.WordIntegration.Services.PageAttacherService Failed to attach page 35
System.ArgumentException: Parameter is not valid.
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)
at PTI_Converter.ImageProcessing.BitmapFromDIB(IntPtr dibPtrArg)
at PTI_Converter.TiffPageExtractor.GetBitmap(Int32 pageNumber)
at PTI_Converter.TiffPageExtractor.GetPage(Int32 pageNumber)
at PNCC.LimDocumentBuilder.DocToImageConverter.Services.DocumentConverterService.GetPageAsBitmap(Int32 pageNumber) in c:\...\DocumentConverterService.cs:line 62

Here's the stack trace.

It's bailing when called from an MVC app hosted in VS 2012, but not when called from a test project in the same solution run using testdriven.net. Same method, same arguments, same document I'm trying to extract pages from, but different result. In both cases I can extract pages 1-34, but not >=35 under MVC. The tiff does not appear to be malformed - I can open it in a variety of apps and see all its pages.

Doesn't seem to matter where the doc is on the filesystem, so probably not a permissions thing.

mortarr
Apr 28, 2005

frozen meat at high speed

wwb posted:

I'd add some debug statements to spit out data about the pdf like how many pages it sees. Not familiar with the underlying library but my guess is it does something that makes it behave different running inside IIS versus running in testdriven.net.

It also might be worth hooking it into full-blown IIS on said machine to see if that somehow makes a difference. To do so and get debugging just setup a virtual site pointed to the app and run VS as administrator and connect to the right w3wp.exe process.

Turns out there was a memory issue... not suprisingly holding multiple versions of an A3-sized bitmap in memory only works on machines with heaps of ram. It's a vendor issue, and nothing to do with the setup/config of iis, visual studio, solution/project files or basically anything under my control.

Thanks for the heads up on debugging w3wp.exe though, I think that would have been my next step and I wasn't looking forward to it!

mortarr
Apr 28, 2005

frozen meat at high speed

Scaramouche posted:

I think this is possible, but I was wondering if you guys could give me a direction to get started. I've got a large number of images provided by a third party. Some of them are either contrasty, adjusted poorly, or what have you. This means that backgrounds that should be white, are instead kind of an off-white. Here's an example image:


So what I'd like to be able to do, programmatically, is 'fix' these images so the white is actually RGB 255 white. Do you guys have any suggestions or libraries that you think are up to this?

Note: I don't have to be able to >find< them, I have another service that does this. I'd be inputting a big list of file names with weird backgrounds into whatever solution I develop.

Not sure if this does what you're after, but I've been using ImageResizer for about two years commercially and found it to be pretty good. I'm using it for one-off resizing of A1 and A2 colour pages taken out of pdf and tiff documents, which is probably way outside what it was intended for, but it's pretty sweet and you can override quite a lot of the processing pipeline if you need custom features.

There is a paid-for version that has a plugin to do white balance adjustment which might be what you need. The source is available though, so check out \Plugins\AdvancedFilters\AutoWhiteBalance.cs in the zip.

From the docs:
Automatic white balance (alpha feature of 3.3.0)

Automatically corrects the white balance of the photo with 1 of 3 algorithms.
- area - Threshold is applied based on cumulative area at the lower and upper ends of the histogram. Much larger thresholds are required for this than SimpleThreshold.
- simple - Simple upper and lower usage thresholds are applied to the values in each channel's histogram to determine the input start/stop points for each individual channel. The start/stop points are used to calculate the scale factor and offset for the channel.
- gimp - Threshold is applied based on strangely skewed cumulative area, identical to the process used by GIMP.

mortarr
Apr 28, 2005

frozen meat at high speed

Dr Monkeysee posted:

Null propagation yesssssssss one more battle won in the war against null.

True that. The nameof operator and string interpolation look pretty neat too.

mortarr
Apr 28, 2005

frozen meat at high speed

Scaramouche posted:

My only experience with SSRS is that the three times I've had to implement something with it that it's not capable of doing what we wanted it to do and we moved to other solutions. Sorry that doesn't help, and maybe it's gotten better (this was 2008R2), but good god was it a tangle of permissions and lovely bridge code and not-quite programming but not-quite scripting.

Yeah, same here... I not at work so no code to hand, but the object model you're working with is pretty opaque - the best I could do was get the SSRS report to render to pdf in memory and then I sent that down to the client as a filecontentresult.

In fact, I remember I got so cross with the whole thing I put the report up on the sql server and just called that from my mvc proj, it was too hard to get meaningful error messages when hosting the whole shebang inside my web app. I'm sure there were permissions errors where kerberos/delegation wasn't working but damned if I could find what aspect of the thing was bailing.

mortarr
Apr 28, 2005

frozen meat at high speed
I'm writing my first web api, and each controller has only get, put, post etc methods, which seems like it's going to result in a large number of controllers over time, because there are quite a few types of object to interact with, and different systems interact with the same object in different ways.

Is this the modern way to do things or am I missing the point?

Actually, just typing this out made me think I should reduce the number of controllers and have overloads on the verb methods, but even so I feel like I'm doing something wrong.

mortarr
Apr 28, 2005

frozen meat at high speed

mortarr posted:

I'm writing my first web api, and each controller has only get, put, post etc methods, which seems like it's going to result in a large number of controllers over time, because there are quite a few types of object to interact with, and different systems interact with the same object in different ways.

Is this the modern way to do things or am I missing the point?

Actually, just typing this out made me think I should reduce the number of controllers and have overloads on the verb methods, but even so I feel like I'm doing something wrong.

Looks like i was missing the point of rest/web api to some extent. I had controllers named around the action like DocumentRegistration, DocumentCount and DocumentList. Refactored around resource (following more research), so I have Document and Documents controllers, with count or list operations selected via config object now.

Typing on my phone sucks, got no code examples sorry.

mortarr
Apr 28, 2005

frozen meat at high speed
Continuing the mvc / web api chat...

So right now I have controllers named after resources: DocumentController, DocumentsController, FolderController, FoldersController etc. They have methods like below, comments are for this example, I've actually got an mvc help area in-app that displays the xml help on the web api controller methods. ApiControllerBase has some common stuff over the top of the normal web api controller thing, like logging object etc.

code:
// Other view models inherit from this...
public class ApiViewModelBase 
{
	public string Username { get; set; }
}

public class DocumentController: ApiControllerBase
{
	// Add or update, can be called multiple times safely
	[HttpPut] 
	public Document Put(DocumentPutViewModel vm) { ... }

	// Get the document by id
	[HttpGet] 
	public Document Get(DocumentGetViewModel vm) { ... }
} 

public class DocumentsController: ApiControllerBase
{
	// Get the documents related to contact id
	[HttpGet] 
	public List<Document> Get(DocumentSearchByContactIdViewModel vm) { ... }


	// Get the documents related to location
	[HttpGet] 
	public List<Document> Get(DocumentSearchByLocationViewModel vm) { ... }
}
The consensus is that the controller method names need to be better - maybe "SearchByLocation" and "SearchByContactId" in DocumentsController? What about the controller method parameter names? Is there anything else I'm doing that seems dumb?

mortarr
Apr 28, 2005

frozen meat at high speed

Bognar posted:

Ditto on one controller per entity type. It would drive me nuts to have a [Type]Controller and [Type]sController for every entity.

True, I guess when you're using [Http*] attribs and not naming the methods like "Get", "Put", but "SearchByContact", then you're not bound to return the same datatype for both singular and plural. Thanks for clearing things up, I've been writing mvc apps for ages, but I'm still fairly new to the whole REST and web api thing.

mortarr
Apr 28, 2005

frozen meat at high speed

Bognar posted:


...

C# code:
@(Html.ActionLink<HomeController>("My Link", c => c.MyMethod(1, "butts")))
Now, refactoring tools will automatically pick up the usage of MyMethod, renaming parameters in the method signature doesn't cause you headaches, and you don't have to pass in null to the weird ActionLink overload when specifying a controller.


I like everything about this, going to file it away for my next mvc project.

mortarr
Apr 28, 2005

frozen meat at high speed

Bognar posted:

Adding to this, a simple but awesome feature that I find myself missing without R# is Move Type to File. Often when prototyping things I'll jam a bunch of classes together in a file, then come back afterwards and refactor into their own files - this is pretty painful with having to create each file manually then copying the code in and trying to get the using statements right.

How did I never know about this!

mortarr
Apr 28, 2005

frozen meat at high speed

Mr Shiny Pants posted:

gently caress Open XML, what a loving piece of poo poo. Pfffff.

All I want is to create a Word Document with some tables, how hard can it be? Well very hard.

God, it isn't even a bit discoverable.

I needed to vent.

I re-wrote a big word macro in c#... it came out with more lines and way more complexity thanks to oxml. Whoever ends up porting that to whatever next tech comes along is not in for a fun time!

mortarr
Apr 28, 2005

frozen meat at high speed

Bognar posted:

Speaking of magic, reflection, and expressions...
https://github.com/ckimes89/ef-graphql

What do you guys think?

That looks real interesting, like being able to use it would be pretty handy, but also implementing the spec itself looks like a sweet-as piece of work though. How far are you through the spec?

mortarr
Apr 28, 2005

frozen meat at high speed

The Wizard of Poz posted:

Putting attributes on the properties is definitely something I'd like to consider, but I guess I wanted to interfere as little as possible with the existing models and I liked the idea of having this as something that could just kind of "plug in" to a model without really touching any of the existing base stuff. Like I said, though, if it's really the simplest way to do it I'm not opposed. I know my way is complicated, but I envisioned it being simpler to understand when you're looking "from the outside in". (This is part of a code API intended to be consumed by our other products).

Edit: Also, regarding the key names, I've just used those as an example, the real keys aren't so easy to automate sadly.

Is there any reason you need the mapping/conversion code in the object itself? I was thinking you could do something with automapper? Phone-posting, and I can't remember specifics, but I maybe you could abuse an automapper typeconverter of your interface/base class plus reflection (and hold that logic somewhere else), then just map to dictionary as needed.

mortarr
Apr 28, 2005

frozen meat at high speed

GrumpyDoctor posted:

I have an Automapper question. Specifically, it's this exact question. Basically, I want the ability to inject a custom object when I call Map that is used as a context object for mapping certain properties. And according that github issue, the exact functionality I needed was added:


And then a commit was referenced, and the issue was closed, and the original poster thanked the maintainer for adding the functionality.

...but I can't figure out how to use it. I can't find that overload, and the "what I'd like to do" code doesn't compile. I can find that overload in a different place, where you implement your own value resolver (I think), but there's still no way to just throw a generic context object at the default resolver, or a way to dig it out inside ResolveUsing. What dumb thing am I missing?

I think what you're after is the resolution context - like so:

code:
    public void Example()
    {
      Mapper.CreateMap<Data, DataDto>()
            .ForMember(dest => dest.DataValue, 
                       opt  => opt.ResolveUsing(ctx => ctx.Context.Options.Items["DataValueToKeep"]));

      AutoMapperConfiguration.Configure();
      Mapper.AssertConfigurationIsValid();

      var dto = Mapper.Map<DataDto>(new Data { DataValue = "value to discard" }, 
                                    opt => opt.Items["DataValueToKeep"] = "value to keep");

      Assert.That(dto.DataValue.Equals("value to keep"));
    }

    public class Data
    {
      public string DataValue { get; set; }
    }

    public class DataDto
    {
      public string DataValue { get; set; }
    }
I have done this in prod code but I don't have it to hand so this is kind-of from memory. The key bit is setting and then pulling stuff out of the ResolutionContext Items dictionary. What sucks with my example here is you need the person calling the Map<> function to know the expected name etc... I'm not sure if there's a way to do the same thing without magic strings - if you find a better way I'd love to know.


[Edit] cleaned up the example a bit.

mortarr fucked around with this message at 08:34 on Oct 4, 2015

mortarr
Apr 28, 2005

frozen meat at high speed
Can you guys critique my workflow here - I do corporate .net work as my day job but I'm about to pick up a contract to do some .net work and I'm trying to find a good way to deliver my work to them. The product I'm working on is an IIS site which will be deployed on a clients server.

I'll do the dev work on my pc, and perform integration tests against a mock of the services that will exist on the clients server.
I check in to a private bitbucket repo, which we would all have access to.
A (hosted?) CI server notices the checkin and does it's work, deploying to the Test server on our network if the tests pass.

I've never used a CI server, but I'm assuming that if the tests pass, the build can be deployed to an ftp server? From here, I'm not sure how we get to Production - is there a way to tell the CI server UAT has passed and that it should do a production build? I've been checking out teamcity, cruisecontrol.net, jenkins and others - both local and hosted, but there seems to be a lot of choice here and I'm not sure what I should be looking for.

After we get a prod build, we would most likely do manual installs while dialled in to the client, but again, I'm not sure what the options are.

By contrast, this is my workflow in my day job:
Check code out from TFS to my pc, then publish to dev, test or prod as needed. We do testing, but it's very ad-hoc UI/integration testing only.


Other stuff I don't really do in my day job is support multiple versions of the same product, any kind of team chat, wiki, work item tracking, that kind of thing. My goal is to set up a workflow that I can hand over to the guys I'm working with if I need to, and not have everything bound up in my head/on my pc/as manual processes like I do in my day job!

mortarr
Apr 28, 2005

frozen meat at high speed

epalm posted:

Why can't I put Automapper mapping configurations (via Mapper.CreateMap statements) in the static constructor of the related object?

To me, this seems like the most logical place to put the mapping statements:

C# code:
public class Person
{
	public int Id { get; set; }
	public string Name { get; set; }
	public int Age { get; set; }
}

public class PersonDto1
{
	static PersonDto1()
	{
		Mapper.CreateMap<Person, PersonDto1>();
	}

	public int Id { get; set; }
	public string Name { get; set; }
}

public class PersonDto2
{
	static PersonDto2()
	{
		Mapper.CreateMap<Person, PersonDto2>();
	}

	public int Id { get; set; }
	public int Age { get; set; }
}
But it appears that running Mapper.Map<Person, PersonDto1>(entity) throws an Exception before the PersonDto1 static constructor runs. I was under the (false) impression that, as soon as you try to do anything with PersonDto1, the static constructor will run. Automapper must be instantiating a PersonDto1 at some point, why isn't the static constructor running?

Edit: Oh. Automapper must simply be checking to see if a mapping exists before trying to map it. Duh.

Hey, not sure if you give a poo poo, but I found this automapper style which keeps the `Mapper.CreateMap<Person, PersonDto2>();` part out of your DTO's for classes with one-to-one mappings... `AutomapperConfigTask.Execute()` gets called on startup, and handles the basic one-one CreateMap statements, so you only need to write the custom ones by implementing IHaveCustomMappings.

I used to have heaps of classes implementing automappers `Profile` that got discovered on startup, but I think having the mapping inside the DTO's is a better way to go than lumping them all together, and this style seems to complement what you're already thinking of with the static methods.

code:
  public interface IMapFrom<T>
  {
  }

  public interface IHaveCustomMappings
  {
    void CreateMappings(IConfiguration configuration);
  }

  public class AutomapperConfigTask 
  {
    public void Execute()
    {
      var types = Assembly.GetExecutingAssembly().GetExportedTypes();

      LoadStandardMappings(types);
      LoadCustomMappings(types);

      Mapper.AssertConfigurationIsValid();
    }

    private static void LoadCustomMappings(IEnumerable<Type> types)
    {
      var maps = (from t in types
                  from i in t.GetInterfaces()
                  where typeof(IHaveCustomMappings).IsAssignableFrom(t) &&
                      !t.IsAbstract &&
                      !t.IsInterface
                  select (IHaveCustomMappings)Activator.CreateInstance(t)).ToArray();

      foreach (var map in maps)
      {
        map.CreateMappings(Mapper.Configuration);
      }
    }

    private static void LoadStandardMappings(IEnumerable<Type> types)
    {
      var maps = (from t in types
                  from i in t.GetInterfaces()
                  where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>) &&
                      !t.IsAbstract &&
                      !t.IsInterface
                  select new
                  {
                    Source = i.GetGenericArguments()[0],
                    Destination = t
                  }).ToArray();

      foreach (var map in maps)
      {
        Mapper.CreateMap(map.Source, map.Destination);
      }
    }
  }

  public class Person
  {
    public string Id { get; set; }
    public string Name { get; set; }
  }

  public class PersonDto : IMapFrom<Person>
  {
    public string Id { get; set; }
    public string Name { get; set; }
  }

  public class PersonDto2 : IHaveCustomMappings
  {
    public string Id { get; set; }
    public string Name { get; set; }
    public List<string> PhoneNumbers { get; set; }

    public void CreateMappings(IConfiguration configuration) 
    {
	configuration.CreateMap<Person, PersonDto2>()
          .ForMember(m => m.Id, opt => opt.MapFrom(src => src.Id))
          .ForMember(m => m.Name, opt => opt.MapFrom(src => src.Name))      
          .ForMember(m => m.PhoneNumbers, opt => opt.UseValue(src => new[] { "111", "222" }));      
    }
  }  

mortarr
Apr 28, 2005

frozen meat at high speed
What do you guys do when you're building software to sell and you use 3rd party libraries via nuget eg. Autofac, elmah, EF etc. Is there a recommended practice for including licenses for these?

With the javascript libraries, the license is usually included as part of the .js file, so I think I'm OK there, but for all these other packages I've just created a "licenses" folder, which contains files named like the package name - "autofac.lic", "autofac.mvc.lic" and copied the license from their github or wherever I can find it into the corresponding .lic file. This folder will be included as part of the distributed software.

I normally develop inhouse apps that are not for distribution, so this has never come up before and I'm not sure what approach to take.

mortarr
Apr 28, 2005

frozen meat at high speed
I feel a bit dumb asking this... when I'm working is a cshtml file in vs2015, when I hit enter after a closing tag, like </div>, </td> etc, all of the html enclosed by that pair of tags is being re-indented to the wrong level. I'm not sure if its a VS thing, resharper, or the two working against each other.

So I start with something like this (all css, asp.net mvc stuff etc omitted):
code:
<tr>
  <td><label>stuff</label><span>goes</span><div>here</div></td>
  <td>
    <ul>
      <li><div><span>thing one</span></li>
      <li><div><span>thing two</span></li>
      <li><div><span>thing three</span></li>
    </ul>
  </td>
</tr>
Then say I hit enter after the </tr> to start typing another <tr> block, and then it gets re-formatted to:
code:
<tr>
<td>
  <label>
    stuff
  </label>
  <span>
    goes
  </span>
  <div>
    here
  </div>
</td>
<td>
  <ul>
    <li>
      <div>
        <span>
          thing one
        </span>
      </div>
    </li>
      <div>
        <span>
          thing two
        </span>
      </div>
    </li>
      <div>
        <span>
          thing three
        </span>
      </div>
    </li>
  </ul>
</td>
</tr>
It's a goddamn pain, and I can't think of what to google for!

mortarr
Apr 28, 2005

frozen meat at high speed

beuges posted:

Your <li> elements have a <div> but no </div> - that's probably what's causing it

Sorry, that was a bit of a crap example... I get it with well-formed html in vs2015, but not in vs2012. Is there some setting to tell vs not to re-indent, I've tried a bunch of things in options/text editor/html/tabs, but it hasn't helped.

mortarr
Apr 28, 2005

frozen meat at high speed

OneEightHundred posted:

My new favorite thing in .NET is that it had an implementation bug that allowed the "no implementing interfaces that could be duplicates after type substitution" rule to be bypassed, a big corporate user got pissed when they patched it out, so they put it back in and now there are 4 pages in the standard dedicated to supporting it.

:suicide:

code:
public interface IIfc<T> { void Func(T p); }

public class Base<T> : IIfc<T> { void IIfc<T>.Func(T p) { Console.WriteLine("Base"); } }

public class Derived<A, B> : Base<A>, IIfc<B>
{
    void IIfc<B>.Func(B p) { Console.WriteLine("Derived"); }

    public void CallA(A p)
    {
        IIfc<A> ifc = this;
        ifc.Func(p);
    }
}

static void Main(string[] args)
{
    (new Derived<int, object>()).CallA(0);
    (new Derived<int, int>()).CallA(0);
}
code:
Base
Derived

Looks confusing, what's the benefit / what cunning tricks can you do with this, that couldn't be done before?

mortarr
Apr 28, 2005

frozen meat at high speed

Captain Melo posted:

Is there an easy way to modify exif data on photos using C#? I don't know if I'm missing something obvious, but I'm completely coming up with a blank. I'm trying to edit the GPS information located in .jpeg files.

https://github.com/mwijnands/JpegMetadata

Not sure if this deals with gps metadata, but it might be a starting point?

mortarr
Apr 28, 2005

frozen meat at high speed
I've got an application at a bunch of customer sites, and one of them wants a feature that's specific to their site that the rest are unlikely to want. I was looking at some kind of plugin system like MEF as a way to keep custom work out of the main solution, but it feels like I could be going down a rabbit hole here... Is there a common approach to this kind of requirement?

mortarr
Apr 28, 2005

frozen meat at high speed
I think mef / plugins arent for me this time... I did a wee proof of concept, and while it worked, it showed some bits that might make development take a while, eg logging, loading/unloading plugins, and generally keeping the logic that belongs in the plugin inside the plugin.

I already have a basic kind of feature detection, so i'll probably go that way instead. Not sure i like it architecture wise, but i can get it done that way pretty quickly.

If it was for my own stuff, I would go mef all the way :-)

mortarr
Apr 28, 2005

frozen meat at high speed

Portland Sucks posted:

I just really hate the person who wrote all this lovely code. I hate them so much and I hate their code and I hate winforms. I'm just a gigantic ball of hate.

Which ever path you take, the next person to touch your code is probably going to think this about whatever you write. What's worse, is if you get made permanent, you'll be the one hating your own code :-)

Not sure what your decision on incremental change vs full scale re-write, but I think going through an incremental brownfields-type renewal will put you in much better standing to future employers than writing something new from scratch.

mortarr
Apr 28, 2005

frozen meat at high speed

The Wizard of Poz posted:

Hmm yeah I will tend toward private methods in the controllers as well. I don't know, it just feels clunky having that information mixed in among the input fields. It feels like I'm working against MVC somehow, and that there must be a more accepted way.

Same here, hidden input fields for simple objects. Sometimes I need to edit lists of child records on the same page, so in that case they go down in their own property like:

code:
  public class ParentViewModel {
    public int ParentId { get; set; }
    ... various props
    public List<ChildViewModel> Children { get; set; }
  }

  public class ChildViewModel {
    public DateTime? DateAdded { get; set; }
    public string Notes { get; set; }
  }  
In the view I use a kendo ui grid to hold the Children (initialised via javascript, not via the asp.net bindings), and I might bind to a custom popup window for row editing or use inline editing if the requirements are more simple. On post, I re-serialise the underlying datasource for the grid via json stringify into a hidden field, then I override DefaultModelBinder and read it back in to its correct property before the controller gets it:

code:
public class ParentViewModelModelBinder : DefaultModelBinder<ParentViewModel>
  {
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
      if (propertyDescriptor.Name == "Children")
      {
        // Set the property ourselves when we're overriding default behaviour
        var serialisedValue = controllerContext.HttpContext.Request.Params[propertyDescriptor.Name] ?? string.Empty;
        var data = serialisedValue.FromJson<List<ChildViewModel>>() ?? new List<ChildViewModel>();

        this.SetProperty(controllerContext, bindingContext, propertyDescriptor, data);
      }
      else
      {
        // If it's not a property of interest, fall back to the default behaviour.
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
      }
    }
  }
This way, I ensure I don't need to requery my EF objects each postback if validation fails.

Someone please tell me there's an easier way for setting up parent/child editable pages in asp.net mvc?!

Adbot
ADBOT LOVES YOU

mortarr
Apr 28, 2005

frozen meat at high speed

The Wizard of Poz posted:

I'm trying to figure out a neat way to hold onto a collection of Entity Framework Include() expressions and retrieve them generically. Let's say I have the following Entities:

(snip)

How can I get that list of includes? I've considered putting it on the ViewModel as a static property, but then there's no way to enforce the presence of the static property using a type constraint, so there's no way to access that static property generically. Ideas?

Not sure if it's helpdul, but Automapper has ProjectTo() which (I think) you use in a similar way to what you are proposing, although you may need to map things beforehand. Maybe digging in to its source would give you some pointers?

If you use its MapTo() method, automapper will project the IQueryable to a list (or similar) and then hit EF once for each of the items in the list (I think this is called the select n+1 problem). Instead, you can use ProjectTo, and it will build a smarter EF query and get all the props at once. It sounds like it's using includes the same way you mention, but I don't know what magic is going on under the hood.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply