Modify Swagger Definition Names for MVC API - asp.net-mvc

I would like to modify the Swagger schema object names that are auto generated for my MVC application.
For example, I have number of entities like EmployeeModel or CompanyModel objects that are accessible via our REST endpoints
However, it's not necessary or desired that the Swagger definition contains the word "Model" after each entity name. They should be known only as Employee or Company -- see example in screen shot.

You have to use the SchemaId function available in your SwaggerConfig.cs file in the EnableSwagger method as follows:
c.SchemaId(t =>
{
c.SchemaId(t => t.FullName.EndsWith("Model") ? t.FullName.Replace("Model", String.Empty) : t.FullName);
});
This methods allows you to override Swashbuckle default behavior and set complex type names properly.
My sample addresses directly the removela of the "Model" part of your boject names, but could be using more complex setup.

What library are you using to build you swagger shema? Take a look at Swashbuckle . This allows to build swagger shema automatically for your app (by using xml-documentation) and is flexible for customization. See "Modifying Generated Schemas" in documentation.

Related

SiteMapNode is readonly, property 'Url' cannot be modified

I setup MVC breadcumbs for my website using MvcSiteMapProvider (Nuget package MvcSiteMapProvider.MVC5 (version 4.6.22)).
It works fine.
Then I want to update Url of Sitemap dynamically like:
SiteMaps.Current.CurrentNode.Url = Url.Action("Index");
Then I got this error:
SiteMapNode is readonly, property 'Url' cannot be modified
Note that I am still able to update Title:
SiteMaps.Current.CurrentNode.Title = "/Index";
Any idea?
The SiteMap is a statically cached object that is shared between all users. Technically, all of the properties are read-only at runtime. However, some of the properties (such as Title) are request-cached so you can safely update them at runtime without affecting other users.
The Url property is a special property that dynamically builds the URL through the MVC UrlHelper class (which is directly driven from your routes). It makes no sense to set it to Url.Action("Index") because that is effectively what it does just by itself (unless you are using a dynamic node provider or custom ISiteMapNodeProvider - those are startup extension points where you load the node configuration, so the properties are read-write).
You just need to set the correct controller and action in your node configuration (which could be XML, attribute based, or code based) and the URL will resolve on its own.
XML Example
<mvcSiteMapNode title="Projects" controller="Project" action="Index"/>
NOTE: You need to account for all route values in the request, either by adding them as another attribute myId="123" or by using preservedRouteParameters="myId" (which tells it to include the myId from the current request when building the URL). See this article for a detailed description of using these options.
NOTE: Setting a URL in the SiteMap configuration effectively overrides MVC support for that node. So, you shouldn't set a URL at all unless it is a non-MVC URL.

Custom UIHint attribute

Is it possible to create a custom version of the UIHint attribute?
When my company first adopted MVC, we used a lot of Html.* helper methods. We are in the process of redesigning out MVC template to make use of the full power of MVC. One way we are doing this is with Display and Editor Templates.
However, one popular HTML extension method we had was to generate dropdowns for Enums. One of the options we had was to sort by the int value or the description or text of the EnumMember.
I would like to see about creating a EnumDropdown attribute that accepts several parameters that can customize the output of the HTML dropdown. However, I don't think it's possible to do this while still retaining the benefits of the UIHint attribute. Meaning, that I won't be able to simply call #Html.EditorFor(m => Model)
I had found that there is a System.Web.UI.IAutoFieldGenerator interface but it doesn't appear to do what I want. Any suggestions?
The newer versions of MVC have this built in now:
EnumDropDownListFor HTML Helper
The only thing UIHint does is suggest a Display or Editor template name. MVC will then add this name to the search path when looking for that template.
You can just use UIHint as is and have your generator create these for you in the correct folders and not have to customize it.

How does one access and bind the entity meta-data (through JavaScript on the client) available from Upshot?

One of the supposed benefits of Upshot is its ability to query meta-data exposed through Data Annotations. How would one access meta-data for entity properties for things like string length, default values, display name, description information, and whether a field is required?
How would connect this data into a validation framwork like jQuery Validation or Knockout Validation?
Note: I am currently using Knockout 2.1.0, Upshot 1.0.0.2, Entity Framework 4.3, and ASP.NET MVC4.
You can use the upshot function metadata() to access this information, for example:
If you have the following upshot registration:
#(Html.UpshotContext(bufferChanges: true)
.DataSource<App.Controllers.DBController>(x => x.GetUsers())
.ClientMapping<App.Models.User>("User")
)
you can access the metadata (and validation rules) like this:
var metadata = upshot.metadata(upshot.type(User));
you can also retrieve information about properties (eg. "Name"):
var propertyType = upshot.metadata.getPropertyType(upshot.type(User), "Name");

how to do Localization for one of the #Model property in mvc3

I have started working on an MVC project and I came across some scenarios where I feel I am stuck. I need to convert the existing MVC3 site to work for multiple language.
I have one HeaderPage.cshtml and it has a view model bound to it by
#model IHeaderPage
And it outputs a property of this model:
<h3>#Model.HeaderName</h3>
I called this view from MainPage.cshtml
#Html.Partial("HeaderPage")
Now in the Controller's Action method I change the model's property
objHeaderPage.HeaderName="Fill your Registeration details";
And when i run the project i see the the text "Fill your Registeration details".
Now how can I change the text value, i.e. it should read from my resx file.
I have already created resx files in App_LocalResources folder.
I heard that, it can be done by Display Attribute.. but how do i do that or is there any other better way?
This should answer your question regarding the use of DisplayAttribute.
I use DisplayAttribute for every property of my ViewModel, but if you have to handle custom messages like "The record can not be saved because of an error...", or something similar, you can simply use
objHeaderPage.HeaderName = Resources.ResourceMessageName;
The framework will choose automatically the correct culture.
I prefer to put all my resources in a separate projects so I can deploy only the dll of the resources in case of need, but you can also think to deploy the resx files to edit them directly on the production machine. I guess it's up to what you prefer/need.
use System.ComponentModel.DataAnnotations Namespace in ViewModel.
[Display(Name="Fill your Registeration details")]
public string HeaderName{get;set;}
also you can use your resource file. Just review http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx

Preferred way to use config settings in asp.net mvc master page

My Problem: I have an MVC3 application where all views use a common master page. The master page has many links to other (internal) sites. I need to be able to change the domain of these links depending on the deployment environment (e.g. staging.blah.com, www.blah.com, dev.blah.com etc). This domain is stored in the web.config.
There are numerous ways of doing this, but I am looking for some sort of consensus as to the preferred method. Here are some options but I am open to any suggestions:
(1) reference appsettings from master page directly. This is the simplest and most common approach but I am not particularly keen on reading the web.config and concatenate the url throughout the master page code. In fact, I am not sure that I like the idea of the view accessing the web.config at all.
(2) stick the appsetting value in viewdata/viewbag using a custom action filter which reads the config. concatenate in the page as before.
(3) as (2), but inject appsetting value in via contructor injection rather than reading it within the filter.
(4) create a base class for all my strongly typed viewmodels and populate with the appsetting using a custom action filter.
(5) create an htmlhelper that takes in the path and internally reads the appsetting and concatenates.
(6) create a custom view base class, inject in appsetting value and make available as property or function that takes in path and concatenates.
Just to add that typically when the master page requires data, I like to use Html.Action, but this is not possible in the case of these URLs that are used throughout the master page.
Thoughts?
(5) create an htmlhelper that takes in the path and internally reads the appsetting and concatenates.
I would go with this one. Your custom HTML helper could look something like this:
<%= Html.ExternalActionLink(
"link text",
new { path = "/foo/bar.php" }
new { param1 = "value1", param2 = "value2" }
) %>
and could emit the following HTML:
link text
What I have done in the past is use viewdata/viewbag in my master page and populate its values in my base controller. The base controller in turn called another class to do the work of reading the values from the web.config.
This way the view is pretty clean (e.g. it does not contain code to read appsettings) and I don't need to create a base view model that matches all my views that use the master.
This approach has the disadvantage that uses a viewdata/viewbag but I decided that was OK in my case and extremely easy to implement.

Resources